From 06015fb45aedd64616bf7e41c4c604dc10818d8f Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 19 Jun 2006 23:57:59 -0700 Subject: [PATCH] --- yaml --- r: 28066 b: refs/heads/master c: 48d83325b61043e3bbd24dd37b9fe433744cf330 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/include/linux/netdevice.h | 1 + trunk/include/net/pkt_sched.h | 7 ++++--- trunk/net/sched/sch_generic.c | 11 +++++++++-- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/[refs] b/[refs] index 40df4b7ede13..3c2f04e5a4d7 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: d6cc7f1a3b33c89c91b3dfce1ff053178893470e +refs/heads/master: 48d83325b61043e3bbd24dd37b9fe433744cf330 diff --git a/trunk/include/linux/netdevice.h b/trunk/include/linux/netdevice.h index e432b743dda2..39919c882a25 100644 --- a/trunk/include/linux/netdevice.h +++ b/trunk/include/linux/netdevice.h @@ -233,6 +233,7 @@ enum netdev_state_t __LINK_STATE_RX_SCHED, __LINK_STATE_LINKWATCH_PENDING, __LINK_STATE_DORMANT, + __LINK_STATE_QDISC_RUNNING, }; diff --git a/trunk/include/net/pkt_sched.h b/trunk/include/net/pkt_sched.h index b94d1ad92c4d..75b5b9333fc7 100644 --- a/trunk/include/net/pkt_sched.h +++ b/trunk/include/net/pkt_sched.h @@ -218,12 +218,13 @@ extern struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, struct rtattr *tab); extern void qdisc_put_rtab(struct qdisc_rate_table *tab); -extern int qdisc_restart(struct net_device *dev); +extern void __qdisc_run(struct net_device *dev); static inline void qdisc_run(struct net_device *dev) { - while (!netif_queue_stopped(dev) && qdisc_restart(dev) < 0) - /* NOTHING */; + if (!netif_queue_stopped(dev) && + !test_and_set_bit(__LINK_STATE_QDISC_RUNNING, &dev->state)) + __qdisc_run(dev); } extern int tc_classify(struct sk_buff *skb, struct tcf_proto *tp, diff --git a/trunk/net/sched/sch_generic.c b/trunk/net/sched/sch_generic.c index b1e4c5e20ac7..d7aca8ef524a 100644 --- a/trunk/net/sched/sch_generic.c +++ b/trunk/net/sched/sch_generic.c @@ -90,7 +90,7 @@ void qdisc_unlock_tree(struct net_device *dev) NOTE: Called under dev->queue_lock with locally disabled BH. */ -int qdisc_restart(struct net_device *dev) +static inline int qdisc_restart(struct net_device *dev) { struct Qdisc *q = dev->qdisc; struct sk_buff *skb; @@ -179,6 +179,14 @@ int qdisc_restart(struct net_device *dev) return q->q.qlen; } +void __qdisc_run(struct net_device *dev) +{ + while (qdisc_restart(dev) < 0 && !netif_queue_stopped(dev)) + /* NOTHING */; + + clear_bit(__LINK_STATE_QDISC_RUNNING, &dev->state); +} + static void dev_watchdog(unsigned long arg) { struct net_device *dev = (struct net_device *)arg; @@ -620,6 +628,5 @@ EXPORT_SYMBOL(qdisc_create_dflt); EXPORT_SYMBOL(qdisc_alloc); EXPORT_SYMBOL(qdisc_destroy); EXPORT_SYMBOL(qdisc_reset); -EXPORT_SYMBOL(qdisc_restart); EXPORT_SYMBOL(qdisc_lock_tree); EXPORT_SYMBOL(qdisc_unlock_tree);