aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorYing Xue <ying.xue@windriver.com>2014-05-04 20:56:14 -0400
committerDavid S. Miller <davem@davemloft.net>2014-05-05 17:26:44 -0400
commitca0c42732c512a12fabe677594840f31861dd31a (patch)
tree80f703e28c77128d77006e47b9e6a9c8735fb5df /net
parent9d561949685749be3d97239eab7d85aa78718108 (diff)
tipc: avoid to asynchronously deliver name tables to peer node
Postpone the actions of delivering name tables until after node lock is released, avoiding to do it under asynchronous context. 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> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/tipc/name_distr.c52
-rw-r--r--net/tipc/name_distr.h30
-rw-r--r--net/tipc/node.c16
-rw-r--r--net/tipc/node.h8
4 files changed, 52 insertions, 54 deletions
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index 8465263246c3..8ce730984aa1 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -38,34 +38,6 @@
38#include "link.h" 38#include "link.h"
39#include "name_distr.h" 39#include "name_distr.h"
40 40
41#define ITEM_SIZE sizeof(struct distr_item)
42
43/**
44 * struct distr_item - publication info distributed to other nodes
45 * @type: name sequence type
46 * @lower: name sequence lower bound
47 * @upper: name sequence upper bound
48 * @ref: publishing port reference
49 * @key: publication key
50 *
51 * ===> All fields are stored in network byte order. <===
52 *
53 * First 3 fields identify (name or) name sequence being published.
54 * Reference field uniquely identifies port that published name sequence.
55 * Key field uniquely identifies publication, in the event a port has
56 * multiple publications of the same name sequence.
57 *
58 * Note: There is no field that identifies the publishing node because it is
59 * the same for all items contained within a publication message.
60 */
61struct distr_item {
62 __be32 type;
63 __be32 lower;
64 __be32 upper;
65 __be32 ref;
66 __be32 key;
67};
68
69/** 41/**
70 * struct publ_list - list of publications made by this node 42 * struct publ_list - list of publications made by this node
71 * @list: circular list of publications 43 * @list: circular list of publications
@@ -239,29 +211,9 @@ static void named_distribute(struct list_head *message_list, u32 node,
239/** 211/**
240 * tipc_named_node_up - tell specified node about all publications by this node 212 * tipc_named_node_up - tell specified node about all publications by this node
241 */ 213 */
242void tipc_named_node_up(unsigned long nodearg) 214void tipc_named_node_up(u32 max_item_buf, u32 node)
243{ 215{
244 struct tipc_node *n_ptr; 216 LIST_HEAD(message_list);
245 struct tipc_link *l_ptr;
246 struct list_head message_list;
247 u32 node = (u32)nodearg;
248 u32 max_item_buf = 0;
249
250 /* compute maximum amount of publication data to send per message */
251 n_ptr = tipc_node_find(node);
252 if (n_ptr) {
253 tipc_node_lock(n_ptr);
254 l_ptr = n_ptr->active_links[0];
255 if (l_ptr)
256 max_item_buf = ((l_ptr->max_pkt - INT_H_SIZE) /
257 ITEM_SIZE) * ITEM_SIZE;
258 tipc_node_unlock(n_ptr);
259 }
260 if (!max_item_buf)
261 return;
262
263 /* create list of publication messages, then send them as a unit */
264 INIT_LIST_HEAD(&message_list);
265 217
266 read_lock_bh(&tipc_nametbl_lock); 218 read_lock_bh(&tipc_nametbl_lock);
267 named_distribute(&message_list, node, &publ_cluster, max_item_buf); 219 named_distribute(&message_list, node, &publ_cluster, max_item_buf);
diff --git a/net/tipc/name_distr.h b/net/tipc/name_distr.h
index 47ff829f9361..b2eed4ec1526 100644
--- a/net/tipc/name_distr.h
+++ b/net/tipc/name_distr.h
@@ -39,10 +39,38 @@
39 39
40#include "name_table.h" 40#include "name_table.h"
41 41
42#define ITEM_SIZE sizeof(struct distr_item)
43
44/**
45 * struct distr_item - publication info distributed to other nodes
46 * @type: name sequence type
47 * @lower: name sequence lower bound
48 * @upper: name sequence upper bound
49 * @ref: publishing port reference
50 * @key: publication key
51 *
52 * ===> All fields are stored in network byte order. <===
53 *
54 * First 3 fields identify (name or) name sequence being published.
55 * Reference field uniquely identifies port that published name sequence.
56 * Key field uniquely identifies publication, in the event a port has
57 * multiple publications of the same name sequence.
58 *
59 * Note: There is no field that identifies the publishing node because it is
60 * the same for all items contained within a publication message.
61 */
62struct distr_item {
63 __be32 type;
64 __be32 lower;
65 __be32 upper;
66 __be32 ref;
67 __be32 key;
68};
69
42struct sk_buff *tipc_named_publish(struct publication *publ); 70struct sk_buff *tipc_named_publish(struct publication *publ);
43struct sk_buff *tipc_named_withdraw(struct publication *publ); 71struct sk_buff *tipc_named_withdraw(struct publication *publ);
44void named_cluster_distribute(struct sk_buff *buf); 72void named_cluster_distribute(struct sk_buff *buf);
45void tipc_named_node_up(unsigned long node); 73void tipc_named_node_up(u32 max_item_buf, u32 node);
46void tipc_named_rcv(struct sk_buff *buf); 74void tipc_named_rcv(struct sk_buff *buf);
47void tipc_named_reinit(void); 75void tipc_named_reinit(void);
48 76
diff --git a/net/tipc/node.c b/net/tipc/node.c
index c3a36bba9952..74efebc1cb7a 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -267,7 +267,7 @@ void tipc_node_detach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
267 267
268static void node_established_contact(struct tipc_node *n_ptr) 268static void node_established_contact(struct tipc_node *n_ptr)
269{ 269{
270 tipc_k_signal((Handler)tipc_named_node_up, n_ptr->addr); 270 n_ptr->flags |= TIPC_NODE_UP;
271 n_ptr->bclink.oos_state = 0; 271 n_ptr->bclink.oos_state = 0;
272 n_ptr->bclink.acked = tipc_bclink_get_last_sent(); 272 n_ptr->bclink.acked = tipc_bclink_get_last_sent();
273 tipc_bclink_add_node(n_ptr->addr); 273 tipc_bclink_add_node(n_ptr->addr);
@@ -455,6 +455,9 @@ int tipc_node_get_linkname(u32 bearer_id, u32 addr, char *linkname, size_t len)
455void tipc_node_unlock(struct tipc_node *node) 455void tipc_node_unlock(struct tipc_node *node)
456{ 456{
457 LIST_HEAD(nsub_list); 457 LIST_HEAD(nsub_list);
458 struct tipc_link *link;
459 int pkt_sz = 0;
460 u32 addr = 0;
458 461
459 if (likely(!node->flags)) { 462 if (likely(!node->flags)) {
460 spin_unlock_bh(&node->lock); 463 spin_unlock_bh(&node->lock);
@@ -465,8 +468,19 @@ void tipc_node_unlock(struct tipc_node *node)
465 list_replace_init(&node->nsub, &nsub_list); 468 list_replace_init(&node->nsub, &nsub_list);
466 node->flags &= ~TIPC_NODE_LOST; 469 node->flags &= ~TIPC_NODE_LOST;
467 } 470 }
471 if (node->flags & TIPC_NODE_UP) {
472 link = node->active_links[0];
473 node->flags &= ~TIPC_NODE_UP;
474 if (link) {
475 pkt_sz = ((link->max_pkt - INT_H_SIZE) / ITEM_SIZE) *
476 ITEM_SIZE;
477 addr = node->addr;
478 }
479 }
468 spin_unlock_bh(&node->lock); 480 spin_unlock_bh(&node->lock);
469 481
470 if (!list_empty(&nsub_list)) 482 if (!list_empty(&nsub_list))
471 tipc_nodesub_notify(&nsub_list); 483 tipc_nodesub_notify(&nsub_list);
484 if (pkt_sz)
485 tipc_named_node_up(pkt_sz, addr);
472} 486}
diff --git a/net/tipc/node.h b/net/tipc/node.h
index 4bd5eff82ce0..38f710fb75dc 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -48,15 +48,19 @@
48#define INVALID_NODE_SIG 0x10000 48#define INVALID_NODE_SIG 0x10000
49 49
50/* Flags used to block (re)establishment of contact with a neighboring node 50/* Flags used to block (re)establishment of contact with a neighboring node
51 * TIPC_NODE_DOWN: indicate node is down 51 * TIPC_NODE_DOWN: indicate node is down and it's used to block the node's
52 * links until RESET or ACTIVE message arrives
52 * TIPC_NODE_RESET: indicate node is reset 53 * TIPC_NODE_RESET: indicate node is reset
53 * TIPC_NODE_LOST: indicate node is lost and it's used to notify subscriptions 54 * TIPC_NODE_LOST: indicate node is lost and it's used to notify subscriptions
54 * when node lock is released 55 * when node lock is released
56 * TIPC_NODE_UP: indicate node is up and it's used to deliver local name table
57 * when node lock is released
55 */ 58 */
56enum { 59enum {
57 TIPC_NODE_DOWN = (1 << 1), 60 TIPC_NODE_DOWN = (1 << 1),
58 TIPC_NODE_RESET = (1 << 2), 61 TIPC_NODE_RESET = (1 << 2),
59 TIPC_NODE_LOST = (1 << 3) 62 TIPC_NODE_LOST = (1 << 3),
63 TIPC_NODE_UP = (1 << 4)
60}; 64};
61 65
62/** 66/**