Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f973b913 authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller
Browse files

[NET_SCHED]: Fix endless loops (part 3): HFSC



Convert HFSC to use qdisc_tree_decrease_len() and add a callback
for deactivating a class when its child queue becomes empty.

All queue purging goes through hfsc_purge_queue(), which is used in
three cases: grafting, class creation (when a leaf class is turned
into an intermediate class by attaching a new class) and class
deletion. In all cases qdisc_tree_decrease_len() is needed.

Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5e50da01
Loading
Loading
Loading
Loading
+13 −5
Original line number Diff line number Diff line
@@ -957,11 +957,7 @@ hfsc_purge_queue(struct Qdisc *sch, struct hfsc_class *cl)
	unsigned int len = cl->qdisc->q.qlen;

	qdisc_reset(cl->qdisc);
	if (len > 0) {
		update_vf(cl, 0, 0);
		set_passive(cl);
		sch->q.qlen -= len;
	}
	qdisc_tree_decrease_qlen(cl->qdisc, len);
}

static void
@@ -1295,6 +1291,17 @@ hfsc_class_leaf(struct Qdisc *sch, unsigned long arg)
	return NULL;
}

static void
hfsc_qlen_notify(struct Qdisc *sch, unsigned long arg)
{
	struct hfsc_class *cl = (struct hfsc_class *)arg;

	if (cl->qdisc->q.qlen == 0) {
		update_vf(cl, 0, 0);
		set_passive(cl);
	}
}

static unsigned long
hfsc_get_class(struct Qdisc *sch, u32 classid)
{
@@ -1779,6 +1786,7 @@ static struct Qdisc_class_ops hfsc_class_ops = {
	.delete		= hfsc_delete_class,
	.graft		= hfsc_graft_class,
	.leaf		= hfsc_class_leaf,
	.qlen_notify	= hfsc_qlen_notify,
	.get		= hfsc_get_class,
	.put		= hfsc_put_class,
	.bind_tcf	= hfsc_bind_tcf,