aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
authorYing Xue <ying.xue@windriver.com>2014-05-04 20:56:17 -0400
committerDavid S. Miller <davem@davemloft.net>2014-05-05 17:26:45 -0400
commit3f5a12bd9f9a61d8a12f9adf778b14e4bb8ca050 (patch)
tree4fe673edf946c5dbcbd472c04d5d20360d897c2e /net/tipc
parenteb8b00f5f248c50603bca383792ac3a618297be0 (diff)
tipc: avoid to asynchronously reset all links
Postpone the actions of resetting all links until after bclink lock is released, avoiding to asynchronously reset all links. 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/tipc')
-rw-r--r--net/tipc/bcast.c21
-rw-r--r--net/tipc/bcast.h2
-rw-r--r--net/tipc/link.c22
-rw-r--r--net/tipc/link.h1
4 files changed, 32 insertions, 14 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index ef8cff4ad743..a0978d0890cb 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -87,6 +87,7 @@ struct tipc_bcbearer {
87 * @lock: spinlock governing access to structure 87 * @lock: spinlock governing access to structure
88 * @link: (non-standard) broadcast link structure 88 * @link: (non-standard) broadcast link structure
89 * @node: (non-standard) node structure representing b'cast link's peer node 89 * @node: (non-standard) node structure representing b'cast link's peer node
90 * @flags: represent bclink states
90 * @bcast_nodes: map of broadcast-capable nodes 91 * @bcast_nodes: map of broadcast-capable nodes
91 * @retransmit_to: node that most recently requested a retransmit 92 * @retransmit_to: node that most recently requested a retransmit
92 * 93 *
@@ -96,6 +97,7 @@ struct tipc_bclink {
96 spinlock_t lock; 97 spinlock_t lock;
97 struct tipc_link link; 98 struct tipc_link link;
98 struct tipc_node node; 99 struct tipc_node node;
100 unsigned int flags;
99 struct tipc_node_map bcast_nodes; 101 struct tipc_node_map bcast_nodes;
100 struct tipc_node *retransmit_to; 102 struct tipc_node *retransmit_to;
101}; 103};
@@ -119,7 +121,26 @@ static void tipc_bclink_lock(void)
119 121
120static void tipc_bclink_unlock(void) 122static void tipc_bclink_unlock(void)
121{ 123{
124 struct tipc_node *node = NULL;
125
126 if (likely(!bclink->flags)) {
127 spin_unlock_bh(&bclink->lock);
128 return;
129 }
130
131 if (bclink->flags & TIPC_BCLINK_RESET) {
132 bclink->flags &= ~TIPC_BCLINK_RESET;
133 node = tipc_bclink_retransmit_to();
134 }
122 spin_unlock_bh(&bclink->lock); 135 spin_unlock_bh(&bclink->lock);
136
137 if (node)
138 tipc_link_reset_all(node);
139}
140
141void tipc_bclink_set_flags(unsigned int flags)
142{
143 bclink->flags |= flags;
123} 144}
124 145
125static u32 bcbuf_acks(struct sk_buff *buf) 146static u32 bcbuf_acks(struct sk_buff *buf)
diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h
index ea162c7b30ee..00330c45df3e 100644
--- a/net/tipc/bcast.h
+++ b/net/tipc/bcast.h
@@ -39,6 +39,7 @@
39 39
40#define MAX_NODES 4096 40#define MAX_NODES 4096
41#define WSIZE 32 41#define WSIZE 32
42#define TIPC_BCLINK_RESET 1
42 43
43/** 44/**
44 * struct tipc_node_map - set of node identifiers 45 * struct tipc_node_map - set of node identifiers
@@ -83,6 +84,7 @@ void tipc_port_list_free(struct tipc_port_list *pl_ptr);
83 84
84int tipc_bclink_init(void); 85int tipc_bclink_init(void);
85void tipc_bclink_stop(void); 86void tipc_bclink_stop(void);
87void tipc_bclink_set_flags(unsigned int flags);
86void tipc_bclink_add_node(u32 addr); 88void tipc_bclink_add_node(u32 addr);
87void tipc_bclink_remove_node(u32 addr); 89void tipc_bclink_remove_node(u32 addr);
88struct tipc_node *tipc_bclink_retransmit_to(void); 90struct tipc_node *tipc_bclink_retransmit_to(void);
diff --git a/net/tipc/link.c b/net/tipc/link.c
index ac074aaf104d..dce2bef81720 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1259,29 +1259,24 @@ void tipc_link_push_queue(struct tipc_link *l_ptr)
1259 } while (!res); 1259 } while (!res);
1260} 1260}
1261 1261
1262static void link_reset_all(unsigned long addr) 1262void tipc_link_reset_all(struct tipc_node *node)
1263{ 1263{
1264 struct tipc_node *n_ptr;
1265 char addr_string[16]; 1264 char addr_string[16];
1266 u32 i; 1265 u32 i;
1267 1266
1268 n_ptr = tipc_node_find((u32)addr); 1267 tipc_node_lock(node);
1269 if (!n_ptr)
1270 return; /* node no longer exists */
1271
1272 tipc_node_lock(n_ptr);
1273 1268
1274 pr_warn("Resetting all links to %s\n", 1269 pr_warn("Resetting all links to %s\n",
1275 tipc_addr_string_fill(addr_string, n_ptr->addr)); 1270 tipc_addr_string_fill(addr_string, node->addr));
1276 1271
1277 for (i = 0; i < MAX_BEARERS; i++) { 1272 for (i = 0; i < MAX_BEARERS; i++) {
1278 if (n_ptr->links[i]) { 1273 if (node->links[i]) {
1279 link_print(n_ptr->links[i], "Resetting link\n"); 1274 link_print(node->links[i], "Resetting link\n");
1280 tipc_link_reset(n_ptr->links[i]); 1275 tipc_link_reset(node->links[i]);
1281 } 1276 }
1282 } 1277 }
1283 1278
1284 tipc_node_unlock(n_ptr); 1279 tipc_node_unlock(node);
1285} 1280}
1286 1281
1287static void link_retransmit_failure(struct tipc_link *l_ptr, 1282static void link_retransmit_failure(struct tipc_link *l_ptr,
@@ -1318,10 +1313,9 @@ static void link_retransmit_failure(struct tipc_link *l_ptr,
1318 n_ptr->bclink.oos_state, 1313 n_ptr->bclink.oos_state,
1319 n_ptr->bclink.last_sent); 1314 n_ptr->bclink.last_sent);
1320 1315
1321 tipc_k_signal((Handler)link_reset_all, (unsigned long)n_ptr->addr);
1322
1323 tipc_node_unlock(n_ptr); 1316 tipc_node_unlock(n_ptr);
1324 1317
1318 tipc_bclink_set_flags(TIPC_BCLINK_RESET);
1325 l_ptr->stale_count = 0; 1319 l_ptr->stale_count = 0;
1326 } 1320 }
1327} 1321}
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 4b556c181bae..7ba73fa6b81e 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -230,6 +230,7 @@ struct sk_buff *tipc_link_cmd_show_stats(const void *req_tlv_area,
230 int req_tlv_space); 230 int req_tlv_space);
231struct sk_buff *tipc_link_cmd_reset_stats(const void *req_tlv_area, 231struct sk_buff *tipc_link_cmd_reset_stats(const void *req_tlv_area,
232 int req_tlv_space); 232 int req_tlv_space);
233void tipc_link_reset_all(struct tipc_node *node);
233void tipc_link_reset(struct tipc_link *l_ptr); 234void tipc_link_reset(struct tipc_link *l_ptr);
234void tipc_link_reset_list(unsigned int bearer_id); 235void tipc_link_reset_list(unsigned int bearer_id);
235int tipc_link_xmit(struct sk_buff *buf, u32 dest, u32 selector); 236int tipc_link_xmit(struct sk_buff *buf, u32 dest, u32 selector);