aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/sched/sch_hfsc.c44
1 files changed, 12 insertions, 32 deletions
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index 3ddc7bd74ecb..6329d7d0d334 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -151,11 +151,8 @@ struct hfsc_class {
151 (monotonic within a period) */ 151 (monotonic within a period) */
152 u64 cl_vtadj; /* intra-period cumulative vt 152 u64 cl_vtadj; /* intra-period cumulative vt
153 adjustment */ 153 adjustment */
154 u64 cl_vtoff; /* inter-period cumulative vt offset */ 154 u64 cl_cvtoff; /* largest virtual time seen among
155 u64 cl_cvtmax; /* max child's vt in the last period */ 155 the children */
156 u64 cl_cvtoff; /* cumulative cvtmax of all periods */
157 u64 cl_pcvtoff; /* parent's cvtoff at initialization
158 time */
159 156
160 struct internal_sc cl_rsc; /* internal real-time service curve */ 157 struct internal_sc cl_rsc; /* internal real-time service curve */
161 struct internal_sc cl_fsc; /* internal fair service curve */ 158 struct internal_sc cl_fsc; /* internal fair service curve */
@@ -701,28 +698,16 @@ init_vf(struct hfsc_class *cl, unsigned int len)
701 } else { 698 } else {
702 /* 699 /*
703 * first child for a new parent backlog period. 700 * first child for a new parent backlog period.
704 * add parent's cvtmax to cvtoff to make a new 701 * initialize cl_vt to the highest value seen
705 * vt (vtoff + vt) larger than the vt in the 702 * among the siblings. this is analogous to
706 * last period for all children. 703 * what cur_time would provide in realtime case.
707 */ 704 */
708 vt = cl->cl_parent->cl_cvtmax; 705 cl->cl_vt = cl->cl_parent->cl_cvtoff;
709 cl->cl_parent->cl_cvtoff += vt;
710 cl->cl_parent->cl_cvtmax = 0;
711 cl->cl_parent->cl_cvtmin = 0; 706 cl->cl_parent->cl_cvtmin = 0;
712 cl->cl_vt = 0;
713 } 707 }
714 708
715 cl->cl_vtoff = cl->cl_parent->cl_cvtoff -
716 cl->cl_pcvtoff;
717
718 /* update the virtual curve */ 709 /* update the virtual curve */
719 vt = cl->cl_vt + cl->cl_vtoff; 710 rtsc_min(&cl->cl_virtual, &cl->cl_fsc, cl->cl_vt, cl->cl_total);
720 rtsc_min(&cl->cl_virtual, &cl->cl_fsc, vt,
721 cl->cl_total);
722 if (cl->cl_virtual.x == vt) {
723 cl->cl_virtual.x -= cl->cl_vtoff;
724 cl->cl_vtoff = 0;
725 }
726 cl->cl_vtadj = 0; 711 cl->cl_vtadj = 0;
727 712
728 cl->cl_vtperiod++; /* increment vt period */ 713 cl->cl_vtperiod++; /* increment vt period */
@@ -779,8 +764,7 @@ update_vf(struct hfsc_class *cl, unsigned int len, u64 cur_time)
779 go_passive = 0; 764 go_passive = 0;
780 765
781 /* update vt */ 766 /* update vt */
782 cl->cl_vt = rtsc_y2x(&cl->cl_virtual, cl->cl_total) 767 cl->cl_vt = rtsc_y2x(&cl->cl_virtual, cl->cl_total) + cl->cl_vtadj;
783 - cl->cl_vtoff + cl->cl_vtadj;
784 768
785 /* 769 /*
786 * if vt of the class is smaller than cvtmin, 770 * if vt of the class is smaller than cvtmin,
@@ -795,9 +779,9 @@ update_vf(struct hfsc_class *cl, unsigned int len, u64 cur_time)
795 if (go_passive) { 779 if (go_passive) {
796 /* no more active child, going passive */ 780 /* no more active child, going passive */
797 781
798 /* update cvtmax of the parent class */ 782 /* update cvtoff of the parent class */
799 if (cl->cl_vt > cl->cl_parent->cl_cvtmax) 783 if (cl->cl_vt > cl->cl_parent->cl_cvtoff)
800 cl->cl_parent->cl_cvtmax = cl->cl_vt; 784 cl->cl_parent->cl_cvtoff = cl->cl_vt;
801 785
802 /* remove this class from the vt tree */ 786 /* remove this class from the vt tree */
803 vttree_remove(cl); 787 vttree_remove(cl);
@@ -940,7 +924,7 @@ static void
940hfsc_change_fsc(struct hfsc_class *cl, struct tc_service_curve *fsc) 924hfsc_change_fsc(struct hfsc_class *cl, struct tc_service_curve *fsc)
941{ 925{
942 sc2isc(fsc, &cl->cl_fsc); 926 sc2isc(fsc, &cl->cl_fsc);
943 rtsc_init(&cl->cl_virtual, &cl->cl_fsc, cl->cl_vtoff + cl->cl_vt, cl->cl_total); 927 rtsc_init(&cl->cl_virtual, &cl->cl_fsc, cl->cl_vt, cl->cl_total);
944 cl->cl_flags |= HFSC_FSC; 928 cl->cl_flags |= HFSC_FSC;
945} 929}
946 930
@@ -1094,7 +1078,6 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
1094 if (parent->level == 0) 1078 if (parent->level == 0)
1095 hfsc_purge_queue(sch, parent); 1079 hfsc_purge_queue(sch, parent);
1096 hfsc_adjust_levels(parent); 1080 hfsc_adjust_levels(parent);
1097 cl->cl_pcvtoff = parent->cl_cvtoff;
1098 sch_tree_unlock(sch); 1081 sch_tree_unlock(sch);
1099 1082
1100 qdisc_class_hash_grow(sch, &q->clhash); 1083 qdisc_class_hash_grow(sch, &q->clhash);
@@ -1482,11 +1465,8 @@ hfsc_reset_class(struct hfsc_class *cl)
1482 cl->cl_e = 0; 1465 cl->cl_e = 0;
1483 cl->cl_vt = 0; 1466 cl->cl_vt = 0;
1484 cl->cl_vtadj = 0; 1467 cl->cl_vtadj = 0;
1485 cl->cl_vtoff = 0;
1486 cl->cl_cvtmin = 0; 1468 cl->cl_cvtmin = 0;
1487 cl->cl_cvtmax = 0;
1488 cl->cl_cvtoff = 0; 1469 cl->cl_cvtoff = 0;
1489 cl->cl_pcvtoff = 0;
1490 cl->cl_vtperiod = 0; 1470 cl->cl_vtperiod = 0;
1491 cl->cl_parentperiod = 0; 1471 cl->cl_parentperiod = 0;
1492 cl->cl_f = 0; 1472 cl->cl_f = 0;