aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/name_table.c
diff options
context:
space:
mode:
authorYing Xue <ying.xue@windriver.com>2014-12-02 02:00:28 -0500
committerDavid S. Miller <davem@davemloft.net>2014-12-08 20:39:57 -0500
commit5492390a9495bade807afca61eab860f852e33fa (patch)
tree8e3ea19de6d1ca5cab811922c60250e5be64bd33 /net/tipc/name_table.c
parent3493d25cfb5eee9d0045c2720878a26dcbeafa73 (diff)
tipc: simplify relationship between name table lock and node lock
When tipc name sequence is published, name table lock is released before name sequence buffer is delivered to remote nodes through its underlying unicast links. However, when name sequence is withdrawn, the name table lock is held until the transmission of the removal message of name sequence is finished. During the process, node lock is nested in name table lock. To prevent node lock from being nested in name table lock, while withdrawing name, we should adopt the same locking policy of publishing name sequence: name table lock should be released before message is sent. Signed-off-by: Ying Xue <ying.xue@windriver.com> Reviewed-by: Erik Hugne <erik.hugne@ericsson.com> Reviewed-by: Jon Maloy <jon.maloy@ericsson.com> Tested-by: Erik Hugne <erik.hugne@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/name_table.c')
-rw-r--r--net/tipc/name_table.c19
1 files changed, 10 insertions, 9 deletions
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 93bac40292c1..bc3e7ed80000 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -685,27 +685,28 @@ struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper,
685int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key) 685int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key)
686{ 686{
687 struct publication *publ; 687 struct publication *publ;
688 struct sk_buff *buf; 688 struct sk_buff *skb = NULL;
689 689
690 write_lock_bh(&tipc_nametbl_lock); 690 write_lock_bh(&tipc_nametbl_lock);
691 publ = tipc_nametbl_remove_publ(type, lower, tipc_own_addr, ref, key); 691 publ = tipc_nametbl_remove_publ(type, lower, tipc_own_addr, ref, key);
692 if (likely(publ)) { 692 if (likely(publ)) {
693 tipc_nametbl->local_publ_count--; 693 tipc_nametbl->local_publ_count--;
694 buf = tipc_named_withdraw(publ); 694 skb = tipc_named_withdraw(publ);
695 /* Any pending external events? */ 695 /* Any pending external events? */
696 tipc_named_process_backlog(); 696 tipc_named_process_backlog();
697 write_unlock_bh(&tipc_nametbl_lock);
698 list_del_init(&publ->pport_list); 697 list_del_init(&publ->pport_list);
699 kfree(publ); 698 kfree(publ);
699 } else {
700 pr_err("Unable to remove local publication\n"
701 "(type=%u, lower=%u, ref=%u, key=%u)\n",
702 type, lower, ref, key);
703 }
704 write_unlock_bh(&tipc_nametbl_lock);
700 705
701 if (buf) 706 if (skb) {
702 named_cluster_distribute(buf); 707 named_cluster_distribute(skb);
703 return 1; 708 return 1;
704 } 709 }
705 write_unlock_bh(&tipc_nametbl_lock);
706 pr_err("Unable to remove local publication\n"
707 "(type=%u, lower=%u, ref=%u, key=%u)\n",
708 type, lower, ref, key);
709 return 0; 710 return 0;
710} 711}
711 712