Skip to content

Commit 36e78a4

Browse files
Jon Paul Maloydavem330
authored andcommitted
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>
1 parent d39bbd4 commit 36e78a4

File tree

2 files changed

+59
-73
lines changed

2 files changed

+59
-73
lines changed

net/tipc/node.c

Lines changed: 44 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ struct tipc_node *tipc_node_create(struct net *net, u32 addr)
142142
list_add_tail_rcu(&n_ptr->list, &temp_node->list);
143143
n_ptr->action_flags = TIPC_WAIT_PEER_LINKS_DOWN;
144144
n_ptr->signature = INVALID_NODE_SIG;
145+
n_ptr->active_links[0] = INVALID_BEARER_ID;
146+
n_ptr->active_links[1] = INVALID_BEARER_ID;
145147
tipc_node_get(n_ptr);
146148
exit:
147149
spin_unlock_bh(&tn->node_list_lock);
@@ -227,12 +229,13 @@ void tipc_node_remove_conn(struct net *net, u32 dnode, u32 port)
227229
*/
228230
void tipc_node_link_up(struct tipc_node *n, int bearer_id)
229231
{
230-
struct tipc_link_entry **actv = &n->active_links[0];
231-
struct tipc_link_entry *le = &n->links[bearer_id];
232-
struct tipc_link *l = le->link;
232+
int *slot0 = &n->active_links[0];
233+
int *slot1 = &n->active_links[1];
234+
struct tipc_link_entry *links = n->links;
235+
struct tipc_link *l = n->links[bearer_id].link;
233236

234237
/* Leave room for tunnel header when returning 'mtu' to users: */
235-
n->links[bearer_id].mtu = l->mtu - INT_H_SIZE;
238+
links[bearer_id].mtu = l->mtu - INT_H_SIZE;
236239

237240
n->working_links++;
238241
n->action_flags |= TIPC_NOTIFY_LINK_UP;
@@ -242,88 +245,67 @@ void tipc_node_link_up(struct tipc_node *n, int bearer_id)
242245
l->name, l->net_plane);
243246

