diff options
author | Michael Chan <mchan@broadcom.com> | 2006-06-26 02:57:04 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2006-06-26 02:57:04 -0400 |
commit | f54d9e8d7f7dd60f26157c12acda3fc94fcd9ab7 (patch) | |
tree | 4cd16db2905ccca54a2e79cc68669b62c024b433 /net | |
parent | 0718bcc09b3597c51e87f265c72135a4928d3c0b (diff) |
[NET]: Fix GSO problems in dev_hard_start_xmit()
Fix 2 problems in dev_hard_start_xmit():
1. nskb->next needs to link back to skb->next if hard_start_xmit()
returns non-zero.
2. Since the total number of GSO fragments may exceed MAX_SKB_FRAGS + 1,
it needs to stop transmitting if the netif_queue is stopped.
Signed-off-by: Michael Chan <mchan@broadcom.com>
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/core/dev.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index ea2469398bd5..aa8454901719 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1325,9 +1325,12 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1325 | nskb->next = NULL; | 1325 | nskb->next = NULL; |
1326 | rc = dev->hard_start_xmit(nskb, dev); | 1326 | rc = dev->hard_start_xmit(nskb, dev); |
1327 | if (unlikely(rc)) { | 1327 | if (unlikely(rc)) { |
1328 | nskb->next = skb->next; | ||
1328 | skb->next = nskb; | 1329 | skb->next = nskb; |
1329 | return rc; | 1330 | return rc; |
1330 | } | 1331 | } |
1332 | if (unlikely(netif_queue_stopped(dev) && skb->next)) | ||
1333 | return NETDEV_TX_BUSY; | ||
1331 | } while (skb->next); | 1334 | } while (skb->next); |
1332 | 1335 | ||
1333 | skb->destructor = DEV_GSO_CB(skb)->destructor; | 1336 | skb->destructor = DEV_GSO_CB(skb)->destructor; |