]> err.no Git - linux-2.6/blobdiff - net/sched/sch_generic.c
Merge branch 'for-linus' of master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband
[linux-2.6] / net / sched / sch_generic.c
index 7aad0121232cb3aa555572524d7609f061718f65..d735f51686a19da66a22b0bf583e7cc81ec11c2f 100644 (file)
@@ -14,7 +14,6 @@
 #include <asm/uaccess.h>
 #include <asm/system.h>
 #include <linux/bitops.h>
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
@@ -96,8 +95,11 @@ static inline int qdisc_restart(struct net_device *dev)
        struct sk_buff *skb;
 
        /* Dequeue packet */
-       if ((skb = q->dequeue(q)) != NULL) {
+       if (((skb = dev->gso_skb)) || ((skb = q->dequeue(q)))) {
                unsigned nolock = (dev->features & NETIF_F_LLTX);
+
+               dev->gso_skb = NULL;
+
                /*
                 * When the driver has LLTX set it does its own locking
                 * in start_xmit. No need to add additional overhead by
@@ -134,10 +136,8 @@ static inline int qdisc_restart(struct net_device *dev)
 
                        if (!netif_queue_stopped(dev)) {
                                int ret;
-                               if (netdev_nit)
-                                       dev_queue_xmit_nit(skb, dev);
 
-                               ret = dev->hard_start_xmit(skb, dev);
+                               ret = dev_hard_start_xmit(skb, dev);
                                if (ret == NETDEV_TX_OK) { 
                                        if (!nolock) {
                                                netif_tx_unlock(dev);
@@ -171,7 +171,10 @@ static inline int qdisc_restart(struct net_device *dev)
                 */
 
 requeue:
-               q->ops->requeue(skb, q);
+               if (skb->next)
+                       dev->gso_skb = skb;
+               else
+                       q->ops->requeue(skb, q);
                netif_schedule(dev);
                return 1;
        }
@@ -593,6 +596,11 @@ void dev_deactivate(struct net_device *dev)
        /* Wait for outstanding qdisc_run calls. */
        while (test_bit(__LINK_STATE_QDISC_RUNNING, &dev->state))
                yield();
+
+       if (dev->gso_skb) {
+               kfree_skb(dev->gso_skb);
+               dev->gso_skb = NULL;
+       }
 }
 
 void dev_init_scheduler(struct net_device *dev)