aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched')
-rw-r--r--net/sched/sch_generic.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index d7aca8ef524a..7aad0121232c 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -181,9 +181,13 @@ requeue:
181 181
182void __qdisc_run(struct net_device *dev) 182void __qdisc_run(struct net_device *dev)
183{ 183{
184 if (unlikely(dev->qdisc == &noop_qdisc))
185 goto out;
186
184 while (qdisc_restart(dev) < 0 && !netif_queue_stopped(dev)) 187 while (qdisc_restart(dev) < 0 && !netif_queue_stopped(dev))
185 /* NOTHING */; 188 /* NOTHING */;
186 189
190out:
187 clear_bit(__LINK_STATE_QDISC_RUNNING, &dev->state); 191 clear_bit(__LINK_STATE_QDISC_RUNNING, &dev->state);
188} 192}
189 193
@@ -583,10 +587,12 @@ void dev_deactivate(struct net_device *dev)
583 587
584 dev_watchdog_down(dev); 588 dev_watchdog_down(dev);
585 589
586 while (test_bit(__LINK_STATE_SCHED, &dev->state)) 590 /* Wait for outstanding dev_queue_xmit calls. */
587 yield(); 591 synchronize_rcu();
588 592
589 spin_unlock_wait(&dev->_xmit_lock); 593 /* Wait for outstanding qdisc_run calls. */
594 while (test_bit(__LINK_STATE_QDISC_RUNNING, &dev->state))
595 yield();
590} 596}
591 597
592void dev_init_scheduler(struct net_device *dev) 598void dev_init_scheduler(struct net_device *dev)