aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/node.c
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2014-08-22 18:09:07 -0400
committerDavid S. Miller <davem@davemloft.net>2014-08-23 14:18:33 -0400
commit50100a5e39461b2a61d6040e73c384766c29975d (patch)
tree7f632d0f22af7f38c282603e5c9f4de3139bce59 /net/tipc/node.c
parent1dd0bd2b14032037d40a316dd52370f1713fa62b (diff)
tipc: use pseudo message to wake up sockets after link congestion
The current link implementation keeps a linked list of blocked ports/ sockets that is populated when there is link congestion. The purpose of this is to let the link know which users to wake up when the congestion abates. This adds unnecessary complexity to the data structure and the code, since it forces us to involve the link each time we want to delete a socket. It also forces us to grab the spinlock port_lock within the scope of node_lock. We want to get rid of this direct dependence, as well as the deadlock hazard resulting from the usage of port_lock. In this commit, we instead let the link keep list of a "wakeup" pseudo messages for use in such situations. Those messages are sent to the pending sockets via the ordinary message reception path, and wake up the socket's owner when they are received. This enables us to get rid of the 'waiting_ports' linked lists in struct tipc_port that manifest this direct reference. As a consequence, we can eliminate another BH entry into the socket, and hence the need to grab port_lock. This is a further step in our effort to remove port_lock altogether. Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Reviewed-by: Erik Hugne <erik.hugne@ericsson.com> Reviewed-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/node.c')
-rw-r--r--net/tipc/node.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/net/tipc/node.c b/net/tipc/node.c
index f7069299943f..6ea2c15cfc88 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -38,6 +38,7 @@
38#include "config.h" 38#include "config.h"
39#include "node.h" 39#include "node.h"
40#include "name_distr.h" 40#include "name_distr.h"
41#include "socket.h"
41 42
42#define NODE_HTABLE_SIZE 512 43#define NODE_HTABLE_SIZE 512
43 44
@@ -100,6 +101,7 @@ struct tipc_node *tipc_node_create(u32 addr)
100 INIT_HLIST_NODE(&n_ptr->hash); 101 INIT_HLIST_NODE(&n_ptr->hash);
101 INIT_LIST_HEAD(&n_ptr->list); 102 INIT_LIST_HEAD(&n_ptr->list);
102 INIT_LIST_HEAD(&n_ptr->nsub); 103 INIT_LIST_HEAD(&n_ptr->nsub);
104 __skb_queue_head_init(&n_ptr->waiting_sks);
103 105
104 hlist_add_head_rcu(&n_ptr->hash, &node_htable[tipc_hashfn(addr)]); 106 hlist_add_head_rcu(&n_ptr->hash, &node_htable[tipc_hashfn(addr)]);
105 107
@@ -474,6 +476,7 @@ int tipc_node_get_linkname(u32 bearer_id, u32 addr, char *linkname, size_t len)
474void tipc_node_unlock(struct tipc_node *node) 476void tipc_node_unlock(struct tipc_node *node)
475{ 477{
476 LIST_HEAD(nsub_list); 478 LIST_HEAD(nsub_list);
479 struct sk_buff_head waiting_sks;
477 u32 addr = 0; 480 u32 addr = 0;
478 481
479 if (likely(!node->action_flags)) { 482 if (likely(!node->action_flags)) {
@@ -481,6 +484,11 @@ void tipc_node_unlock(struct tipc_node *node)
481 return; 484 return;
482 } 485 }
483 486
487 __skb_queue_head_init(&waiting_sks);
488 if (node->action_flags & TIPC_WAKEUP_USERS) {
489 skb_queue_splice_init(&node->waiting_sks, &waiting_sks);
490 node->action_flags &= ~TIPC_WAKEUP_USERS;
491 }
484 if (node->action_flags & TIPC_NOTIFY_NODE_DOWN) { 492 if (node->action_flags & TIPC_NOTIFY_NODE_DOWN) {
485 list_replace_init(&node->nsub, &nsub_list); 493 list_replace_init(&node->nsub, &nsub_list);
486 node->action_flags &= ~TIPC_NOTIFY_NODE_DOWN; 494 node->action_flags &= ~TIPC_NOTIFY_NODE_DOWN;
@@ -491,8 +499,12 @@ void tipc_node_unlock(struct tipc_node *node)
491 } 499 }
492 spin_unlock_bh(&node->lock); 500 spin_unlock_bh(&node->lock);
493 501
502 while (!skb_queue_empty(&waiting_sks))
503 tipc_sk_rcv(__skb_dequeue(&waiting_sks));
504
494 if (!list_empty(&nsub_list)) 505 if (!list_empty(&nsub_list))
495 tipc_nodesub_notify(&nsub_list); 506 tipc_nodesub_notify(&nsub_list);
507
496 if (addr) 508 if (addr)
497 tipc_named_node_up(addr); 509 tipc_named_node_up(addr);
498} 510}