244247
/* No active links ? => take both active slots */
245-
if (!actv[0]) {
246-
actv[0] = le;
247-
actv[1] = le;
248+
if (*slot0 < 0) {
249+
*slot0 = bearer_id;
250+
*slot1 = bearer_id;
248251
node_established_contact(n);
249252
return;
250253
}
251-
if (l->priority < actv[0]->link->priority) {
254+
255+
/* Lower prio than current active ? => no slot */
256+
if (l->priority < links[*slot0].link->priority) {
252257
pr_debug("New link <%s> becomes standby\n", l->name);
253258
return;
254259
}
255-
tipc_link_dup_queue_xmit(actv[0]->link, l);
260+
tipc_link_dup_queue_xmit(links[*slot0].link, l);
256261

257-
/* Take one active slot if applicable */
258-
if (l->priority == actv[0]->link->priority) {
259-
actv[0] = le;
262+
/* Same prio as current active ? => take one slot */
263+
if (l->priority == links[*slot0].link->priority) {
264+
*slot0 = bearer_id;
260265
return;
261266
}
262-
/* Higher prio than current active? => take both active slots */
263-
pr_debug("Old l <%s> becomes standby\n", actv[0]->link->name);
264-
if (actv[1] != actv[0])
265-
pr_debug("Old link <%s> now standby\n", actv[1]->link->name);
266-
actv[0] = le;
267-
actv[1] = le;
268-
}
269-
270-
/**
271-
* node_select_active_links - select which working links should be active
272-
*/
273-
static void node_select_active_links(struct tipc_node *n)
274-
{
275-
struct tipc_link_entry **actv = &n->active_links[0];
276-
struct tipc_link *l;
277-
u32 b, highest = 0;
278267

279-
actv[0] = NULL;
280-
actv[1] = NULL;
281-
282-
for (b = 0; b < MAX_BEARERS; b++) {
283-
l = n->links[b].link;
284-
if (!l || !tipc_link_is_up(l) || (l->priority < highest))
285-
continue;
286-
if (l->priority > highest) {
287-
highest = l->priority;
288-
actv[0] = &n->links[b];
289-
actv[1] = &n->links[b];
290-
continue;
291-
}
292-
actv[1] = &n->links[b];
293-
}
268+
/* Higher prio than current active => take both active slots */
269+
pr_debug("Old link <%s> now standby\n", links[*slot0].link->name);
270+
*slot0 = bearer_id;
271+
*slot1 = bearer_id;
294272
}
295273

296274
/**
297275
* tipc_node_link_down - handle loss of link
298276
*/
299277
void tipc_node_link_down(struct tipc_node *n, int bearer_id)
300278
{
301-
struct tipc_link_entry **actv = &n->active_links[0];
302-
struct tipc_link_entry *le = &n->links[bearer_id];
303-
struct tipc_link *l = le->link;
279+
int *slot0 = &n->active_links[0];
280+
int *slot1 = &n->active_links[1];
281+
int i, highest = 0;
282+
struct tipc_link *l, *_l;
304283

284+
l = n->links[bearer_id].link;
305285
n->working_links--;
306286
n->action_flags |= TIPC_NOTIFY_LINK_DOWN;
307287
n->link_id = l->peer_bearer_id << 16 | l->bearer_id;
308288

309-
if (!tipc_link_is_active(l)) {
310-
pr_debug("Lost standby link <%s> on network plane %c\n",
311-
l->name, l->net_plane);
312-
return;
313-
}
314289
pr_debug("Lost link <%s> on network plane %c\n",
315290
l->name, l->net_plane);
316291

317-
/* Resdistribute active slots if applicable */
318-
if (actv[0] == le)
319-
actv[0] = actv[1];
320-
if (actv[1] == le)
321-
actv[1] = actv[0];
322-
323-
/* Last link of this priority? => select other ones if available */
324-
if (actv[0] == le)
325-
node_select_active_links(n);
326-
292+
/* Select new active link if any available */
293+
*slot0 = INVALID_BEARER_ID;
294+
*slot1 = INVALID_BEARER_ID;
295+
for (i = 0; i < MAX_BEARERS; i++) {
296+
_l = n->links[i].link;
297+
if (!_l || !tipc_link_is_up(_l))
298+
continue;
299+
if (_l->priority < highest)
300+
continue;
301+
if (_l->priority > highest) {
302+
highest = _l->priority;
303+
*slot0 = i;
304+
*slot1 = i;
305+
continue;
306+
}
307+
*slot1 = i;
308+
}
327309
if (tipc_node_is_up(n))
328310
tipc_link_failover_send_queue(l);
329311
else
@@ -332,7 +314,7 @@ void tipc_node_link_down(struct tipc_node *n, int bearer_id)
332314

333315
bool tipc_node_is_up(struct tipc_node *n)
334316
{
335-
return n->active_links[0];
317+
return n->active_links[0] != INVALID_BEARER_ID;
336318
}
337319

338320
void tipc_node_check_dest(struct tipc_node *n, struct tipc_bearer *b,

net/tipc/node.h

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
/* Out-of-range value for node signature */
4646
#define INVALID_NODE_SIG 0x10000
4747

48+
#define INVALID_BEARER_ID -1
49+
4850
/* Flags used to take different actions according to flag type
4951
* TIPC_WAIT_PEER_LINKS_DOWN: wait to see that peer's links are down
5052
* TIPC_WAIT_OWN_LINKS_DOWN: wait until peer node is declared down
@@ -105,7 +107,7 @@ struct tipc_link_entry {
105107
* @hash: links to adjacent nodes in unsorted hash chain
106108
* @inputq: pointer to input queue containing messages for msg event
107109
* @namedq: pointer to name table input queue with name table messages
108-
* @active_links: pointer into links[] array, identifying which links are active
110+
* @active_links: bearer ids of active links, used as index into links[] array
109111
* @links: array containing references to all links to node
110112
* @action_flags: bit mask of different types of node actions
111113
* @bclink: broadcast-related info
@@ -126,7 +128,7 @@ struct tipc_node {
126128
struct hlist_node hash;
127129
struct sk_buff_head *inputq;
128130
struct sk_buff_head *namedq;
129-
struct tipc_link_entry *active_links[2];
131+
int active_links[2];
130132
struct tipc_link_entry links[MAX_BEARERS];
131133
int action_flags;
132134
struct tipc_node_bclink bclink;
@@ -176,25 +178,27 @@ static inline bool tipc_node_blocked(struct tipc_node *node)
176178

177179
static inline struct tipc_link *node_active_link(struct tipc_node *n, int sel)
178180
{
179-
struct tipc_link_entry *le = n->active_links[sel & 1];
181+
int bearer_id = n->active_links[sel & 1];
182+
183+
if (unlikely(bearer_id == INVALID_BEARER_ID))
184+
return NULL;
180185

181-
if (likely(le))
182-
return le->link;
183-
return NULL;
186+
return n->links[bearer_id].link;
184187
}
185188

186-
static inline uint tipc_node_get_mtu(struct net *net, u32 addr, u32 selector)
189+
static inline unsigned int tipc_node_get_mtu(struct net *net, u32 addr, u32 sel)
187190
{
188191
struct tipc_node *n;
189-
struct tipc_link_entry *le;
192+
int bearer_id;
190193
unsigned int mtu = MAX_MSG_SIZE;
191194

192195
n = tipc_node_find(net, addr);
193196
if (unlikely(!n))
194197
return mtu;
195-
le = n->active_links[selector & 1];
196-
if (likely(le))
197-
mtu = le->mtu;
198+
199+
bearer_id = n->active_links[sel & 1];
200+
if (likely(bearer_id != INVALID_BEARER_ID))
201+
mtu = n->links[bearer_id].mtu;
198202
tipc_node_put(n);
199203
return mtu;
200204
}

0 commit comments

Comments
 (0)