tipc: use bearer index when looking up active links
struct tipc_node currently holds two arrays of link pointers; one,
indexed by bearer identity, which contains all links irrespective of
current state, and one two-slot array for the currently active link
or links. The latter array contains direct pointers into the elements
of the former. This has the effect that we cannot know the bearer id of
a link when accessing it via the "active_links[]" array without actually
dereferencing the pointer, something we want to avoid in some cases.
In this commit, we do instead store the bearer identity in the
"active_links" array, and use this as an index to find the right element
in the overall link entry array. This change should be seen as a
preparation for the later commits in this series.
Reviewed-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 20ec61c..1972964 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -142,6 +142,8 @@
list_add_tail_rcu(&n_ptr->list, &temp_node->list);
n_ptr->action_flags = TIPC_WAIT_PEER_LINKS_DOWN;
n_ptr->signature = INVALID_NODE_SIG;
+ n_ptr->active_links[0] = INVALID_BEARER_ID;
+ n_ptr->active_links[1] = INVALID_BEARER_ID;
tipc_node_get(n_ptr);
exit:
spin_unlock_bh(&tn->node_list_lock);
@@ -227,12 +229,13 @@
*/
void tipc_node_link_up(struct tipc_node *n, int bearer_id)
{
- struct tipc_link_entry **actv = &n->active_links[0];
- struct tipc_link_entry *le = &n->links[bearer_id];
- struct tipc_link *l = le->link;
+ int *slot0 = &n->active_links[0];
+ int *slot1 = &n->active_links[1];
+ struct tipc_link_entry *links = n->links;
+ struct tipc_link *l = n->links[bearer_id].link;
/* Leave room for tunnel header when returning 'mtu' to users: */
- n->links[bearer_id].mtu = l->mtu - INT_H_SIZE;
+ links[bearer_id].mtu = l->mtu - INT_H_SIZE;
n->working_links++;
n->action_flags |= TIPC_NOTIFY_LINK_UP;
@@ -242,55 +245,30 @@
l->name, l->net_plane);
/* No active links ? => take both active slots */
- if (!actv[0]) {
- actv[0] = le;
- actv[1] = le;
+ if (*slot0 < 0) {
+ *slot0 = bearer_id;
+ *slot1 = bearer_id;
node_established_contact(n);
return;
}
- if (l->priority < actv[0]->link->priority) {
+
+ /* Lower prio than current active ? => no slot */
+ if (l->priority < links[*slot0].link->priority) {
pr_debug("New link <%s> becomes standby\n", l->name);
return;
}
- tipc_link_dup_queue_xmit(actv[0]->link, l);
+ tipc_link_dup_queue_xmit(links[*slot0].link, l);
- /* Take one active slot if applicable */
- if (l->priority == actv[0]->link->priority) {
- actv[0] = le;
+ /* Same prio as current active ? => take one slot */
+ if (l->priority == links[*slot0].link->priority) {
+ *slot0 = bearer_id;
return;
}
- /* Higher prio than current active? => take both active slots */
- pr_debug("Old l <%s> becomes standby\n", actv[0]->link->name);
- if (actv[1] != actv[0])
- pr_debug("Old link <%s> now standby\n", actv[1]->link->name);
- actv[0] = le;
- actv[1] = le;
-}
-/**
- * node_select_active_links - select which working links should be active
- */
-static void node_select_active_links(struct tipc_node *n)
-{
- struct tipc_link_entry **actv = &n->active_links[0];
- struct tipc_link *l;
- u32 b, highest = 0;
-
- actv[0] = NULL;
- actv[1] = NULL;
-
- for (b = 0; b < MAX_BEARERS; b++) {
- l = n->links[b].link;
- if (!l || !tipc_link_is_up(l) || (l->priority < highest))
- continue;
- if (l->priority > highest) {
- highest = l->priority;
- actv[0] = &n->links[b];
- actv[1] = &n->links[b];
- continue;
- }
- actv[1] = &n->links[b];
- }
+ /* Higher prio than current active => take both active slots */
+ pr_debug("Old link <%s> now standby\n", links[*slot0].link->name);
+ *slot0 = bearer_id;
+ *slot1 = bearer_id;
}
/**
@@ -298,32 +276,36 @@
*/
void tipc_node_link_down(struct tipc_node *n, int bearer_id)
{
- struct tipc_link_entry **actv = &n->active_links[0];
- struct tipc_link_entry *le = &n->links[bearer_id];
- struct tipc_link *l = le->link;
+ int *slot0 = &n->active_links[0];
+ int *slot1 = &n->active_links[1];
+ int i, highest = 0;
+ struct tipc_link *l, *_l;
+ l = n->links[bearer_id].link;
n->working_links--;
n->action_flags |= TIPC_NOTIFY_LINK_DOWN;
n->link_id = l->peer_bearer_id << 16 | l->bearer_id;
- if (!tipc_link_is_active(l)) {
- pr_debug("Lost standby link <%s> on network plane %c\n",
- l->name, l->net_plane);
- return;
- }
pr_debug("Lost link <%s> on network plane %c\n",
l->name, l->net_plane);
- /* Resdistribute active slots if applicable */
- if (actv[0] == le)
- actv[0] = actv[1];
- if (actv[1] == le)
- actv[1] = actv[0];
-
- /* Last link of this priority? => select other ones if available */
- if (actv[0] == le)
- node_select_active_links(n);
-
+ /* Select new active link if any available */
+ *slot0 = INVALID_BEARER_ID;
+ *slot1 = INVALID_BEARER_ID;
+ for (i = 0; i < MAX_BEARERS; i++) {
+ _l = n->links[i].link;
+ if (!_l || !tipc_link_is_up(_l))
+ continue;
+ if (_l->priority < highest)
+ continue;
+ if (_l->priority > highest) {
+ highest = _l->priority;
+ *slot0 = i;
+ *slot1 = i;
+ continue;
+ }
+ *slot1 = i;
+ }
if (tipc_node_is_up(n))
tipc_link_failover_send_queue(l);
else
@@ -332,7 +314,7 @@
bool tipc_node_is_up(struct tipc_node *n)
{
- return n->active_links[0];
+ return n->active_links[0] != INVALID_BEARER_ID;
}
void tipc_node_check_dest(struct tipc_node *n, struct tipc_bearer *b,