aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/node.c
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2015-07-16 16:54:29 -0400
committerDavid S. Miller <davem@davemloft.net>2015-07-20 23:41:16 -0400
commit8a1577c96f122308ac9b5f195f9f9a7dd74ac541 (patch)
tree76c366004226f31bb11af37dfa00a6d0146fc4ad /net/tipc/node.c
parent333ef69ed2121f535e00ceb26e095d3745584c6e (diff)
tipc: move link supervision timer to node level
In our effort to move control of the links to the link aggregation layer, we move the perodic link supervision timer to struct tipc_node. The new timer is shared between all links belonging to the node, thus saving resources, while still kicking the FSM on both its pertaining links at each expiration. The current link timer and corresponding functions are removed. Reviewed-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/node.c')
-rw-r--r--net/tipc/node.c66
1 files changed, 62 insertions, 4 deletions
diff --git a/net/tipc/node.c b/net/tipc/node.c
index b7a4457f653c..77effb233725 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -44,6 +44,7 @@
44static void node_lost_contact(struct tipc_node *n_ptr); 44static void node_lost_contact(struct tipc_node *n_ptr);
45static void node_established_contact(struct tipc_node *n_ptr); 45static void node_established_contact(struct tipc_node *n_ptr);
46static void tipc_node_delete(struct tipc_node *node); 46static void tipc_node_delete(struct tipc_node *node);
47static void tipc_node_timeout(unsigned long data);
47 48
48struct tipc_sock_conn { 49struct tipc_sock_conn {
49 u32 port; 50 u32 port;
@@ -145,11 +146,27 @@ struct tipc_node *tipc_node_create(struct net *net, u32 addr)
145 n_ptr->active_links[0] = INVALID_BEARER_ID; 146 n_ptr->active_links[0] = INVALID_BEARER_ID;
146 n_ptr->active_links[1] = INVALID_BEARER_ID; 147 n_ptr->active_links[1] = INVALID_BEARER_ID;
147 tipc_node_get(n_ptr); 148 tipc_node_get(n_ptr);
149 setup_timer(&n_ptr->timer, tipc_node_timeout, (unsigned long)n_ptr);
150 n_ptr->keepalive_intv = U32_MAX;
148exit: 151exit:
149 spin_unlock_bh(&tn->node_list_lock); 152 spin_unlock_bh(&tn->node_list_lock);
150 return n_ptr; 153 return n_ptr;
151} 154}
152 155
156static void tipc_node_calculate_timer(struct tipc_node *n, struct tipc_link *l)
157{
158 unsigned long tol = l->tolerance;
159 unsigned long intv = ((tol / 4) > 500) ? 500 : tol / 4;
160 unsigned long keepalive_intv = msecs_to_jiffies(intv);
161
162 /* Link with lowest tolerance determines timer interval */
163 if (keepalive_intv < n->keepalive_intv)
164 n->keepalive_intv = keepalive_intv;
165
166 /* Ensure link's abort limit corresponds to current interval */
167 l->abort_limit = l->tolerance / jiffies_to_msecs(n->keepalive_intv);
168}
169
153static void tipc_node_delete(struct tipc_node *node) 170static void tipc_node_delete(struct tipc_node *node)
154{ 171{
155 list_del_rcu(&node->list); 172 list_del_rcu(&node->list);
@@ -163,8 +180,11 @@ void tipc_node_stop(struct net *net)
163 struct tipc_node *node, *t_node; 180 struct tipc_node *node, *t_node;
164 181
165 spin_lock_bh(&tn->node_list_lock); 182 spin_lock_bh(&tn->node_list_lock);
166 list_for_each_entry_safe(node, t_node, &tn->node_list, list) 183 list_for_each_entry_safe(node, t_node, &tn->node_list, list) {
184 if (del_timer(&node->timer))
185 tipc_node_put(node);
167 tipc_node_put(node); 186 tipc_node_put(node);
187 }
168 spin_unlock_bh(&tn->node_list_lock); 188 spin_unlock_bh(&tn->node_list_lock);
169} 189}
170 190
@@ -222,6 +242,38 @@ void tipc_node_remove_conn(struct net *net, u32 dnode, u32 port)
222 tipc_node_put(node); 242 tipc_node_put(node);
223} 243}
224 244
245/* tipc_node_timeout - handle expiration of node timer
246 */
247static void tipc_node_timeout(unsigned long data)
248{
249 struct tipc_node *n = (struct tipc_node *)data;
250 struct sk_buff_head xmitq;
251 struct tipc_link *l;
252 struct tipc_media_addr *maddr;
253 int bearer_id;
254 int rc = 0;
255
256 __skb_queue_head_init(&xmitq);
257
258 for (bearer_id = 0; bearer_id < MAX_BEARERS; bearer_id++) {
259 tipc_node_lock(n);
260 l = n->links[bearer_id].link;
261 if (l) {
262 /* Link tolerance may change asynchronously: */
263 tipc_node_calculate_timer(n, l);
264 rc = tipc_link_timeout(l, &xmitq);
265 if (rc & TIPC_LINK_DOWN_EVT)
266 tipc_link_reset(l);
267 }
268 tipc_node_unlock(n);
269 maddr = &n->links[bearer_id].maddr;
270 tipc_bearer_xmit(n->net, bearer_id, &xmitq, maddr);
271 }
272 if (!mod_timer(&n->timer, jiffies + n->keepalive_intv))
273 tipc_node_get(n);
274 tipc_node_put(n);
275}
276
225/** 277/**
226 * tipc_node_link_up - handle addition of link 278 * tipc_node_link_up - handle addition of link
227 * 279 *
@@ -335,10 +387,16 @@ bool tipc_node_update_dest(struct tipc_node *n, struct tipc_bearer *b,
335 struct tipc_media_addr *curr = &n->links[b->identity].maddr; 387 struct tipc_media_addr *curr = &n->links[b->identity].maddr;
336 struct sk_buff_head *inputq = &n->links[b->identity].inputq; 388 struct sk_buff_head *inputq = &n->links[b->identity].inputq;
337 389
338 if (!l) 390 if (!l) {
339 l = tipc_link_create(n, b, maddr, inputq, &n->bclink.namedq); 391 l = tipc_link_create(n, b, maddr, inputq, &n->bclink.namedq);
340 if (!l) 392 if (!l)
341 return false; 393 return false;
394 tipc_node_calculate_timer(n, l);
395 if (n->link_cnt == 1) {
396 if (!mod_timer(&n->timer, jiffies + n->keepalive_intv))
397 tipc_node_get(n);
398 }
399 }
342 memcpy(&l->media_addr, maddr, sizeof(*maddr)); 400 memcpy(&l->media_addr, maddr, sizeof(*maddr));
343 memcpy(curr, maddr, sizeof(*maddr)); 401 memcpy(curr, maddr, sizeof(*maddr));
344 tipc_link_reset(l); 402 tipc_link_reset(l);