diff options
author | Ying Xue <ying.xue@windriver.com> | 2014-11-25 22:41:53 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-11-26 12:30:17 -0500 |
commit | bc6fecd4098df2d21b056486e5b418c84be95032 (patch) | |
tree | 4b37da9bbd5fda66bba92558de5e6c9dfe97b7f6 /net/tipc/link.c | |
parent | 58dc55f25631178ee74cd27185956a8f7dcb3e32 (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.c | 74 |
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 | */ |
399 | void tipc_link_purge_queues(struct tipc_link *l_ptr) | 400 | void 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, | |||
974 | static struct sk_buff *link_insert_deferred_queue(struct tipc_link *l_ptr, | 972 | static 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 | */ |
1276 | u32 tipc_link_defer_pkt(struct sk_buff **head, struct sk_buff **tail, | 1278 | u32 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); |