diff options
-rw-r--r-- | include/linux/netdevice.h | 1 | ||||
-rw-r--r-- | include/net/pkt_sched.h | 7 | ||||
-rw-r--r-- | net/sched/sch_generic.c | 11 |
3 files changed, 14 insertions, 5 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index e432b743dda2..39919c882a25 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -233,6 +233,7 @@ enum netdev_state_t | |||
233 | __LINK_STATE_RX_SCHED, | 233 | __LINK_STATE_RX_SCHED, |
234 | __LINK_STATE_LINKWATCH_PENDING, | 234 | __LINK_STATE_LINKWATCH_PENDING, |
235 | __LINK_STATE_DORMANT, | 235 | __LINK_STATE_DORMANT, |
236 | __LINK_STATE_QDISC_RUNNING, | ||
236 | }; | 237 | }; |
237 | 238 | ||
238 | 239 | ||
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h index b94d1ad92c4d..75b5b9333fc7 100644 --- a/include/net/pkt_sched.h +++ b/include/net/pkt_sched.h | |||
@@ -218,12 +218,13 @@ extern struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, | |||
218 | struct rtattr *tab); | 218 | struct rtattr *tab); |
219 | extern void qdisc_put_rtab(struct qdisc_rate_table *tab); | 219 | extern void qdisc_put_rtab(struct qdisc_rate_table *tab); |
220 | 220 | ||
221 | extern int qdisc_restart(struct net_device *dev); | 221 | extern void __qdisc_run(struct net_device *dev); |
222 | 222 | ||
223 | static inline void qdisc_run(struct net_device *dev) | 223 | static inline void qdisc_run(struct net_device *dev) |
224 | { | 224 | { |
225 | while (!netif_queue_stopped(dev) && qdisc_restart(dev) < 0) | 225 | if (!netif_queue_stopped(dev) && |
226 | /* NOTHING */; | 226 | !test_and_set_bit(__LINK_STATE_QDISC_RUNNING, &dev->state)) |
227 | __qdisc_run(dev); | ||
227 | } | 228 | } |
228 | 229 | ||
229 | extern int tc_classify(struct sk_buff *skb, struct tcf_proto *tp, | 230 | extern int tc_classify(struct sk_buff *skb, struct tcf_proto *tp, |
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index b1e4c5e20ac7..d7aca8ef524a 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
@@ -90,7 +90,7 @@ void qdisc_unlock_tree(struct net_device *dev) | |||
90 | NOTE: Called under dev->queue_lock with locally disabled BH. | 90 | NOTE: Called under dev->queue_lock with locally disabled BH. |
91 | */ | 91 | */ |
92 | 92 | ||
93 | int qdisc_restart(struct net_device *dev) | 93 | static inline int qdisc_restart(struct net_device *dev) |
94 | { | 94 | { |
95 | struct Qdisc *q = dev->qdisc; | 95 | struct Qdisc *q = dev->qdisc; |
96 | struct sk_buff *skb; | 96 | struct sk_buff *skb; |
@@ -179,6 +179,14 @@ requeue: | |||
179 | return q->q.qlen; | 179 | return q->q.qlen; |
180 | } | 180 | } |
181 | 181 | ||
182 | void __qdisc_run(struct net_device *dev) | ||
183 | { | ||
184 | while (qdisc_restart(dev) < 0 && !netif_queue_stopped(dev)) | ||
185 | /* NOTHING */; | ||
186 | |||
187 | clear_bit(__LINK_STATE_QDISC_RUNNING, &dev->state); | ||
188 | } | ||
189 | |||
182 | static void dev_watchdog(unsigned long arg) | 190 | static void dev_watchdog(unsigned long arg) |
183 | { | 191 | { |
184 | struct net_device *dev = (struct net_device *)arg; | 192 | struct net_device *dev = (struct net_device *)arg; |
@@ -620,6 +628,5 @@ EXPORT_SYMBOL(qdisc_create_dflt); | |||
620 | EXPORT_SYMBOL(qdisc_alloc); | 628 | EXPORT_SYMBOL(qdisc_alloc); |
621 | EXPORT_SYMBOL(qdisc_destroy); | 629 | EXPORT_SYMBOL(qdisc_destroy); |
622 | EXPORT_SYMBOL(qdisc_reset); | 630 | EXPORT_SYMBOL(qdisc_reset); |
623 | EXPORT_SYMBOL(qdisc_restart); | ||
624 | EXPORT_SYMBOL(qdisc_lock_tree); | 631 | EXPORT_SYMBOL(qdisc_lock_tree); |
625 | EXPORT_SYMBOL(qdisc_unlock_tree); | 632 | EXPORT_SYMBOL(qdisc_unlock_tree); |