aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/node.c
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2015-07-16 16:54:21 -0400
committerDavid S. Miller <davem@davemloft.net>2015-07-20 23:41:14 -0400
commitd39bbd445dc44259c77bbbc8aadcce7dcdba39cc (patch)
treec82e8d60ae0426c7e0605374e285bf606fdd4ed8 /net/tipc/node.c
parentd3a43b907ae688af6cb753c53cd7de05f3c1ba85 (diff)
tipc: move link input queue to tipc_node
At present, the link input queue and the name distributor receive queues are fields aggregated in struct tipc_link. This is a hazard, because a link might be deleted while a receiving socket still keeps reference to one of the queues. This commit fixes this bug. However, rather than adding yet another reference counter to the critical data path, we move the two queues to safe ground inside struct tipc_node, which is already protected, and let the link code only handle references to the queues. This is also in line with planned later changes in this area. 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/node.c')
-rw-r--r--net/tipc/node.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 06f642abdf38..20ec61ceffac 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -132,6 +132,7 @@ struct tipc_node *tipc_node_create(struct net *net, u32 addr)
132 INIT_LIST_HEAD(&n_ptr->list); 132 INIT_LIST_HEAD(&n_ptr->list);
133 INIT_LIST_HEAD(&n_ptr->publ_list); 133 INIT_LIST_HEAD(&n_ptr->publ_list);
134 INIT_LIST_HEAD(&n_ptr->conn_sks); 134 INIT_LIST_HEAD(&n_ptr->conn_sks);
135 skb_queue_head_init(&n_ptr->bclink.namedq);
135 __skb_queue_head_init(&n_ptr->bclink.deferdq); 136 __skb_queue_head_init(&n_ptr->bclink.deferdq);
136 hlist_add_head_rcu(&n_ptr->hash, &tn->node_htable[tipc_hashfn(addr)]); 137 hlist_add_head_rcu(&n_ptr->hash, &tn->node_htable[tipc_hashfn(addr)]);
137 list_for_each_entry_rcu(temp_node, &tn->node_list, list) { 138 list_for_each_entry_rcu(temp_node, &tn->node_list, list) {
@@ -350,9 +351,10 @@ bool tipc_node_update_dest(struct tipc_node *n, struct tipc_bearer *b,
350{ 351{
351 struct tipc_link *l = n->links[b->identity].link; 352 struct tipc_link *l = n->links[b->identity].link;
352 struct tipc_media_addr *curr = &n->links[b->identity].maddr; 353 struct tipc_media_addr *curr = &n->links[b->identity].maddr;
354 struct sk_buff_head *inputq = &n->links[b->identity].inputq;
353 355
354 if (!l) 356 if (!l)
355 l = tipc_link_create(n, b, maddr); 357 l = tipc_link_create(n, b, maddr, inputq, &n->bclink.namedq);
356 if (!l) 358 if (!l)
357 return false; 359 return false;
358 memcpy(&l->media_addr, maddr, sizeof(*maddr)); 360 memcpy(&l->media_addr, maddr, sizeof(*maddr));