diff options
author | Michael Chan <mchan@broadcom.com> | 2006-06-25 23:57:04 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2006-06-25 23:57:04 -0700 |
commit | f54d9e8d7f7dd60f26157c12acda3fc94fcd9ab7 (patch) | |
tree | 4cd16db2905ccca54a2e79cc68669b62c024b433 /net | |
parent | 0718bcc09b3597c51e87f265c72135a4928d3c0b (diff) | |
download | linux-f54d9e8d7f7dd60f26157c12acda3fc94fcd9ab7.tar.bz2 |
[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) nskb->next = NULL; rc = dev->hard_start_xmit(nskb, dev); if (unlikely(rc)) { + nskb->next = skb->next; skb->next = nskb; return rc; } + if (unlikely(netif_queue_stopped(dev) && skb->next)) + return NETDEV_TX_BUSY; } while (skb->next); skb->destructor = DEV_GSO_CB(skb)->destructor; |