[PATCH 06/11] sch_hfsc.c: seg_y2x(), rtsc_y2x(), hfsc_change_class() minor changes
STALE5447d
From: Michal Soltys <hidden>
Date: 2011-11-05 02:33:10
Subsystem:
networking [general], tc subsystem, the rest · Maintainers:
"David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Jamal Hadi Salim, Jiri Pirko, Linus Torvalds
hfsc_change_class(): Make sure that invalid input (flat 2nd segment, USC without FSC) is not allowed. Even though userspace (tc) does the respective checks as well - we want to verify if everything is in order before the following seg_y2x() change (and some other userspace tools not doing such checks might exist): seg_y2x(): All callers (actually there's only one - rtsc_y2x()) guarantee that the slope argument actually makese sense (otherwise the results would be unusable) - so we don't heave to check for +inf case. rtsc_y2x(): In case of flat 1st segment of a service curve, the function always returns maximum a, such that f(a) = y (for our curves then, a = x + dx). To keep things consistent (and continuous), we also return x+dx for values < y. --- net/sched/sch_hfsc.c | 39 +++++++++++++++++++++++++++++---------- 1 files changed, 29 insertions(+), 10 deletions(-)
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index e0cf11b..8da2d88 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c@@ -400,6 +400,8 @@ seg_y2x(u64 y, u64 ism) { u64 x; + /* callers guarantee that ism is not infinity */ +#if 0 if (y == 0) x = 0; else if (ism == HT_INFINITY)
@@ -408,6 +410,8 @@ seg_y2x(u64 y, u64 ism) x = (y >> ISM_SHIFT) * ism + (((y & ISM_MASK) * ism) >> ISM_SHIFT); } +#endif + x = (y >> ISM_SHIFT) * ism + (((y & ISM_MASK) * ism) >> ISM_SHIFT); return x; }
@@ -509,7 +513,7 @@ rtsc_y2x(struct runtime_sc *rtsc, u64 y) { u64 x; - if (y < rtsc->y) + if (y < rtsc->y && rtsc->dy != 0) x = rtsc->x; else if (y <= rtsc->y + rtsc->dy) { /* x belongs to the 1st segment */
@@ -985,22 +989,40 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, if (tb[TCA_HFSC_RSC]) { rsc = nla_data(tb[TCA_HFSC_RSC]); - if (rsc->m1 == 0 && rsc->m2 == 0) - rsc = NULL; + if (rsc->m2 == 0) { + if (rsc->m1 != 0) + return -EINVAL; + else + rsc = NULL; + } } if (tb[TCA_HFSC_FSC]) { fsc = nla_data(tb[TCA_HFSC_FSC]); - if (fsc->m1 == 0 && fsc->m2 == 0) - fsc = NULL; + if (fsc->m2 == 0) { + if (fsc->m1 != 0) + return -EINVAL; + else + fsc = NULL; + } } if (tb[TCA_HFSC_USC]) { usc = nla_data(tb[TCA_HFSC_USC]); - if (usc->m1 == 0 && usc->m2 == 0) - usc = NULL; + if (usc->m2 == 0) { + if (usc->m1 != 0) + return -EINVAL; + else + usc = NULL; + } } + if (rsc == NULL && fsc == NULL) + return -EINVAL; + + if (fsc == NULL && usc != NULL) + return -EINVAL; + if (cl != NULL) { if (parentid) { if (cl->cl_parent &&
@@ -1053,9 +1075,6 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, if (hfsc_find_class(classid, sch)) return -EEXIST; - if (rsc == NULL && fsc == NULL) - return -EINVAL; - cl = kzalloc(sizeof(struct hfsc_class), GFP_KERNEL); if (cl == NULL) return -ENOBUFS;
--
1.7.7.1