summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2006-06-26 08:57:04 +0200
committerDavid S. Miller <davem@davemloft.net>2006-06-26 08:57:04 +0200
commitf54d9e8d7f7dd60f26157c12acda3fc94fcd9ab7 (patch)
tree4cd16db2905ccca54a2e79cc68669b62c024b433 /net
parent[NET]: Fix CHECKSUM_HW GSO problems. (diff)
downloadlinux-f54d9e8d7f7dd60f26157c12acda3fc94fcd9ab7.tar.xz
linux-f54d9e8d7f7dd60f26157c12acda3fc94fcd9ab7.zip
[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.c3
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;