Commit e200c64b authored by David S. Miller's avatar David S. Miller Committed by Linus Torvalds

[PKT_SCHED]: Do not check netif_queue_stopped() in dequeue ops, races with driver.

Based upon a patch from Stephen Hemminger.
Signed-off-by: default avatarDavid S. Miller <davem@redhat.com>
parent 8c1dd613
...@@ -1054,7 +1054,7 @@ cbq_dequeue(struct Qdisc *sch) ...@@ -1054,7 +1054,7 @@ cbq_dequeue(struct Qdisc *sch)
if (sch->q.qlen) { if (sch->q.qlen) {
sch->stats.overlimits++; sch->stats.overlimits++;
if (q->wd_expires && !netif_queue_stopped(sch->dev)) { if (q->wd_expires) {
long delay = PSCHED_US2JIFFIE(q->wd_expires); long delay = PSCHED_US2JIFFIE(q->wd_expires);
if (delay <= 0) if (delay <= 0)
delay = 1; delay = 1;
......
...@@ -111,7 +111,7 @@ static struct sk_buff *dly_dequeue(struct Qdisc *sch) ...@@ -111,7 +111,7 @@ static struct sk_buff *dly_dequeue(struct Qdisc *sch)
if (skb) { if (skb) {
struct dly_skb_cb *cb = (struct dly_skb_cb *)skb->cb; struct dly_skb_cb *cb = (struct dly_skb_cb *)skb->cb;
psched_time_t now; psched_time_t now;
long diff; long diff, delay;
PSCHED_GET_TIME(now); PSCHED_GET_TIME(now);
diff = q->latency - PSCHED_TDIFF(now, cb->queuetime); diff = q->latency - PSCHED_TDIFF(now, cb->queuetime);
...@@ -128,12 +128,10 @@ static struct sk_buff *dly_dequeue(struct Qdisc *sch) ...@@ -128,12 +128,10 @@ static struct sk_buff *dly_dequeue(struct Qdisc *sch)
goto retry; goto retry;
} }
if (!netif_queue_stopped(sch->dev)) { delay = PSCHED_US2JIFFIE(diff);
long delay = PSCHED_US2JIFFIE(diff); if (delay <= 0)
if (delay <= 0) delay = 1;
delay = 1; mod_timer(&q->timer, jiffies+delay);
mod_timer(&q->timer, jiffies+delay);
}
sch->flags |= TCQ_F_THROTTLED; sch->flags |= TCQ_F_THROTTLED;
} }
......
...@@ -1721,8 +1721,7 @@ hfsc_dequeue(struct Qdisc *sch) ...@@ -1721,8 +1721,7 @@ hfsc_dequeue(struct Qdisc *sch)
cl = actlist_get_minvt(&q->root, cur_time); cl = actlist_get_minvt(&q->root, cur_time);
if (cl == NULL) { if (cl == NULL) {
sch->stats.overlimits++; sch->stats.overlimits++;
if (!netif_queue_stopped(sch->dev)) hfsc_schedule_watchdog(sch, cur_time);
hfsc_schedule_watchdog(sch, cur_time);
return NULL; return NULL;
} }
} }
......
...@@ -1008,7 +1008,6 @@ htb_dequeue_tree(struct htb_sched *q,int prio,int level) ...@@ -1008,7 +1008,6 @@ htb_dequeue_tree(struct htb_sched *q,int prio,int level)
static void htb_delay_by(struct Qdisc *sch,long delay) static void htb_delay_by(struct Qdisc *sch,long delay)
{ {
struct htb_sched *q = (struct htb_sched *)sch->data; struct htb_sched *q = (struct htb_sched *)sch->data;
if (netif_queue_stopped(sch->dev)) return;
if (delay <= 0) delay = 1; if (delay <= 0) delay = 1;
if (unlikely(delay > 5*HZ)) { if (unlikely(delay > 5*HZ)) {
if (net_ratelimit()) if (net_ratelimit())
......
...@@ -201,7 +201,7 @@ static struct sk_buff *tbf_dequeue(struct Qdisc* sch) ...@@ -201,7 +201,7 @@ static struct sk_buff *tbf_dequeue(struct Qdisc* sch)
if (skb) { if (skb) {
psched_time_t now; psched_time_t now;
long toks; long toks, delay;
long ptoks = 0; long ptoks = 0;
unsigned int len = skb->len; unsigned int len = skb->len;
...@@ -229,14 +229,12 @@ static struct sk_buff *tbf_dequeue(struct Qdisc* sch) ...@@ -229,14 +229,12 @@ static struct sk_buff *tbf_dequeue(struct Qdisc* sch)
return skb; return skb;
} }
if (!netif_queue_stopped(sch->dev)) { delay = PSCHED_US2JIFFIE(max_t(long, -toks, -ptoks));
long delay = PSCHED_US2JIFFIE(max_t(long, -toks, -ptoks));
if (delay == 0) if (delay == 0)
delay = 1; delay = 1;
mod_timer(&q->wd_timer, jiffies+delay); mod_timer(&q->wd_timer, jiffies+delay);
}
/* Maybe we have a shorter packet in the queue, /* Maybe we have a shorter packet in the queue,
which can be sent now. It sounds cool, which can be sent now. It sounds cool,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment