aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/sch_red.c
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2011-12-08 21:46:45 -0500
committerDavid S. Miller <davem@davemloft.net>2011-12-09 13:46:15 -0500
commita73ed26bbae7327370c5bd298f07de78df9e3466 (patch)
tree3c7a04e638261cdd16c324ecd07e303e72fac3b9 /net/sched/sch_red.c
parent0221cd51543972782af558c527e4ac58b32049fa (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.c9
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)
170static const struct nla_policy red_policy[TCA_RED_MAX + 1] = { 170static 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
175static int red_change(struct Qdisc *sch, struct nlattr *opt) 176static 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)