Skip to content

Commit 5e50da0

Browse files
kaberDavid S. Miller
authored andcommitted
[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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 43effa1 commit 5e50da0

File tree

7 files changed

+22
-10
lines changed

7 files changed

+22
-10
lines changed

net/sched/sch_cbq.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1687,7 +1687,7 @@ static int cbq_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
16871687
sch_tree_lock(sch);
16881688
*old = cl->q;
16891689
cl->q = new;
1690-
sch->q.qlen -= (*old)->q.qlen;
1690+
qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
16911691
qdisc_reset(*old);
16921692
sch_tree_unlock(sch);
16931693

net/sched/sch_dsmark.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,8 @@ static int dsmark_graft(struct Qdisc *sch, unsigned long arg,
9696

9797
sch_tree_lock(sch);
9898
*old = xchg(&p->q, new);
99+
qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
99100
qdisc_reset(*old);
100-
sch->q.qlen = 0;
101101
sch_tree_unlock(sch);
102102

103103
return 0;

net/sched/sch_netem.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -662,8 +662,8 @@ static int netem_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
662662

663663
sch_tree_lock(sch);
664664
*old = xchg(&q->qdisc, new);
665+
qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
665666
qdisc_reset(*old);
666-
sch->q.qlen = 0;
667667
sch_tree_unlock(sch);
668668

669669
return 0;

net/sched/sch_prio.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,8 +222,10 @@ static int prio_tune(struct Qdisc *sch, struct rtattr *opt)
222222

223223
for (i=q->bands; i<TCQ_PRIO_BANDS; i++) {
224224
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);
226227
qdisc_destroy(child);
228+
}
227229
}
228230
sch_tree_unlock(sch);
229231

@@ -236,8 +238,11 @@ static int prio_tune(struct Qdisc *sch, struct rtattr *opt)
236238
sch_tree_lock(sch);
237239
child = xchg(&q->queues[i], child);
238240

239-
if (child != &noop_qdisc)
241+
if (child != &noop_qdisc) {
242+
qdisc_tree_decrease_qlen(child,
243+
child->q.qlen);
240244
qdisc_destroy(child);
245+
}
241246
sch_tree_unlock(sch);
242247
}
243248
}
@@ -295,7 +300,7 @@ static int prio_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
295300
sch_tree_lock(sch);
296301
*old = q->queues[band];
297302
q->queues[band] = new;
298-
sch->q.qlen -= (*old)->q.qlen;
303+
qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
299304
qdisc_reset(*old);
300305
sch_tree_unlock(sch);
301306

net/sched/sch_red.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,8 +229,10 @@ static int red_change(struct Qdisc *sch, struct rtattr *opt)
229229
sch_tree_lock(sch);
230230
q->flags = ctl->flags;
231231
q->limit = ctl->limit;
232-
if (child)
232+
if (child) {
233+
qdisc_tree_decrease_qlen(q->qdisc, q->qdisc->q.qlen);
233234
qdisc_destroy(xchg(&q->qdisc, child));
235+
}
234236

235237
red_set_parms(&q->parms, ctl->qth_min, ctl->qth_max, ctl->Wlog,
236238
ctl->Plog, ctl->Scell_log,
@@ -308,8 +310,8 @@ static int red_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
308310

309311
sch_tree_lock(sch);
310312
*old = xchg(&q->qdisc, new);
313+
qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
311314
qdisc_reset(*old);
312-
sch->q.qlen = 0;
313315
sch_tree_unlock(sch);
314316
return 0;
315317
}

net/sched/sch_sfq.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,7 @@ static int sfq_change(struct Qdisc *sch, struct rtattr *opt)
393393
{
394394
struct sfq_sched_data *q = qdisc_priv(sch);
395395
struct tc_sfq_qopt *ctl = RTA_DATA(opt);
396+
unsigned int qlen;
396397

397398
if (opt->rta_len < RTA_LENGTH(sizeof(*ctl)))
398399
return -EINVAL;
@@ -403,8 +404,10 @@ static int sfq_change(struct Qdisc *sch, struct rtattr *opt)
403404
if (ctl->limit)
404405
q->limit = min_t(u32, ctl->limit, SFQ_DEPTH);
405406

407+
qlen = sch->q.qlen;
406408
while (sch->q.qlen >= q->limit-1)
407409
sfq_drop(sch);
410+
qdisc_tree_decrease_qlen(sch, qlen - sch->q.qlen);
408411

409412
del_timer(&q->perturb_timer);
410413
if (q->perturb_period) {

net/sched/sch_tbf.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,8 +348,10 @@ static int tbf_change(struct Qdisc* sch, struct rtattr *opt)
348348
}
349349

350350
sch_tree_lock(sch);
351-
if (child)
351+
if (child) {
352+
qdisc_tree_decrease_qlen(q->qdisc, q->qdisc->q.qlen);
352353
qdisc_destroy(xchg(&q->qdisc, child));
354+
}
353355
q->limit = qopt->limit;
354356
q->mtu = qopt->mtu;
355357
q->max_size = max_size;
@@ -451,8 +453,8 @@ static int tbf_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
451453

452454
sch_tree_lock(sch);
453455
*old = xchg(&q->qdisc, new);
456+
qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
454457
qdisc_reset(*old);
455-
sch->q.qlen = 0;
456458
sch_tree_unlock(sch);
457459

458460
return 0;

0 commit comments

Comments
 (0)