diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2011-12-08 21:46:45 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-12-09 13:46:15 -0500 |
commit | a73ed26bbae7327370c5bd298f07de78df9e3466 (patch) | |
tree | 3c7a04e638261cdd16c324ecd07e303e72fac3b9 /net/sched/sch_red.c | |
parent | 0221cd51543972782af558c527e4ac58b32049fa (diff) |
sch_red: generalize accurate MAX_P support to RED/GRED/CHOKE
Now RED uses a Q0.32 number to store max_p (max probability), allow
RED/GRED/CHOKE to use/report full resolution at config/dump time.
Old tc binaries are non aware of new attributes, and still set/get Plog.
New tc binary set/get both Plog and max_p for backward compatibility,
they display "probability value" if they get max_p from new kernels.
# tc -d qdisc show dev ...
...
qdisc red 10: parent 1:1 limit 360Kb min 30Kb max 90Kb ecn ewma 5
probability 0.09 Scell_log 15
Make sure we avoid potential divides by 0 in reciprocal_value(), if
(max_th - min_th) is big.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sched/sch_red.c')
-rw-r--r-- | net/sched/sch_red.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c index 8f5a85bf9d10..ce2256a17d7e 100644 --- a/net/sched/sch_red.c +++ b/net/sched/sch_red.c | |||
@@ -170,6 +170,7 @@ static void red_destroy(struct Qdisc *sch) | |||
170 | static const struct nla_policy red_policy[TCA_RED_MAX + 1] = { | 170 | static const struct nla_policy red_policy[TCA_RED_MAX + 1] = { |
171 | [TCA_RED_PARMS] = { .len = sizeof(struct tc_red_qopt) }, | 171 | [TCA_RED_PARMS] = { .len = sizeof(struct tc_red_qopt) }, |
172 | [TCA_RED_STAB] = { .len = RED_STAB_SIZE }, | 172 | [TCA_RED_STAB] = { .len = RED_STAB_SIZE }, |
173 | [TCA_RED_MAX_P] = { .type = NLA_U32 }, | ||
173 | }; | 174 | }; |
174 | 175 | ||
175 | static int red_change(struct Qdisc *sch, struct nlattr *opt) | 176 | static int red_change(struct Qdisc *sch, struct nlattr *opt) |
@@ -179,6 +180,7 @@ static int red_change(struct Qdisc *sch, struct nlattr *opt) | |||
179 | struct tc_red_qopt *ctl; | 180 | struct tc_red_qopt *ctl; |
180 | struct Qdisc *child = NULL; | 181 | struct Qdisc *child = NULL; |
181 | int err; | 182 | int err; |
183 | u32 max_P; | ||
182 | 184 | ||
183 | if (opt == NULL) | 185 | if (opt == NULL) |
184 | return -EINVAL; | 186 | return -EINVAL; |
@@ -191,6 +193,8 @@ static int red_change(struct Qdisc *sch, struct nlattr *opt) | |||
191 | tb[TCA_RED_STAB] == NULL) | 193 | tb[TCA_RED_STAB] == NULL) |
192 | return -EINVAL; | 194 | return -EINVAL; |
193 | 195 | ||
196 | max_P = tb[TCA_RED_MAX_P] ? nla_get_u32(tb[TCA_RED_MAX_P]) : 0; | ||
197 | |||
194 | ctl = nla_data(tb[TCA_RED_PARMS]); | 198 | ctl = nla_data(tb[TCA_RED_PARMS]); |
195 | 199 | ||
196 | if (ctl->limit > 0) { | 200 | if (ctl->limit > 0) { |
@@ -209,8 +213,9 @@ static int red_change(struct Qdisc *sch, struct nlattr *opt) | |||
209 | } | 213 | } |
210 | 214 | ||
211 | red_set_parms(&q->parms, ctl->qth_min, ctl->qth_max, ctl->Wlog, | 215 | red_set_parms(&q->parms, ctl->qth_min, ctl->qth_max, ctl->Wlog, |
212 | ctl->Plog, ctl->Scell_log, | 216 | ctl->Plog, ctl->Scell_log, |
213 | nla_data(tb[TCA_RED_STAB])); | 217 | nla_data(tb[TCA_RED_STAB]), |
218 | max_P); | ||
214 | 219 | ||
215 | del_timer(&q->adapt_timer); | 220 | del_timer(&q->adapt_timer); |
216 | if (ctl->flags & TC_RED_ADAPTATIVE) | 221 | if (ctl->flags & TC_RED_ADAPTATIVE) |