aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/netdevice.h1
-rw-r--r--include/net/pkt_sched.h7
-rw-r--r--net/sched/sch_generic.c11
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);
219extern void qdisc_put_rtab(struct qdisc_rate_table *tab); 219extern void qdisc_put_rtab(struct qdisc_rate_table *tab);
220 220
221extern int qdisc_restart(struct net_device *dev); 221extern void __qdisc_run(struct net_device *dev);
222 222
223static inline void qdisc_run(struct net_device *dev) 223static 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
229extern int tc_classify(struct sk_buff *skb, struct tcf_proto *tp, 230extern 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
93int qdisc_restart(struct net_device *dev) 93static 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
182void __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
182static void dev_watchdog(unsigned long arg) 190static 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);
620EXPORT_SYMBOL(qdisc_alloc); 628EXPORT_SYMBOL(qdisc_alloc);
621EXPORT_SYMBOL(qdisc_destroy); 629EXPORT_SYMBOL(qdisc_destroy);
622EXPORT_SYMBOL(qdisc_reset); 630EXPORT_SYMBOL(qdisc_reset);
623EXPORT_SYMBOL(qdisc_restart);
624EXPORT_SYMBOL(qdisc_lock_tree); 631EXPORT_SYMBOL(qdisc_lock_tree);
625EXPORT_SYMBOL(qdisc_unlock_tree); 632EXPORT_SYMBOL(qdisc_unlock_tree);