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 /net/sched | |
| 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>
Diffstat (limited to 'net/sched')
| -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; |
