diff options
author | Konstantin Khlebnikov <khlebnikov@yandex-team.ru> | 2017-09-20 15:46:11 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-09-21 11:56:32 -0700 |
commit | 21f4d5cc25ec0e6e8eb8420dd2c399e6d2fc7d14 (patch) | |
tree | b6d820299994336c14458d8a198a1cb9fce79730 | |
parent | c8e1812960eeae42e2183154927028511c4bc566 (diff) | |
download | linux-exynos-21f4d5cc25ec0e6e8eb8420dd2c399e6d2fc7d14.tar.gz linux-exynos-21f4d5cc25ec0e6e8eb8420dd2c399e6d2fc7d14.tar.bz2 linux-exynos-21f4d5cc25ec0e6e8eb8420dd2c399e6d2fc7d14.zip |
net_sched/hfsc: fix curve activation in hfsc_change_class()
If real-time or fair-share curves are enabled in hfsc_change_class()
class isn't inserted into rb-trees yet. Thus init_ed() and init_vf()
must be called in place of update_ed() and update_vf().
Remove isn't required because for now curves cannot be disabled.
Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/sched/sch_hfsc.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index daaf214e5201..3f88b75488b0 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c @@ -958,6 +958,8 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, } if (cl != NULL) { + int old_flags; + if (parentid) { if (cl->cl_parent && cl->cl_parent->cl_common.classid != parentid) @@ -978,6 +980,8 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, } sch_tree_lock(sch); + old_flags = cl->cl_flags; + if (rsc != NULL) hfsc_change_rsc(cl, rsc, cur_time); if (fsc != NULL) @@ -986,10 +990,21 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, hfsc_change_usc(cl, usc, cur_time); if (cl->qdisc->q.qlen != 0) { - if (cl->cl_flags & HFSC_RSC) - update_ed(cl, qdisc_peek_len(cl->qdisc)); - if (cl->cl_flags & HFSC_FSC) - update_vf(cl, 0, cur_time); + int len = qdisc_peek_len(cl->qdisc); + + if (cl->cl_flags & HFSC_RSC) { + if (old_flags & HFSC_RSC) + update_ed(cl, len); + else + init_ed(cl, len); + } + + if (cl->cl_flags & HFSC_FSC) { + if (old_flags & HFSC_FSC) + update_vf(cl, 0, cur_time); + else + init_vf(cl, len); + } } sch_tree_unlock(sch); |