aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2015-07-16 16:54:22 -0400
committerDavid S. Miller <davem@davemloft.net>2015-07-20 23:41:14 -0400
commit36e78a463b26c9b8017a2e11dcd6c4b8e34b4161 (patch)
treec7094acaffbadf48912af2acbc3f038628ccaa2b /net/tipc
parentd39bbd445dc44259c77bbbc8aadcce7dcdba39cc (diff)
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>
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/node.c106
-rw-r--r--net/tipc/node.h26
2 files changed, 59 insertions, 73 deletions
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 20ec61ceffac..19729645d494 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -142,6 +142,8 @@ struct tipc_node *tipc_node_create(struct net *net, u32 addr)
142 list_add_tail_rcu(&n_ptr->list, &temp_node->list); 142 list_add_tail_rcu(&n_ptr->list, &temp_node->list);
143 n_ptr->action_flags = TIPC_WAIT_PEER_LINKS_DOWN; 143 n_ptr->action_flags = TIPC_WAIT_PEER_LINKS_DOWN;
144 n_ptr->signature = INVALID_NODE_SIG; 144 n_ptr->signature = INVALID_NODE_SIG;
145 n_ptr->active_links[0] = INVALID_BEARER_ID;
146 n_ptr->active_links[1] = INVALID_BEARER_ID;
145 tipc_node_get(n_ptr); 147 tipc_node_get(n_ptr);
146exit: 148exit:
147 spin_unlock_bh(&tn->node_list_lock); 149 spin_unlock_bh(&tn->node_list_lock);
@@ -227,12 +229,13 @@ void tipc_node_remove_conn(struct net *net, u32 dnode, u32 port)
227 */ 229 */
228void tipc_node_link_up(struct tipc_node *n, int bearer_id) 230void tipc_node_link_up(struct tipc_node *n, int bearer_id)
229{ 231{
230 struct tipc_link_entry **actv = &n->active_links[0]; 232 int *slot0 = &n->active_links[0];
231 struct tipc_link_entry *le = &n->links[bearer_id]; 233 int *slot1 = &n->active_links[1];
232 struct tipc_link *l = le->link; 234 struct tipc_link_entry *links = n->links;
235 struct tipc_link *l = n->links[bearer_id].link;
233 236
234 /* Leave room for tunnel header when returning 'mtu' to users: */ 237 /* 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;
236 239
237 n->working_links++; 240 n->working_links++;
238 n->action_flags |= TIPC_NOTIFY_LINK_UP; 241 n->action_flags |= TIPC_NOTIFY_LINK_UP;
@@ -242,55 +245,30 @@ void tipc_node_link_up(struct tipc_node *n, int bearer_id)
242 l->name, l->net_plane); 245 l->name, l->net_plane);
243 246
244 /* No active links ? => take both active slots */ 247 /* No active links ? => take both active slots */
245 if (!actv[0]) { 248 if (*slot0 < 0) {
246 actv[0] = le; 249 *slot0 = bearer_id;
247 actv[1] = le; 250 *slot1 = bearer_id;
248 node_established_contact(n); 251 node_established_contact(n);
249 return; 252 return;
250 } 253 }
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) {
252 pr_debug("New link <%s> becomes standby\n", l->name); 257 pr_debug("New link <%s> becomes standby\n", l->name);
253 return; 258 return;
254 } 259 }
255 tipc_link_dup_queue_xmit(actv[0]->link, l); 260 tipc_link_dup_queue_xmit(links[*slot0].link, l);
256 261
257 /* Take one active slot if applicable */ 262 /* Same prio as current active ? => take one slot */
258 if (l->priority == actv[0]->link->priority) { 263 if (l->priority == links[*slot0].link->priority) {
259 actv[0] = le; 264 *slot0 = bearer_id;
260 return; 265 return;
261 } 266 }
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 */
273static 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;
278 267
279 actv[0] = NULL; 268 /* Higher prio than current active => take both active slots */
280 actv[1] = NULL; 269 pr_debug("Old link <%s> now standby\n", links[*slot0].link->name);
281 270 *slot0 = bearer_id;
282 for (b = 0; b < MAX_BEARERS; b++) { 271 *slot1 = bearer_id;
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 }
294} 272}
295 273
296/** 274/**
@@ -298,32 +276,36 @@ static void node_select_active_links(struct tipc_node *n)
298 */ 276 */
299void tipc_node_link_down(struct tipc_node *n, int bearer_id) 277void tipc_node_link_down(struct tipc_node *n, int bearer_id)
300{ 278{
301 struct tipc_link_entry **actv = &n->active_links[0]; 279 int *slot0 = &n->active_links[0];
302 struct tipc_link_entry *le = &n->links[bearer_id]; 280 int *slot1 = &n->active_links[1];
303 struct tipc_link *l = le->link; 281 int i, highest = 0;
282 struct tipc_link *l, *_l;
304 283
284 l = n->links[bearer_id].link;
305 n->working_links--; 285 n->working_links--;
306 n->action_flags |= TIPC_NOTIFY_LINK_DOWN; 286 n->action_flags |= TIPC_NOTIFY_LINK_DOWN;
307 n->link_id = l->peer_bearer_id << 16 | l->bearer_id; 287 n->link_id = l->peer_bearer_id << 16 | l->bearer_id;
308 288
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 }
314 pr_debug("Lost link <%s> on network plane %c\n", 289 pr_debug("Lost link <%s> on network plane %c\n",
315 l->name, l->net_plane); 290 l->name, l->net_plane);
316 291
317 /* Resdistribute active slots if applicable */ 292 /* Select new active link if any available */
318 if (actv[0] == le) 293 *slot0 = INVALID_BEARER_ID;
319 actv[0] = actv[1]; 294 *slot1 = INVALID_BEARER_ID;
320 if (actv[1] == le) 295 for (i = 0; i < MAX_BEARERS; i++) {
321 actv[1] = actv[0]; 296 _l = n->links[i].link;
322 297 if (!_l || !tipc_link_is_up(_l))
323 /* Last link of this priority? => select other ones if available */ 298 continue;
324 if (actv[0] == le) 299 if (_l->priority < highest)
325 node_select_active_links(n); 300 continue;
326 301 if (_l->priority > highest) {
302 highest = _l->priority;
303 *slot0 = i;
304 *slot1 = i;
305 continue;
306 }
307 *slot1 = i;
308 }
327 if (tipc_node_is_up(n)) 309 if (tipc_node_is_up(n))
328 tipc_link_failover_send_queue(l); 310 tipc_link_failover_send_queue(l);
329 else 311 else
@@ -332,7 +314,7 @@ void tipc_node_link_down(struct tipc_node *n, int bearer_id)
332 314
333bool tipc_node_is_up(struct tipc_node *n) 315bool tipc_node_is_up(struct tipc_node *n)
334{ 316{
335 return n->active_links[0]; 317 return n->active_links[0] != INVALID_BEARER_ID;
336} 318}
337 319
338void tipc_node_check_dest(struct tipc_node *n, struct tipc_bearer *b, 320void tipc_node_check_dest(struct tipc_node *n, struct tipc_bearer *b,
diff --git a/net/tipc/node.h b/net/tipc/node.h
index 0657cbf1f5cd..74f278adada3 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -45,6 +45,8 @@
45/* Out-of-range value for node signature */ 45/* Out-of-range value for node signature */
46#define INVALID_NODE_SIG 0x10000 46#define INVALID_NODE_SIG 0x10000
47 47
48#define INVALID_BEARER_ID -1
49
48/* Flags used to take different actions according to flag type 50/* Flags used to take different actions according to flag type
49 * TIPC_WAIT_PEER_LINKS_DOWN: wait to see that peer's links are down 51 * TIPC_WAIT_PEER_LINKS_DOWN: wait to see that peer's links are down
50 * TIPC_WAIT_OWN_LINKS_DOWN: wait until peer node is declared down 52 * TIPC_WAIT_OWN_LINKS_DOWN: wait until peer node is declared down
@@ -105,7 +107,7 @@ struct tipc_link_entry {
105 * @hash: links to adjacent nodes in unsorted hash chain 107 * @hash: links to adjacent nodes in unsorted hash chain
106 * @inputq: pointer to input queue containing messages for msg event 108 * @inputq: pointer to input queue containing messages for msg event
107 * @namedq: pointer to name table input queue with name table messages 109 * @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
109 * @links: array containing references to all links to node 111 * @links: array containing references to all links to node
110 * @action_flags: bit mask of different types of node actions 112 * @action_flags: bit mask of different types of node actions
111 * @bclink: broadcast-related info 113 * @bclink: broadcast-related info
@@ -126,7 +128,7 @@ struct tipc_node {
126 struct hlist_node hash; 128 struct hlist_node hash;
127 struct sk_buff_head *inputq; 129 struct sk_buff_head *inputq;
128 struct sk_buff_head *namedq; 130 struct sk_buff_head *namedq;
129 struct tipc_link_entry *active_links[2]; 131 int active_links[2];
130 struct tipc_link_entry links[MAX_BEARERS]; 132 struct tipc_link_entry links[MAX_BEARERS];
131 int action_flags; 133 int action_flags;
132 struct tipc_node_bclink bclink; 134 struct tipc_node_bclink bclink;
@@ -176,25 +178,27 @@ static inline bool tipc_node_blocked(struct tipc_node *node)
176 178
177static inline struct tipc_link *node_active_link(struct tipc_node *n, int sel) 179static inline struct tipc_link *node_active_link(struct tipc_node *n, int sel)
178{ 180{
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;
180 185
181 if (likely(le)) 186 return n->links[bearer_id].link;
182 return le->link;
183 return NULL;
184} 187}
185 188
186static inline uint tipc_node_get_mtu(struct net *net, u32 addr, u32 selector) 189static inline unsigned int tipc_node_get_mtu(struct net *net, u32 addr, u32 sel)
187{ 190{
188 struct tipc_node *n; 191 struct tipc_node *n;
189 struct tipc_link_entry *le; 192 int bearer_id;
190 unsigned int mtu = MAX_MSG_SIZE; 193 unsigned int mtu = MAX_MSG_SIZE;
191 194
192 n = tipc_node_find(net, addr); 195 n = tipc_node_find(net, addr);
193 if (unlikely(!n)) 196 if (unlikely(!n))
194 return mtu; 197 return mtu;
195 le = n->active_links[selector & 1]; 198
196 if (likely(le)) 199 bearer_id = n->active_links[sel & 1];
197 mtu = le->mtu; 200 if (likely(bearer_id != INVALID_BEARER_ID))
201 mtu = n->links[bearer_id].mtu;
198 tipc_node_put(n); 202 tipc_node_put(n);
199 return mtu; 203 return mtu;
200} 204}