diff options
author | Ying Xue <ying.xue@windriver.com> | 2014-05-04 20:56:17 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-05-05 17:26:45 -0400 |
commit | 3f5a12bd9f9a61d8a12f9adf778b14e4bb8ca050 (patch) | |
tree | 4fe673edf946c5dbcbd472c04d5d20360d897c2e /net/tipc | |
parent | eb8b00f5f248c50603bca383792ac3a618297be0 (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.c | 21 | ||||
-rw-r--r-- | net/tipc/bcast.h | 2 | ||||
-rw-r--r-- | net/tipc/link.c | 22 | ||||
-rw-r--r-- | net/tipc/link.h | 1 |
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 | ||
120 | static void tipc_bclink_unlock(void) | 122 | static 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 | |||
141 | void tipc_bclink_set_flags(unsigned int flags) | ||
142 | { | ||
143 | bclink->flags |= flags; | ||
123 | } | 144 | } |
124 | 145 | ||
125 | static u32 bcbuf_acks(struct sk_buff *buf) | 146 | static 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 | ||
84 | int tipc_bclink_init(void); | 85 | int tipc_bclink_init(void); |
85 | void tipc_bclink_stop(void); | 86 | void tipc_bclink_stop(void); |
87 | void tipc_bclink_set_flags(unsigned int flags); | ||
86 | void tipc_bclink_add_node(u32 addr); | 88 | void tipc_bclink_add_node(u32 addr); |
87 | void tipc_bclink_remove_node(u32 addr); | 89 | void tipc_bclink_remove_node(u32 addr); |
88 | struct tipc_node *tipc_bclink_retransmit_to(void); | 90 | struct 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 | ||
1262 | static void link_reset_all(unsigned long addr) | 1262 | void 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 | ||
1287 | static void link_retransmit_failure(struct tipc_link *l_ptr, | 1282 | static 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); |
231 | struct sk_buff *tipc_link_cmd_reset_stats(const void *req_tlv_area, | 231 | struct sk_buff *tipc_link_cmd_reset_stats(const void *req_tlv_area, |
232 | int req_tlv_space); | 232 | int req_tlv_space); |
233 | void tipc_link_reset_all(struct tipc_node *node); | ||
233 | void tipc_link_reset(struct tipc_link *l_ptr); | 234 | void tipc_link_reset(struct tipc_link *l_ptr); |
234 | void tipc_link_reset_list(unsigned int bearer_id); | 235 | void tipc_link_reset_list(unsigned int bearer_id); |
235 | int tipc_link_xmit(struct sk_buff *buf, u32 dest, u32 selector); | 236 | int tipc_link_xmit(struct sk_buff *buf, u32 dest, u32 selector); |