summaryrefslogtreecommitdiffstats
path: root/net/tipc/link.c
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2015-07-16 16:54:23 -0400
committerDavid S. Miller <davem@davemloft.net>2015-07-20 23:41:15 -0400
commit22d85c79428b8ca9a01623aa3e3a1fe29a30a119 (patch)
treebc72ee5256301d591616db2270c45929be2d58d6 /net/tipc/link.c
parent36e78a463b26c9b8017a2e11dcd6c4b8e34b4161 (diff)
tipc: change sk_buffer handling in tipc_link_xmit()
When the function tipc_link_xmit() is given a buffer list for transmission, it currently consumes the list both when transmission is successful and when it fails, except for the special case when it encounters link congestion. This behavior is inconsistent, and needs to be corrected if we want to avoid problems in later commits in this series. In this commit, we change this to let the function consume the list only when transmission is successful, and leave the list with the sender in all other cases. We also modifiy the socket code so that it adapts to this change, i.e., purges the list when a non-congestion error code is returned. 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/link.c')
-rw-r--r--net/tipc/link.c23
1 files changed, 9 insertions, 14 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c
index f8e0e2ceceb4..ea32679b6737 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -340,7 +340,7 @@ void tipc_link_delete_list(struct net *net, unsigned int bearer_id)
340 * @link: congested link 340 * @link: congested link
341 * @list: message that was attempted sent 341 * @list: message that was attempted sent
342 * Create pseudo msg to send back to user when congestion abates 342 * Create pseudo msg to send back to user when congestion abates
343 * Only consumes message if there is an error 343 * Does not consume buffer list
344 */ 344 */
345static int link_schedule_user(struct tipc_link *link, struct sk_buff_head *list) 345static int link_schedule_user(struct tipc_link *link, struct sk_buff_head *list)
346{ 346{
@@ -354,7 +354,7 @@ static int link_schedule_user(struct tipc_link *link, struct sk_buff_head *list)
354 if (unlikely(imp > TIPC_CRITICAL_IMPORTANCE)) { 354 if (unlikely(imp > TIPC_CRITICAL_IMPORTANCE)) {
355 pr_warn("%s<%s>, send queue full", link_rst_msg, link->name); 355 pr_warn("%s<%s>, send queue full", link_rst_msg, link->name);
356 tipc_link_reset(link); 356 tipc_link_reset(link);
357 goto err; 357 return -ENOBUFS;
358 } 358 }
359 /* Non-blocking sender: */ 359 /* Non-blocking sender: */
360 if (TIPC_SKB_CB(skb_peek(list))->wakeup_pending) 360 if (TIPC_SKB_CB(skb_peek(list))->wakeup_pending)
@@ -364,15 +364,12 @@ static int link_schedule_user(struct tipc_link *link, struct sk_buff_head *list)
364 skb = tipc_msg_create(SOCK_WAKEUP, 0, INT_H_SIZE, 0, 364 skb = tipc_msg_create(SOCK_WAKEUP, 0, INT_H_SIZE, 0,
365 addr, addr, oport, 0, 0); 365 addr, addr, oport, 0, 0);
366 if (!skb) 366 if (!skb)
367 goto err; 367 return -ENOBUFS;
368 TIPC_SKB_CB(skb)->chain_sz = skb_queue_len(list); 368 TIPC_SKB_CB(skb)->chain_sz = skb_queue_len(list);
369 TIPC_SKB_CB(skb)->chain_imp = imp; 369 TIPC_SKB_CB(skb)->chain_imp = imp;
370 skb_queue_tail(&link->wakeupq, skb); 370 skb_queue_tail(&link->wakeupq, skb);
371 link->stats.link_congs++; 371 link->stats.link_congs++;
372 return -ELINKCONG; 372 return -ELINKCONG;
373err:
374 __skb_queue_purge(list);
375 return -ENOBUFS;
376} 373}
377 374
378/** 375/**
@@ -641,8 +638,7 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
641 * @link: link to use 638 * @link: link to use
642 * @list: chain of buffers containing message 639 * @list: chain of buffers containing message
643 * 640 *
644 * Consumes the buffer chain, except when returning -ELINKCONG, 641 * Consumes the buffer chain, except when returning an error code,
645 * since the caller then may want to make more send attempts.
646 * Returns 0 if success, or errno: -ELINKCONG, -EMSGSIZE or -ENOBUFS 642 * Returns 0 if success, or errno: -ELINKCONG, -EMSGSIZE or -ENOBUFS
647 * Messages at TIPC_SYSTEM_IMPORTANCE are always accepted 643 * Messages at TIPC_SYSTEM_IMPORTANCE are always accepted
648 */ 644 */
@@ -666,10 +662,9 @@ int __tipc_link_xmit(struct net *net, struct tipc_link *link,
666 if (unlikely(link->backlog[i].len >= link->backlog[i].limit)) 662 if (unlikely(link->backlog[i].len >= link->backlog[i].limit))
667 return link_schedule_user(link, list); 663 return link_schedule_user(link, list);
668 } 664 }
669 if (unlikely(msg_size(msg) > mtu)) { 665 if (unlikely(msg_size(msg) > mtu))
670 __skb_queue_purge(list);
671 return -EMSGSIZE; 666 return -EMSGSIZE;
672 } 667
673 /* Prepare each packet for sending, and add to relevant queue: */ 668 /* Prepare each packet for sending, and add to relevant queue: */
674 while (skb_queue_len(list)) { 669 while (skb_queue_len(list)) {
675 skb = skb_peek(list); 670 skb = skb_peek(list);
@@ -722,7 +717,7 @@ static int __tipc_link_xmit_skb(struct tipc_link *link, struct sk_buff *skb)
722 717
723/* tipc_link_xmit_skb(): send single buffer to destination 718/* tipc_link_xmit_skb(): send single buffer to destination
724 * Buffers sent via this functon are generally TIPC_SYSTEM_IMPORTANCE 719 * Buffers sent via this functon are generally TIPC_SYSTEM_IMPORTANCE
725 * messages, which will not be rejected 720 * messages, which will not cause link congestion
726 * The only exception is datagram messages rerouted after secondary 721 * The only exception is datagram messages rerouted after secondary
727 * lookup, which are rare and safe to dispose of anyway. 722 * lookup, which are rare and safe to dispose of anyway.
728 * TODO: Return real return value, and let callers use 723 * TODO: Return real return value, and let callers use
@@ -736,7 +731,7 @@ int tipc_link_xmit_skb(struct net *net, struct sk_buff *skb, u32 dnode,
736 731
737 skb2list(skb, &head); 732 skb2list(skb, &head);
738 rc = tipc_link_xmit(net, &head, dnode, selector); 733 rc = tipc_link_xmit(net, &head, dnode, selector);
739 if (rc == -ELINKCONG) 734 if (rc)
740 kfree_skb(skb); 735 kfree_skb(skb);
741 return 0; 736 return 0;
742} 737}
@@ -748,7 +743,7 @@ int tipc_link_xmit_skb(struct net *net, struct sk_buff *skb, u32 dnode,
748 * @dsz: amount of user data to be sent 743 * @dsz: amount of user data to be sent
749 * @dnode: address of destination node 744 * @dnode: address of destination node
750 * @selector: a number used for deterministic link selection 745 * @selector: a number used for deterministic link selection
751 * Consumes the buffer chain, except when returning -ELINKCONG 746 * Consumes the buffer chain, except when returning error
752 * Returns 0 if success, otherwise errno: -ELINKCONG,-EHOSTUNREACH,-EMSGSIZE 747 * Returns 0 if success, otherwise errno: -ELINKCONG,-EHOSTUNREACH,-EMSGSIZE
753 */ 748 */
754int tipc_link_xmit(struct net *net, struct sk_buff_head *list, u32 dnode, 749int tipc_link_xmit(struct net *net, struct sk_buff_head *list, u32 dnode,