]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/sched/sch_generic.c
[S390] Cleanup in signal handling code.
[linux-2.6-omap-h63xx.git] / net / sched / sch_generic.c
index d7aca8ef524ab8f9ea9d01b986d0ea7a88c72c3a..6f91518997951cbd13056373f36a98c0f87136b2 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;
        }
@@ -181,9 +184,13 @@ requeue:
 
 void __qdisc_run(struct net_device *dev)
 {
+       if (unlikely(dev->qdisc == &noop_qdisc))
+               goto out;
+
        while (qdisc_restart(dev) < 0 && !netif_queue_stopped(dev))
                /* NOTHING */;
 
+out:
        clear_bit(__LINK_STATE_QDISC_RUNNING, &dev->state);
 }
 
@@ -231,9 +238,7 @@ void __netdev_watchdog_up(struct net_device *dev)
 
 static void dev_watchdog_up(struct net_device *dev)
 {
-       netif_tx_lock_bh(dev);
        __netdev_watchdog_up(dev);
-       netif_tx_unlock_bh(dev);
 }
 
 static void dev_watchdog_down(struct net_device *dev)
@@ -425,10 +430,9 @@ struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops)
        size = QDISC_ALIGN(sizeof(*sch));
        size += ops->priv_size + (QDISC_ALIGNTO - 1);
 
-       p = kmalloc(size, GFP_KERNEL);
+       p = kzalloc(size, GFP_KERNEL);
        if (!p)
                goto errout;
-       memset(p, 0, size);
        sch = (struct Qdisc *) QDISC_ALIGN((unsigned long) p);
        sch->padded = (char *) sch - (char *) p;
 
@@ -583,10 +587,17 @@ void dev_deactivate(struct net_device *dev)
 
        dev_watchdog_down(dev);
 
-       while (test_bit(__LINK_STATE_SCHED, &dev->state))
+       /* Wait for outstanding dev_queue_xmit calls. */
+       synchronize_rcu();
+
+       /* Wait for outstanding qdisc_run calls. */
+       while (test_bit(__LINK_STATE_QDISC_RUNNING, &dev->state))
                yield();
 
-       spin_unlock_wait(&dev->_xmit_lock);
+       if (dev->gso_skb) {
+               kfree_skb(dev->gso_skb);
+               dev->gso_skb = NULL;
+       }
 }
 
 void dev_init_scheduler(struct net_device *dev)