]> err.no Git - linux-2.6/blobdiff - net/sched/sch_generic.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[linux-2.6] / net / sched / sch_generic.c
index cb625b4d6da5e89b5a82ffd4685fa78e64e642b3..9c9cd4d94890d1b1c5fb7d582af730f37248cfc0 100644 (file)
@@ -135,7 +135,8 @@ static inline int qdisc_restart(struct Qdisc *q)
        txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb));
 
        HARD_TX_LOCK(dev, txq, smp_processor_id());
-       if (!netif_subqueue_stopped(dev, skb))
+       if (!netif_tx_queue_stopped(txq) &&
+           !netif_tx_queue_frozen(txq))
                ret = dev_hard_start_xmit(skb, dev, txq);
        HARD_TX_UNLOCK(dev, txq);
 
@@ -162,7 +163,8 @@ static inline int qdisc_restart(struct Qdisc *q)
                break;
        }
 
-       if (ret && netif_tx_queue_stopped(txq))
+       if (ret && (netif_tx_queue_stopped(txq) ||
+                   netif_tx_queue_frozen(txq)))
                ret = 0;
 
        return ret;
@@ -212,9 +214,9 @@ static void dev_watchdog(unsigned long arg)
                        if (some_queue_stopped &&
                            time_after(jiffies, (dev->trans_start +
                                                 dev->watchdog_timeo))) {
-                               printk(KERN_INFO "NETDEV WATCHDOG: %s: "
-                                      "transmit timed out\n",
-                                      dev->name);
+                               char drivername[64];
+                               printk(KERN_INFO "NETDEV WATCHDOG: %s (%s): transmit timed out\n",
+                                      dev->name, netdev_drivername(dev, drivername, 64));
                                dev->tx_timeout(dev);
                                WARN_ON_ONCE(1);
                        }
@@ -596,7 +598,7 @@ static void transition_one_qdisc(struct net_device *dev,
        int *need_watchdog_p = _need_watchdog;
 
        rcu_assign_pointer(dev_queue->qdisc, new_qdisc);
-       if (new_qdisc != &noqueue_qdisc)
+       if (need_watchdog_p && new_qdisc != &noqueue_qdisc)
                *need_watchdog_p = 1;
 }
 
@@ -619,6 +621,7 @@ void dev_activate(struct net_device *dev)
 
        need_watchdog = 0;
        netdev_for_each_tx_queue(dev, transition_one_qdisc, &need_watchdog);
+       transition_one_qdisc(dev, &dev->rx_queue, NULL);
 
        if (need_watchdog) {
                dev->trans_start = jiffies;
@@ -677,6 +680,7 @@ void dev_deactivate(struct net_device *dev)
        bool running;
 
        netdev_for_each_tx_queue(dev, dev_deactivate_queue, &noop_qdisc);
+       dev_deactivate_queue(dev, &dev->rx_queue, &noop_qdisc);
 
        dev_watchdog_down(dev);
 
@@ -718,7 +722,7 @@ static void dev_init_scheduler_queue(struct net_device *dev,
 void dev_init_scheduler(struct net_device *dev)
 {
        netdev_for_each_tx_queue(dev, dev_init_scheduler_queue, &noop_qdisc);
-       dev_init_scheduler_queue(dev, &dev->rx_queue, NULL);
+       dev_init_scheduler_queue(dev, &dev->rx_queue, &noop_qdisc);
 
        setup_timer(&dev->watchdog_timer, dev_watchdog, (unsigned long)dev);
 }
@@ -736,15 +740,15 @@ static void shutdown_scheduler_queue(struct net_device *dev,
                dev_queue->qdisc = qdisc_default;
                dev_queue->qdisc_sleeping = qdisc_default;
 
-               spin_lock(root_lock);
+               spin_lock_bh(root_lock);
                qdisc_destroy(qdisc);
-               spin_unlock(root_lock);
+               spin_unlock_bh(root_lock);
        }
 }
 
 void dev_shutdown(struct net_device *dev)
 {
        netdev_for_each_tx_queue(dev, shutdown_scheduler_queue, &noop_qdisc);
-       shutdown_scheduler_queue(dev, &dev->rx_queue, NULL);
-       BUG_TRAP(!timer_pending(&dev->watchdog_timer));
+       shutdown_scheduler_queue(dev, &dev->rx_queue, &noop_qdisc);
+       WARN_ON(timer_pending(&dev->watchdog_timer));
 }