diff options
author | Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> | 2007-09-19 13:42:03 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-09-20 15:14:08 -0400 |
commit | 5588b40d7c2bff75ee573ed42d1738c73ce24492 (patch) | |
tree | ab075cd6d417054139ce9b0d90c4fff5aa59ab0a /net/sched | |
parent | 1a03b81db96aeaac0276224f25c0701a1ba37318 (diff) |
[PKT_SCHED]: Fix 'SFQ qdisc crashes with limit of 2 packets'
Acked-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sched')
-rw-r--r-- | net/sched/sch_sfq.c | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index 957957309859..3a23e30bc79e 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c | |||
@@ -270,7 +270,7 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc* sch) | |||
270 | q->tail = x; | 270 | q->tail = x; |
271 | } | 271 | } |
272 | } | 272 | } |
273 | if (++sch->q.qlen < q->limit-1) { | 273 | if (++sch->q.qlen <= q->limit) { |
274 | sch->bstats.bytes += skb->len; | 274 | sch->bstats.bytes += skb->len; |
275 | sch->bstats.packets++; | 275 | sch->bstats.packets++; |
276 | return 0; | 276 | return 0; |
@@ -306,7 +306,7 @@ sfq_requeue(struct sk_buff *skb, struct Qdisc* sch) | |||
306 | q->tail = x; | 306 | q->tail = x; |
307 | } | 307 | } |
308 | } | 308 | } |
309 | if (++sch->q.qlen < q->limit - 1) { | 309 | if (++sch->q.qlen <= q->limit) { |
310 | sch->qstats.requeues++; | 310 | sch->qstats.requeues++; |
311 | return 0; | 311 | return 0; |
312 | } | 312 | } |
@@ -391,10 +391,10 @@ static int sfq_change(struct Qdisc *sch, struct rtattr *opt) | |||
391 | q->quantum = ctl->quantum ? : psched_mtu(sch->dev); | 391 | q->quantum = ctl->quantum ? : psched_mtu(sch->dev); |
392 | q->perturb_period = ctl->perturb_period*HZ; | 392 | q->perturb_period = ctl->perturb_period*HZ; |
393 | if (ctl->limit) | 393 | if (ctl->limit) |
394 | q->limit = min_t(u32, ctl->limit, SFQ_DEPTH); | 394 | q->limit = min_t(u32, ctl->limit, SFQ_DEPTH - 2); |
395 | 395 | ||
396 | qlen = sch->q.qlen; | 396 | qlen = sch->q.qlen; |
397 | while (sch->q.qlen >= q->limit-1) | 397 | while (sch->q.qlen > q->limit) |
398 | sfq_drop(sch); | 398 | sfq_drop(sch); |
399 | qdisc_tree_decrease_qlen(sch, qlen - sch->q.qlen); | 399 | qdisc_tree_decrease_qlen(sch, qlen - sch->q.qlen); |
400 | 400 | ||
@@ -423,7 +423,7 @@ static int sfq_init(struct Qdisc *sch, struct rtattr *opt) | |||
423 | q->dep[i+SFQ_DEPTH].next = i+SFQ_DEPTH; | 423 | q->dep[i+SFQ_DEPTH].next = i+SFQ_DEPTH; |
424 | q->dep[i+SFQ_DEPTH].prev = i+SFQ_DEPTH; | 424 | q->dep[i+SFQ_DEPTH].prev = i+SFQ_DEPTH; |
425 | } | 425 | } |
426 | q->limit = SFQ_DEPTH; | 426 | q->limit = SFQ_DEPTH - 2; |
427 | q->max_depth = 0; | 427 | q->max_depth = 0; |
428 | q->tail = SFQ_DEPTH; | 428 | q->tail = SFQ_DEPTH; |
429 | if (opt == NULL) { | 429 | if (opt == NULL) { |