Commit 8a1577c96f122308ac9b5f195f9f9a7dd74ac541

Authored by Jon Paul Maloy
Committed by David S. Miller
1 parent 333ef69ed2

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>

Showing 4 changed files with 68 additions and 80 deletions Side-by-side Diff

... ... @@ -127,7 +127,6 @@
127 127 struct sk_buff *skb);
128 128 static void tipc_link_proto_rcv(struct tipc_link *link,
129 129 struct sk_buff *skb);
130   -static void link_set_supervision_props(struct tipc_link *l_ptr, u32 tol);
131 130 static void link_state_event(struct tipc_link *l_ptr, u32 event);
132 131 static void tipc_link_build_proto_msg(struct tipc_link *l, int mtyp, bool probe,
133 132 u16 rcvgap, int tolerance, int priority,
... ... @@ -139,7 +138,6 @@
139 138 static void tipc_link_input(struct tipc_link *l, struct sk_buff *skb);
140 139 static bool tipc_data_input(struct tipc_link *l, struct sk_buff *skb);
141 140 static bool tipc_link_failover_rcv(struct tipc_link *l, struct sk_buff **skb);
142   -static void link_set_timer(struct tipc_link *link, unsigned long time);
143 141 static void link_activate(struct tipc_link *link);
144 142  
145 143 /*
... ... @@ -150,21 +148,6 @@
150 148 return (i + 3) & ~3u;
151 149 }
152 150  
153   -static void tipc_link_release(struct kref *kref)
154   -{
155   - kfree(container_of(kref, struct tipc_link, ref));
156   -}
157   -
158   -static void tipc_link_get(struct tipc_link *l_ptr)
159   -{
160   - kref_get(&l_ptr->ref);
161   -}
162   -
163   -static void tipc_link_put(struct tipc_link *l_ptr)
164   -{
165   - kref_put(&l_ptr->ref, tipc_link_release);
166   -}
167   -
168 151 static struct tipc_link *tipc_parallel_link(struct tipc_link *l)
169 152 {
170 153 struct tipc_node *n = l->owner;
... ... @@ -192,40 +175,6 @@
192 175 }
193 176  
194 177 /**
195   - * link_timeout - handle expiration of link timer
196   - */
197   -static void link_timeout(unsigned long data)
198   -{
199   - struct tipc_link *l = (struct tipc_link *)data;
200   - struct sk_buff_head xmitq;
201   - struct sk_buff *skb;
202   - int rc;
203   -
204   - __skb_queue_head_init(&xmitq);
205   -
206   - tipc_node_lock(l->owner);
207   -
208   - rc = tipc_link_timeout(l, &xmitq);
209   -
210   - if (rc & TIPC_LINK_DOWN_EVT)
211   - tipc_link_reset(l);
212   -
213   - skb = __skb_dequeue(&xmitq);
214   - if (skb)
215   - tipc_bearer_send(l->owner->net, l->bearer_id,
216   - skb, &l->media_addr);
217   - link_set_timer(l, l->keepalive_intv);
218   - tipc_node_unlock(l->owner);
219   - tipc_link_put(l);
220   -}
221   -
222   -static void link_set_timer(struct tipc_link *link, unsigned long time)
223   -{
224   - if (!mod_timer(&link->timer, jiffies + time))
225   - tipc_link_get(link);
226   -}
227   -
228   -/**
229 178 * tipc_link_create - create a new link
230 179 * @n_ptr: pointer to associated node
231 180 * @b_ptr: pointer to associated bearer
... ... @@ -265,7 +214,6 @@
265 214 pr_warn("Link creation failed, no memory\n");
266 215 return NULL;
267 216 }
268   - kref_init(&l_ptr->ref);
269 217 l_ptr->addr = peer;
270 218 if_name = strchr(b_ptr->name, ':') + 1;
271 219 sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:unknown",
... ... @@ -278,7 +226,7 @@
278 226 l_ptr->owner = n_ptr;
279 227 l_ptr->peer_session = WILDCARD_SESSION;
280 228 l_ptr->bearer_id = b_ptr->identity;
281   - link_set_supervision_props(l_ptr, b_ptr->tolerance);
  229 + l_ptr->tolerance = b_ptr->tolerance;
282 230 l_ptr->state = TIPC_LINK_RESETTING;
283 231  
284 232 l_ptr->pmsg = (struct tipc_msg *)&l_ptr->proto_msg;
... ... @@ -304,8 +252,6 @@
304 252 skb_queue_head_init(l_ptr->inputq);
305 253 link_reset_statistics(l_ptr);
306 254 tipc_node_attach_link(n_ptr, l_ptr);
307   - setup_timer(&l_ptr->timer, link_timeout, (unsigned long)l_ptr);
308   - link_set_timer(l_ptr, l_ptr->keepalive_intv);
309 255 return l_ptr;
310 256 }
311 257  
312 258  
... ... @@ -316,12 +262,8 @@
316 262 void tipc_link_delete(struct tipc_link *l)
317 263 {
318 264 tipc_link_reset(l);
319   - if (del_timer(&l->timer))
320   - tipc_link_put(l);
321   - /* Delete link now, or when timer is finished: */
322 265 tipc_link_reset_fragments(l);
323 266 tipc_node_detach_link(l->owner, l);
324   - tipc_link_put(l);
325 267 }
326 268  
327 269 void tipc_link_delete_list(struct net *net, unsigned int bearer_id)
... ... @@ -1447,7 +1389,7 @@
1447 1389  
1448 1390 msg_tol = msg_link_tolerance(msg);
1449 1391 if (msg_tol > l_ptr->tolerance)
1450   - link_set_supervision_props(l_ptr, msg_tol);
  1392 + l_ptr->tolerance = msg_tol;
