Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[pandora-kernel.git] / net / sched / sch_generic.c
index c84b659..b4c6809 100644 (file)
@@ -251,9 +251,8 @@ static void dev_watchdog(unsigned long arg)
                        }
 
                        if (some_queue_timedout) {
-                               char drivername[64];
                                WARN_ONCE(1, KERN_INFO "NETDEV WATCHDOG: %s (%s): transmit queue %u timed out\n",
-                                      dev->name, netdev_drivername(dev, drivername, 64), i);
+                                      dev->name, netdev_drivername(dev), i);
                                dev->netdev_ops->ndo_tx_timeout(dev);
                        }
                        if (!mod_timer(&dev->watchdog_timer,
@@ -815,9 +814,17 @@ static bool some_qdisc_is_busy(struct net_device *dev)
        return false;
 }
 
+/**
+ *     dev_deactivate_many - deactivate transmissions on several devices
+ *     @head: list of devices to deactivate
+ *
+ *     This function returns only when all outstanding transmissions
+ *     have completed, unless all devices are in dismantle phase.
+ */
 void dev_deactivate_many(struct list_head *head)
 {
        struct net_device *dev;
+       bool sync_needed = false;
 
        list_for_each_entry(dev, head, unreg_list) {
                netdev_for_each_tx_queue(dev, dev_deactivate_queue,
@@ -827,10 +834,15 @@ void dev_deactivate_many(struct list_head *head)
                                             &noop_qdisc);
 
                dev_watchdog_down(dev);
+               sync_needed |= !dev->dismantle;
        }
 
-       /* Wait for outstanding qdisc-less dev_queue_xmit calls. */
-       synchronize_rcu();
+       /* Wait for outstanding qdisc-less dev_queue_xmit calls.
+        * This is avoided if all devices are in dismantle phase :
+        * Caller will call synchronize_net() for us
+        */
+       if (sync_needed)
+               synchronize_net();
 
        /* Wait for outstanding qdisc_run calls. */
        list_for_each_entry(dev, head, unreg_list)