net_sched/hfsc: fix curve activation in hfsc_change_class()
authorKonstantin Khlebnikov <khlebnikov@yandex-team.ru>
Wed, 20 Sep 2017 12:46:11 +0000 (15:46 +0300)
committerDavid S. Miller <davem@davemloft.net>
Thu, 21 Sep 2017 18:56:32 +0000 (11:56 -0700)
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>
net/sched/sch_hfsc.c

index daaf214e5201919ca3681e1670ac1389cb7985a4..3f88b75488b03275b152298bab0e66ea02298caa 100644 (file)
@@ -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);