diff options
Diffstat (limited to 'net/sched')
-rw-r--r-- | net/sched/Kconfig | 10 | ||||
-rw-r--r-- | net/sched/sch_generic.c | 26 |
2 files changed, 26 insertions, 10 deletions
diff --git a/net/sched/Kconfig b/net/sched/Kconfig index 92435a882f..9c15c4888d 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig | |||
@@ -2,9 +2,7 @@ | |||
2 | # Traffic control configuration. | 2 | # Traffic control configuration. |
3 | # | 3 | # |
4 | 4 | ||
5 | menu "QoS and/or fair queueing" | 5 | menuconfig NET_SCHED |
6 | |||
7 | config NET_SCHED | ||
8 | bool "QoS and/or fair queueing" | 6 | bool "QoS and/or fair queueing" |
9 | select NET_SCH_FIFO | 7 | select NET_SCH_FIFO |
10 | ---help--- | 8 | ---help--- |
@@ -41,9 +39,6 @@ config NET_SCHED | |||
41 | The available schedulers are listed in the following questions; you | 39 | The available schedulers are listed in the following questions; you |
42 | can say Y to as many as you like. If unsure, say N now. | 40 | can say Y to as many as you like. If unsure, say N now. |
43 | 41 | ||
44 | config NET_SCH_FIFO | ||
45 | bool | ||
46 | |||
47 | if NET_SCHED | 42 | if NET_SCHED |
48 | 43 | ||
49 | comment "Queueing/Scheduling" | 44 | comment "Queueing/Scheduling" |
@@ -500,4 +495,5 @@ config NET_CLS_IND | |||
500 | 495 | ||
501 | endif # NET_SCHED | 496 | endif # NET_SCHED |
502 | 497 | ||
503 | endmenu | 498 | config NET_SCH_FIFO |
499 | bool | ||
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index e01d57692c..fa1a6f45dc 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
@@ -556,6 +556,7 @@ void dev_deactivate(struct net_device *dev) | |||
556 | { | 556 | { |
557 | struct Qdisc *qdisc; | 557 | struct Qdisc *qdisc; |
558 | struct sk_buff *skb; | 558 | struct sk_buff *skb; |
559 | int running; | ||
559 | 560 | ||
560 | spin_lock_bh(&dev->queue_lock); | 561 | spin_lock_bh(&dev->queue_lock); |
561 | qdisc = dev->qdisc; | 562 | qdisc = dev->qdisc; |
@@ -571,12 +572,31 @@ void dev_deactivate(struct net_device *dev) | |||
571 | 572 | ||
572 | dev_watchdog_down(dev); | 573 | dev_watchdog_down(dev); |
573 | 574 | ||
574 | /* Wait for outstanding dev_queue_xmit calls. */ | 575 | /* Wait for outstanding qdisc-less dev_queue_xmit calls. */ |
575 | synchronize_rcu(); | 576 | synchronize_rcu(); |
576 | 577 | ||
577 | /* Wait for outstanding qdisc_run calls. */ | 578 | /* Wait for outstanding qdisc_run calls. */ |
578 | while (test_bit(__LINK_STATE_QDISC_RUNNING, &dev->state)) | 579 | do { |
579 | yield(); | 580 | while (test_bit(__LINK_STATE_QDISC_RUNNING, &dev->state)) |
581 | yield(); | ||
582 | |||
583 | /* | ||
584 | * Double-check inside queue lock to ensure that all effects | ||
585 | * of the queue run are visible when we return. | ||
586 | */ | ||
587 | spin_lock_bh(&dev->queue_lock); | ||
588 | running = test_bit(__LINK_STATE_QDISC_RUNNING, &dev->state); | ||
589 | spin_unlock_bh(&dev->queue_lock); | ||
590 | |||
591 | /* | ||
592 | * The running flag should never be set at this point because | ||
593 | * we've already set dev->qdisc to noop_qdisc *inside* the same | ||
594 | * pair of spin locks. That is, if any qdisc_run starts after | ||
595 | * our initial test it should see the noop_qdisc and then | ||
596 | * clear the RUNNING bit before dropping the queue lock. So | ||
597 | * if it is set here then we've found a bug. | ||
598 | */ | ||
599 | } while (WARN_ON_ONCE(running)); | ||
580 | } | 600 | } |
581 | 601 | ||
582 | void dev_init_scheduler(struct net_device *dev) | 602 | void dev_init_scheduler(struct net_device *dev) |