[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: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
5e50da01d0
commit
f973b913e1
@@ -957,11 +957,7 @@ hfsc_purge_queue(struct Qdisc *sch, struct hfsc_class *cl)
|
|||||||
unsigned int len = cl->qdisc->q.qlen;
|
unsigned int len = cl->qdisc->q.qlen;
|
||||||
|
|
||||||
qdisc_reset(cl->qdisc);
|
qdisc_reset(cl->qdisc);
|
||||||
if (len > 0) {
|
qdisc_tree_decrease_qlen(cl->qdisc, len);
|
||||||
update_vf(cl, 0, 0);
|
|
||||||
set_passive(cl);
|
|
||||||
sch->q.qlen -= len;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1295,6 +1291,17 @@ hfsc_class_leaf(struct Qdisc *sch, unsigned long arg)
|
|||||||
return NULL;
|
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
|
static unsigned long
|
||||||
hfsc_get_class(struct Qdisc *sch, u32 classid)
|
hfsc_get_class(struct Qdisc *sch, u32 classid)
|
||||||
{
|
{
|
||||||
@@ -1779,6 +1786,7 @@ static struct Qdisc_class_ops hfsc_class_ops = {
|
|||||||
.delete = hfsc_delete_class,
|
.delete = hfsc_delete_class,
|
||||||
.graft = hfsc_graft_class,
|
.graft = hfsc_graft_class,
|
||||||
.leaf = hfsc_class_leaf,
|
.leaf = hfsc_class_leaf,
|
||||||
|
.qlen_notify = hfsc_qlen_notify,
|
||||||
.get = hfsc_get_class,
|
.get = hfsc_get_class,
|
||||||
.put = hfsc_put_class,
|
.put = hfsc_put_class,
|
||||||
.bind_tcf = hfsc_bind_tcf,
|
.bind_tcf = hfsc_bind_tcf,
|
||||||
|
Reference in New Issue
Block a user