pkt_sched: sch_drr: fix drr_dequeue loop()
Jarek Poplawski points out: If all child qdiscs of sch_drr are non-work-conserving (e.g. sch_tbf) drr_dequeue() will busy-loop waiting for skbs instead of leaving the job for a watchdog. Checking for list_empty() in each loop isn't necessary either, because this can never be true except the first time. Using non-work-conserving qdiscs as children of DRR makes no sense, simply bail out in that case. Reported-by: Jarek Poplawski <jarkao2@gmail.com> Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
4b40eed73e
commit
3f0947c3ff
|
@ -373,11 +373,13 @@ static struct sk_buff *drr_dequeue(struct Qdisc *sch)
|
|||
struct sk_buff *skb;
|
||||
unsigned int len;
|
||||
|
||||
while (!list_empty(&q->active)) {
|
||||
if (list_empty(&q->active))
|
||||
goto out;
|
||||
while (1) {
|
||||
cl = list_first_entry(&q->active, struct drr_class, alist);
|
||||
skb = cl->qdisc->ops->peek(cl->qdisc);
|
||||
if (skb == NULL)
|
||||
goto skip;
|
||||
goto out;
|
||||
|
||||
len = qdisc_pkt_len(skb);
|
||||
if (len <= cl->deficit) {
|
||||
|
@ -390,9 +392,9 @@ static struct sk_buff *drr_dequeue(struct Qdisc *sch)
|
|||
}
|
||||
|
||||
cl->deficit += cl->quantum;
|
||||
skip:
|
||||
list_move_tail(&cl->alist, &q->active);
|
||||
}
|
||||
out:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue