aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/link.c
diff options
context:
space:
mode:
authorYing Xue <ying.xue@windriver.com>2014-11-25 22:41:53 -0500
committerDavid S. Miller <davem@davemloft.net>2014-11-26 12:30:17 -0500
commitbc6fecd4098df2d21b056486e5b418c84be95032 (patch)
tree4b37da9bbd5fda66bba92558de5e6c9dfe97b7f6 /net/tipc/link.c
parent58dc55f25631178ee74cd27185956a8f7dcb3e32 (diff)
tipc: use generic SKB list APIs to manage deferred queue of link
Use standard SKB list APIs associated with struct sk_buff_head to manage link's deferred queue, simplifying relevant code. Signed-off-by: Ying Xue <ying.xue@windriver.com> Reviewed-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/link.c')
-rw-r--r--net/tipc/link.c74
1 files changed, 32 insertions, 42 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 9e94bf935e48..d9c2310e417d 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -292,6 +292,7 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
292 292
293 l_ptr->next_out_no = 1; 293 l_ptr->next_out_no = 1;
294 __skb_queue_head_init(&l_ptr->outqueue); 294 __skb_queue_head_init(&l_ptr->outqueue);
295 __skb_queue_head_init(&l_ptr->deferred_queue);
295 __skb_queue_head_init(&l_ptr->waiting_sks); 296 __skb_queue_head_init(&l_ptr->waiting_sks);
296 297
297 link_reset_statistics(l_ptr); 298 link_reset_statistics(l_ptr);
@@ -398,7 +399,7 @@ void tipc_link_reset_fragments(struct tipc_link *l_ptr)
398 */ 399 */
399void tipc_link_purge_queues(struct tipc_link *l_ptr) 400void tipc_link_purge_queues(struct tipc_link *l_ptr)
400{ 401{
401 kfree_skb_list(l_ptr->oldest_deferred_in); 402 __skb_queue_purge(&l_ptr->deferred_queue);
402 __skb_queue_purge(&l_ptr->outqueue); 403 __skb_queue_purge(&l_ptr->outqueue);
403 tipc_link_reset_fragments(l_ptr); 404 tipc_link_reset_fragments(l_ptr);
404} 405}
@@ -433,7 +434,7 @@ void tipc_link_reset(struct tipc_link *l_ptr)
433 434
434 /* Clean up all queues: */ 435 /* Clean up all queues: */
435 __skb_queue_purge(&l_ptr->outqueue); 436 __skb_queue_purge(&l_ptr->outqueue);
436 kfree_skb_list(l_ptr->oldest_deferred_in); 437 __skb_queue_purge(&l_ptr->deferred_queue);
437 if (!skb_queue_empty(&l_ptr->waiting_sks)) { 438 if (!skb_queue_empty(&l_ptr->waiting_sks)) {
438 skb_queue_splice_init(&l_ptr->waiting_sks, &owner->waiting_sks); 439 skb_queue_splice_init(&l_ptr->waiting_sks, &owner->waiting_sks);
439 owner->action_flags |= TIPC_WAKEUP_USERS; 440 owner->action_flags |= TIPC_WAKEUP_USERS;
@@ -442,9 +443,6 @@ void tipc_link_reset(struct tipc_link *l_ptr)
442 l_ptr->unacked_window = 0; 443 l_ptr->unacked_window = 0;
443 l_ptr->checkpoint = 1; 444 l_ptr->checkpoint = 1;
444 l_ptr->next_out_no = 1; 445 l_ptr->next_out_no = 1;
445 l_ptr->deferred_inqueue_sz = 0;
446 l_ptr->oldest_deferred_in = NULL;
447 l_ptr->newest_deferred_in = NULL;
448 l_ptr->fsm_msg_cnt = 0; 446 l_ptr->fsm_msg_cnt = 0;
449 l_ptr->stale_count = 0; 447 l_ptr->stale_count = 0;
450 link_reset_statistics(l_ptr); 448 link_reset_statistics(l_ptr);
@@ -974,19 +972,23 @@ void tipc_link_retransmit(struct tipc_link *l_ptr, struct sk_buff *skb,
974static struct sk_buff *link_insert_deferred_queue(struct tipc_link *l_ptr, 972static struct sk_buff *link_insert_deferred_queue(struct tipc_link *l_ptr,
975 struct sk_buff *buf) 973 struct sk_buff *buf)
976{ 974{
975 struct sk_buff_head head;
976 struct sk_buff *skb = NULL;
977 u32 seq_no; 977 u32 seq_no;
978 978
979 if (l_ptr->oldest_deferred_in == NULL) 979 if (skb_queue_empty(&l_ptr->deferred_queue))
980 return buf; 980 return buf;
981 981
982 seq_no = buf_seqno(l_ptr->oldest_deferred_in); 982 seq_no = buf_seqno(skb_peek(&l_ptr->deferred_queue));
983 if (seq_no == mod(l_ptr->next_in_no)) { 983 if (seq_no == mod(l_ptr->next_in_no)) {
984 l_ptr->newest_deferred_in->next = buf; 984 __skb_queue_head_init(&head);
985 buf = l_ptr->oldest_deferred_in; 985 skb_queue_splice_tail_init(&l_ptr->deferred_queue, &head);
986 l_ptr->oldest_deferred_in = NULL; 986 skb = head.next;
987 l_ptr->deferred_inqueue_sz = 0; 987 skb->prev = NULL;
988 head.prev->next = buf;
989 head.prev->prev = NULL;
988 } 990 }
989 return buf; 991 return skb;
990} 992}
991 993
992/** 994/**
@@ -1170,7 +1172,7 @@ void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr)
1170 continue; 1172 continue;
1171 } 1173 }
1172 l_ptr->next_in_no++; 1174 l_ptr->next_in_no++;
1173 if (unlikely(l_ptr->oldest_deferred_in)) 1175 if (unlikely(!skb_queue_empty(&l_ptr->deferred_queue)))
1174 head = link_insert_deferred_queue(l_ptr, head); 1176 head = link_insert_deferred_queue(l_ptr, head);
1175 1177
1176 if (unlikely(++l_ptr->unacked_window >= TIPC_MIN_LINK_WIN)) { 1178 if (unlikely(++l_ptr->unacked_window >= TIPC_MIN_LINK_WIN)) {
@@ -1273,48 +1275,37 @@ static int tipc_link_input(struct tipc_link *l, struct sk_buff *buf)
1273 * 1275 *
1274 * Returns increase in queue length (i.e. 0 or 1) 1276 * Returns increase in queue length (i.e. 0 or 1)
1275 */ 1277 */
1276u32 tipc_link_defer_pkt(struct sk_buff **head, struct sk_buff **tail, 1278u32 tipc_link_defer_pkt(struct sk_buff_head *list, struct sk_buff *skb)
1277 struct sk_buff *buf)
1278{ 1279{
1279 struct sk_buff *queue_buf; 1280 struct sk_buff *skb1;
1280 struct sk_buff **prev; 1281 u32 seq_no = buf_seqno(skb);
1281 u32 seq_no = buf_seqno(buf);
1282
1283 buf->next = NULL;
1284 1282
1285 /* Empty queue ? */ 1283 /* Empty queue ? */
1286 if (*head == NULL) { 1284 if (skb_queue_empty(list)) {
1287 *head = *tail = buf; 1285 __skb_queue_tail(list, skb);
1288 return 1; 1286 return 1;
1289 } 1287 }
1290 1288
1291 /* Last ? */ 1289 /* Last ? */
1292 if (less(buf_seqno(*tail), seq_no)) { 1290 if (less(buf_seqno(skb_peek_tail(list)), seq_no)) {
1293 (*tail)->next = buf; 1291 __skb_queue_tail(list, skb);
1294 *tail = buf;
1295 return 1; 1292 return 1;
1296 } 1293 }
1297 1294
1298 /* Locate insertion point in queue, then insert; discard if duplicate */ 1295 /* Locate insertion point in queue, then insert; discard if duplicate */
1299 prev = head; 1296 skb_queue_walk(list, skb1) {
1300 queue_buf = *head; 1297 u32 curr_seqno = buf_seqno(skb1);
1301 for (;;) {
1302 u32 curr_seqno = buf_seqno(queue_buf);
1303 1298
1304 if (seq_no == curr_seqno) { 1299 if (seq_no == curr_seqno) {
1305 kfree_skb(buf); 1300 kfree_skb(skb);
1306 return 0; 1301 return 0;
1307 } 1302 }
1308 1303
1309 if (less(seq_no, curr_seqno)) 1304 if (less(seq_no, curr_seqno))
1310 break; 1305 break;
1311
1312 prev = &queue_buf->next;
1313 queue_buf = queue_buf->next;
1314 } 1306 }
1315 1307
1316 buf->next = queue_buf; 1308 __skb_queue_before(list, skb1, skb);
1317 *prev = buf;
1318 return 1; 1309 return 1;
1319} 1310}
1320 1311
@@ -1344,15 +1335,14 @@ static void link_handle_out_of_seq_msg(struct tipc_link *l_ptr,
1344 return; 1335 return;
1345 } 1336 }
1346 1337
1347 if (tipc_link_defer_pkt(&l_ptr->oldest_deferred_in, 1338 if (tipc_link_defer_pkt(&l_ptr->deferred_queue, buf)) {
1348 &l_ptr->newest_deferred_in, buf)) {
1349 l_ptr->deferred_inqueue_sz++;
1350 l_ptr->stats.deferred_recv++; 1339 l_ptr->stats.deferred_recv++;
1351 TIPC_SKB_CB(buf)->deferred = true; 1340 TIPC_SKB_CB(buf)->deferred = true;
1352 if ((l_ptr->deferred_inqueue_sz % 16) == 1) 1341 if ((skb_queue_len(&l_ptr->deferred_queue) % 16) == 1)
1353 tipc_link_proto_xmit(l_ptr, STATE_MSG, 0, 0, 0, 0, 0); 1342 tipc_link_proto_xmit(l_ptr, STATE_MSG, 0, 0, 0, 0, 0);
1354 } else 1343 } else {
1355 l_ptr->stats.duplicates++; 1344 l_ptr->stats.duplicates++;
1345 }
1356} 1346}
1357 1347
1358/* 1348/*
@@ -1388,8 +1378,8 @@ void tipc_link_proto_xmit(struct tipc_link *l_ptr, u32 msg_typ, int probe_msg,
1388 if (l_ptr->next_out) 1378 if (l_ptr->next_out)
1389 next_sent = buf_seqno(l_ptr->next_out); 1379 next_sent = buf_seqno(l_ptr->next_out);
1390 msg_set_next_sent(msg, next_sent); 1380 msg_set_next_sent(msg, next_sent);
1391 if (l_ptr->oldest_deferred_in) { 1381 if (!skb_queue_empty(&l_ptr->deferred_queue)) {
1392 u32 rec = buf_seqno(l_ptr->oldest_deferred_in); 1382 u32 rec = buf_seqno(skb_peek(&l_ptr->deferred_queue));
1393 gap = mod(rec - mod(l_ptr->next_in_no)); 1383 gap = mod(rec - mod(l_ptr->next_in_no));
1394 } 1384 }
1395 msg_set_seq_gap(msg, gap); 1385 msg_set_seq_gap(msg, gap);