diff options
author | Patrick McHardy <kaber@trash.net> | 2006-11-29 20:36:20 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-12-03 00:31:43 -0500 |
commit | 5e50da01d0ce7ef0ba3ed6cfabd62f327da0aca6 (patch) | |
tree | 6f2205ceae40a7fd5b498e94c60b65140740a027 | |
parent | 43effa1e57fc4635e0301b27d78f9d83afe78974 (diff) |
[NET_SCHED]: Fix endless loops (part 2): "simple" qdiscs
Convert the "simple" qdiscs to use qdisc_tree_decrease_qlen() where
necessary:
- all graft operations
- destruction of old child qdiscs in prio, red and tbf change operation
- purging of queue in sfq change operation
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/sched/sch_cbq.c | 2 | ||||
-rw-r--r-- | net/sched/sch_dsmark.c | 2 | ||||
-rw-r--r-- | net/sched/sch_netem.c | 2 | ||||
-rw-r--r-- | net/sched/sch_prio.c | 11 | ||||
-rw-r--r-- | net/sched/sch_red.c | 6 | ||||
-rw-r--r-- | net/sched/sch_sfq.c | 3 | ||||
-rw-r--r-- | net/sched/sch_tbf.c | 6 |
7 files changed, 22 insertions, 10 deletions
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index 908b10d0d61f..ba82dfab6043 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c | |||
@@ -1687,7 +1687,7 @@ static int cbq_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, | |||
1687 | sch_tree_lock(sch); | 1687 | sch_tree_lock(sch); |
1688 | *old = cl->q; | 1688 | *old = cl->q; |
1689 | cl->q = new; | 1689 | cl->q = new; |
1690 | sch->q.qlen -= (*old)->q.qlen; | 1690 | qdisc_tree_decrease_qlen(*old, (*old)->q.qlen); |
1691 | qdisc_reset(*old); | 1691 | qdisc_reset(*old); |
1692 | sch_tree_unlock(sch); | 1692 | sch_tree_unlock(sch); |
1693 | 1693 | ||
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c index afedd92b7496..d5421816f007 100644 --- a/net/sched/sch_dsmark.c +++ b/net/sched/sch_dsmark.c | |||
@@ -96,8 +96,8 @@ static int dsmark_graft(struct Qdisc *sch, unsigned long arg, | |||
96 | 96 | ||
97 | sch_tree_lock(sch); | 97 | sch_tree_lock(sch); |
98 | *old = xchg(&p->q, new); | 98 | *old = xchg(&p->q, new); |
99 | qdisc_tree_decrease_qlen(*old, (*old)->q.qlen); | ||
99 | qdisc_reset(*old); | 100 | qdisc_reset(*old); |
100 | sch->q.qlen = 0; | ||
101 | sch_tree_unlock(sch); | 101 | sch_tree_unlock(sch); |
102 | 102 | ||
103 | return 0; | 103 | return 0; |
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index 90aeeb7b7167..672c35445793 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c | |||
@@ -662,8 +662,8 @@ static int netem_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, | |||
662 | 662 | ||
663 | sch_tree_lock(sch); | 663 | sch_tree_lock(sch); |
664 | *old = xchg(&q->qdisc, new); | 664 | *old = xchg(&q->qdisc, new); |
665 | qdisc_tree_decrease_qlen(*old, (*old)->q.qlen); | ||
665 | qdisc_reset(*old); | 666 | qdisc_reset(*old); |
666 | sch->q.qlen = 0; | ||
667 | sch_tree_unlock(sch); | 667 | sch_tree_unlock(sch); |
668 | 668 | ||
669 | return 0; | 669 | return 0; |
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c index 3fc0c0fa5bcc..2567b4c96c1e 100644 --- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c | |||
@@ -222,8 +222,10 @@ static int prio_tune(struct Qdisc *sch, struct rtattr *opt) | |||
222 | 222 | ||
223 | for (i=q->bands; i<TCQ_PRIO_BANDS; i++) { | 223 | for (i=q->bands; i<TCQ_PRIO_BANDS; i++) { |
224 | struct Qdisc *child = xchg(&q->queues[i], &noop_qdisc); | 224 | struct Qdisc *child = xchg(&q->queues[i], &noop_qdisc); |
225 | if (child != &noop_qdisc) | 225 | if (child != &noop_qdisc) { |
226 | qdisc_tree_decrease_qlen(child, child->q.qlen); | ||
226 | qdisc_destroy(child); | 227 | qdisc_destroy(child); |
228 | } | ||
227 | } | 229 | } |
228 | sch_tree_unlock(sch); | 230 | sch_tree_unlock(sch); |
229 | 231 | ||
@@ -236,8 +238,11 @@ static int prio_tune(struct Qdisc *sch, struct rtattr *opt) | |||
236 | sch_tree_lock(sch); | 238 | sch_tree_lock(sch); |
237 | child = xchg(&q->queues[i], child); | 239 | child = xchg(&q->queues[i], child); |
238 | 240 | ||
239 | if (child != &noop_qdisc) | 241 | if (child != &noop_qdisc) { |
242 | qdisc_tree_decrease_qlen(child, | ||
243 | child->q.qlen); | ||
240 | qdisc_destroy(child); | 244 | qdisc_destroy(child); |
245 | } | ||
241 | sch_tree_unlock(sch); | 246 | sch_tree_unlock(sch); |
242 | } | 247 | } |
243 | } | 248 | } |
@@ -295,7 +300,7 @@ static int prio_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, | |||
295 | sch_tree_lock(sch); | 300 | sch_tree_lock(sch); |
296 | *old = q->queues[band]; | 301 | *old = q->queues[band]; |
297 | q->queues[band] = new; | 302 | q->queues[band] = new; |
298 | sch->q.qlen -= (*old)->q.qlen; | 303 | qdisc_tree_decrease_qlen(*old, (*old)->q.qlen); |
299 | qdisc_reset(*old); | 304 | qdisc_reset(*old); |
300 | sch_tree_unlock(sch); | 305 | sch_tree_unlock(sch); |
301 | 306 | ||
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c index ee66c5ca80c6..acddad08850f 100644 --- a/net/sched/sch_red.c +++ b/net/sched/sch_red.c | |||
@@ -229,8 +229,10 @@ static int red_change(struct Qdisc *sch, struct rtattr *opt) | |||
229 | sch_tree_lock(sch); | 229 | sch_tree_lock(sch); |
230 | q->flags = ctl->flags; | 230 | q->flags = ctl->flags; |
231 | q->limit = ctl->limit; | 231 | q->limit = ctl->limit; |
232 | if (child) | 232 | if (child) { |
233 | qdisc_tree_decrease_qlen(q->qdisc, q->qdisc->q.qlen); | ||
233 | qdisc_destroy(xchg(&q->qdisc, child)); | 234 | qdisc_destroy(xchg(&q->qdisc, child)); |
235 | } | ||
234 | 236 | ||
235 | red_set_parms(&q->parms, ctl->qth_min, ctl->qth_max, ctl->Wlog, | 237 | red_set_parms(&q->parms, ctl->qth_min, ctl->qth_max, ctl->Wlog, |
236 | ctl->Plog, ctl->Scell_log, | 238 | ctl->Plog, ctl->Scell_log, |
@@ -308,8 +310,8 @@ static int red_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, | |||
308 | 310 | ||
309 | sch_tree_lock(sch); | 311 | sch_tree_lock(sch); |
310 | *old = xchg(&q->qdisc, new); | 312 | *old = xchg(&q->qdisc, new); |
313 | qdisc_tree_decrease_qlen(*old, (*old)->q.qlen); | ||
311 | qdisc_reset(*old); | 314 | qdisc_reset(*old); |
312 | sch->q.qlen = 0; | ||
313 | sch_tree_unlock(sch); | 315 | sch_tree_unlock(sch); |
314 | return 0; | 316 | return 0; |
315 | } | 317 | } |
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index d0d6e595a78c..459cda258a5c 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c | |||
@@ -393,6 +393,7 @@ static int sfq_change(struct Qdisc *sch, struct rtattr *opt) | |||
393 | { | 393 | { |
394 | struct sfq_sched_data *q = qdisc_priv(sch); | 394 | struct sfq_sched_data *q = qdisc_priv(sch); |
395 | struct tc_sfq_qopt *ctl = RTA_DATA(opt); | 395 | struct tc_sfq_qopt *ctl = RTA_DATA(opt); |
396 | unsigned int qlen; | ||
396 | 397 | ||
397 | if (opt->rta_len < RTA_LENGTH(sizeof(*ctl))) | 398 | if (opt->rta_len < RTA_LENGTH(sizeof(*ctl))) |
398 | return -EINVAL; | 399 | return -EINVAL; |
@@ -403,8 +404,10 @@ static int sfq_change(struct Qdisc *sch, struct rtattr *opt) | |||
403 | if (ctl->limit) | 404 | if (ctl->limit) |
404 | q->limit = min_t(u32, ctl->limit, SFQ_DEPTH); | 405 | q->limit = min_t(u32, ctl->limit, SFQ_DEPTH); |
405 | 406 | ||
407 | qlen = sch->q.qlen; | ||
406 | while (sch->q.qlen >= q->limit-1) | 408 | while (sch->q.qlen >= q->limit-1) |
407 | sfq_drop(sch); | 409 | sfq_drop(sch); |
410 | qdisc_tree_decrease_qlen(sch, qlen - sch->q.qlen); | ||
408 | 411 | ||
409 | del_timer(&q->perturb_timer); | 412 | del_timer(&q->perturb_timer); |
410 | if (q->perturb_period) { | 413 | if (q->perturb_period) { |
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c index 2562a6040b76..23b7624354f5 100644 --- a/net/sched/sch_tbf.c +++ b/net/sched/sch_tbf.c | |||
@@ -348,8 +348,10 @@ static int tbf_change(struct Qdisc* sch, struct rtattr *opt) | |||
348 | } | 348 | } |
349 | 349 | ||
350 | sch_tree_lock(sch); | 350 | sch_tree_lock(sch); |
351 | if (child) | 351 | if (child) { |
352 | qdisc_tree_decrease_qlen(q->qdisc, q->qdisc->q.qlen); | ||
352 | qdisc_destroy(xchg(&q->qdisc, child)); | 353 | qdisc_destroy(xchg(&q->qdisc, child)); |
354 | } | ||
353 | q->limit = qopt->limit; | 355 | q->limit = qopt->limit; |
354 | q->mtu = qopt->mtu; | 356 | q->mtu = qopt->mtu; |
355 | q->max_size = max_size; | 357 | q->max_size = max_size; |
@@ -451,8 +453,8 @@ static int tbf_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, | |||
451 | 453 | ||
452 | sch_tree_lock(sch); | 454 | sch_tree_lock(sch); |
453 | *old = xchg(&q->qdisc, new); | 455 | *old = xchg(&q->qdisc, new); |
456 | qdisc_tree_decrease_qlen(*old, (*old)->q.qlen); | ||
454 | qdisc_reset(*old); | 457 | qdisc_reset(*old); |
455 | sch->q.qlen = 0; | ||
456 | sch_tree_unlock(sch); | 458 | sch_tree_unlock(sch); |
457 | 459 | ||
458 | return 0; | 460 | return 0; |