1451 1393  
1452 1394 if (msg_linkprio(msg) > l_ptr->priority)
1453 1395 l_ptr->priority = msg_linkprio(msg);
... ... @@ -1473,7 +1415,7 @@
1473 1415  
1474 1416 msg_tol = msg_link_tolerance(msg);
1475 1417 if (msg_tol)
1476   - link_set_supervision_props(l_ptr, msg_tol);
  1418 + l_ptr->tolerance = msg_tol;
1477 1419  
1478 1420 if (msg_linkprio(msg) &&
1479 1421 (msg_linkprio(msg) != l_ptr->priority)) {
... ... @@ -1796,18 +1738,6 @@
1796 1738 return *skb;
1797 1739 }
1798 1740  
1799   -static void link_set_supervision_props(struct tipc_link *l_ptr, u32 tol)
1800   -{
1801   - unsigned long intv = ((tol / 4) > 500) ? 500 : tol / 4;
1802   -
1803   - if ((tol < TIPC_MIN_LINK_TOL) || (tol > TIPC_MAX_LINK_TOL))
1804   - return;
1805   -
1806   - l_ptr->tolerance = tol;
1807   - l_ptr->keepalive_intv = msecs_to_jiffies(intv);
1808   - l_ptr->abort_limit = tol / (jiffies_to_msecs(l_ptr->keepalive_intv));
1809   -}
1810   -
1811 1741 void tipc_link_set_queue_limits(struct tipc_link *l, u32 win)
1812 1742 {
1813 1743 int max_bulk = TIPC_MAX_PUBLICATIONS / (l->mtu / ITEM_SIZE);
... ... @@ -1984,7 +1914,7 @@
1984 1914 u32 tol;
1985 1915  
1986 1916 tol = nla_get_u32(props[TIPC_NLA_PROP_TOL]);
1987   - link_set_supervision_props(link, tol);
  1917 + link->tolerance = tol;
1988 1918 tipc_link_proto_xmit(link, STATE_MSG, 0, 0, tol, 0);
1989 1919 }
1990 1920 if (props[TIPC_NLA_PROP_PRIO]) {
... ... @@ -146,9 +146,7 @@
146 146 u32 addr;
147 147 char name[TIPC_MAX_LINK_NAME];
148 148 struct tipc_media_addr media_addr;
149   - struct timer_list timer;
150 149 struct tipc_node *owner;
151   - struct kref ref;
152 150  
153 151 /* Management and link supervision data */
154 152 u32 peer_session;
... ... @@ -44,6 +44,7 @@
44 44 static void node_lost_contact(struct tipc_node *n_ptr);
45 45 static void node_established_contact(struct tipc_node *n_ptr);
46 46 static void tipc_node_delete(struct tipc_node *node);
  47 +static void tipc_node_timeout(unsigned long data);
47 48  
48 49 struct tipc_sock_conn {
49 50 u32 port;
50 51  
... ... @@ -145,11 +146,27 @@
145 146 n_ptr->active_links[0] = INVALID_BEARER_ID;
146 147 n_ptr->active_links[1] = INVALID_BEARER_ID;
147 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;
148 151 exit:
149 152 spin_unlock_bh(&tn->node_list_lock);
150 153 return n_ptr;
151 154 }
152 155  
  156 +static 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 +
153 170 static void tipc_node_delete(struct tipc_node *node)
154 171 {
155 172 list_del_rcu(&node->list);
156 173  
... ... @@ -163,8 +180,11 @@
163 180 struct tipc_node *node, *t_node;
164 181  
165 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 186 tipc_node_put(node);
  187 + }
168 188 spin_unlock_bh(&tn->node_list_lock);
169 189 }
170 190  
... ... @@ -222,6 +242,38 @@
222 242 tipc_node_put(node);
223 243 }
224 244  
  245 +/* tipc_node_timeout - handle expiration of node timer
  246 + */
  247 +static 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 278 * tipc_node_link_up - handle addition of link
227 279 *
228 280  
... ... @@ -335,10 +387,16 @@
335 387 struct tipc_media_addr *curr = &n->links[b->identity].maddr;
336 388 struct sk_buff_head *inputq = &n->links[b->identity].inputq;
337 389  
338   - if (!l)
  390 + if (!l) {
339 391 l = tipc_link_create(n, b, maddr, inputq, &n->bclink.namedq);
340   - if (!l)
341   - return false;
  392 + if (!l)
  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 400 memcpy(&l->media_addr, maddr, sizeof(*maddr));
343 401 memcpy(curr, maddr, sizeof(*maddr));
344 402 tipc_link_reset(l);
... ... @@ -140,6 +140,8 @@
140 140 u32 link_id;
141 141 struct list_head publ_list;
142 142 struct list_head conn_sks;
  143 + unsigned long keepalive_intv;
  144 + struct timer_list timer;
143 145 struct rcu_head rcu;
144 146 };
145 147