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_gred.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_gred.c')
-rw-r--r-- | net/sched/sch_gred.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c index b9493a09a870..a1b7407ac2a4 100644 --- a/net/sched/sch_gred.c +++ b/net/sched/sch_gred.c | |||
@@ -34,7 +34,7 @@ struct gred_sched; | |||
34 | 34 | ||
35 | struct gred_sched_data { | 35 | struct gred_sched_data { |
36 | u32 limit; /* HARD maximal queue length */ | 36 | u32 limit; /* HARD maximal queue length */ |
37 | u32 DP; /* the drop pramaters */ | 37 | u32 DP; /* the drop parameters */ |
38 | u32 bytesin; /* bytes seen on virtualQ so far*/ | 38 | u32 bytesin; /* bytes seen on virtualQ so far*/ |
39 | u32 packetsin; /* packets seen on virtualQ so far*/ | 39 | u32 packetsin; /* packets seen on virtualQ so far*/ |
40 | u32 backlog; /* bytes on the virtualQ */ | 40 | u32 backlog; /* bytes on the virtualQ */ |
@@ -379,7 +379,8 @@ static inline int gred_change_table_def(struct Qdisc *sch, struct nlattr *dps) | |||
379 | } | 379 | } |
380 | 380 | ||
381 | static inline int gred_change_vq(struct Qdisc *sch, int dp, | 381 | static inline int gred_change_vq(struct Qdisc *sch, int dp, |
382 | struct tc_gred_qopt *ctl, int prio, u8 *stab) | 382 | struct tc_gred_qopt *ctl, int prio, |
383 | u8 *stab, u32 max_P) | ||
383 | { | 384 | { |
384 | struct gred_sched *table = qdisc_priv(sch); | 385 | struct gred_sched *table = qdisc_priv(sch); |
385 | struct gred_sched_data *q; | 386 | struct gred_sched_data *q; |
@@ -400,7 +401,7 @@ static inline int gred_change_vq(struct Qdisc *sch, int dp, | |||
400 | 401 | ||
401 | red_set_parms(&q->parms, | 402 | red_set_parms(&q->parms, |
402 | ctl->qth_min, ctl->qth_max, ctl->Wlog, ctl->Plog, | 403 | ctl->qth_min, ctl->qth_max, ctl->Wlog, ctl->Plog, |
403 | ctl->Scell_log, stab); | 404 | ctl->Scell_log, stab, max_P); |
404 | 405 | ||
405 | return 0; | 406 | return 0; |
406 | } | 407 | } |
@@ -409,6 +410,7 @@ static const struct nla_policy gred_policy[TCA_GRED_MAX + 1] = { | |||
409 | [TCA_GRED_PARMS] = { .len = sizeof(struct tc_gred_qopt) }, | 410 | [TCA_GRED_PARMS] = { .len = sizeof(struct tc_gred_qopt) }, |
410 | [TCA_GRED_STAB] = { .len = 256 }, | 411 | [TCA_GRED_STAB] = { .len = 256 }, |
411 | [TCA_GRED_DPS] = { .len = sizeof(struct tc_gred_sopt) }, | 412 | [TCA_GRED_DPS] = { .len = sizeof(struct tc_gred_sopt) }, |
413 | [TCA_GRED_MAX_P] = { .type = NLA_U32 }, | ||
412 | }; | 414 | }; |
413 | 415 | ||
414 | static int gred_change(struct Qdisc *sch, struct nlattr *opt) | 416 | static int gred_change(struct Qdisc *sch, struct nlattr *opt) |
@@ -418,6 +420,7 @@ static int gred_change(struct Qdisc *sch, struct nlattr *opt) | |||
418 | struct nlattr *tb[TCA_GRED_MAX + 1]; | 420 | struct nlattr *tb[TCA_GRED_MAX + 1]; |
419 | int err, prio = GRED_DEF_PRIO; | 421 | int err, prio = GRED_DEF_PRIO; |
420 | u8 *stab; | 422 | u8 *stab; |
423 | u32 max_P; | ||
421 | 424 | ||
422 | if (opt == NULL) | 425 | if (opt == NULL) |
423 | return -EINVAL; | 426 | return -EINVAL; |
@@ -433,6 +436,8 @@ static int gred_change(struct Qdisc *sch, struct nlattr *opt) | |||
433 | tb[TCA_GRED_STAB] == NULL) | 436 | tb[TCA_GRED_STAB] == NULL) |
434 | return -EINVAL; | 437 | return -EINVAL; |
435 | 438 | ||
439 | max_P = tb[TCA_GRED_MAX_P] ? nla_get_u32(tb[TCA_GRED_MAX_P]) : 0; | ||
440 | |||
436 | err = -EINVAL; | 441 | err = -EINVAL; |
437 | ctl = nla_data(tb[TCA_GRED_PARMS]); | 442 | ctl = nla_data(tb[TCA_GRED_PARMS]); |
438 | stab = nla_data(tb[TCA_GRED_STAB]); | 443 | stab = nla_data(tb[TCA_GRED_STAB]); |
@@ -457,7 +462,7 @@ static int gred_change(struct Qdisc *sch, struct nlattr *opt) | |||
457 | 462 | ||
458 | sch_tree_lock(sch); | 463 | sch_tree_lock(sch); |
459 | 464 | ||
460 | err = gred_change_vq(sch, ctl->DP, ctl, prio, stab); | 465 | err = gred_change_vq(sch, ctl->DP, ctl, prio, stab, max_P); |
461 | if (err < 0) | 466 | if (err < 0) |
462 | goto errout_locked; | 467 | goto errout_locked; |
463 | 468 | ||
@@ -498,6 +503,7 @@ static int gred_dump(struct Qdisc *sch, struct sk_buff *skb) | |||
498 | struct gred_sched *table = qdisc_priv(sch); | 503 | struct gred_sched *table = qdisc_priv(sch); |
499 | struct nlattr *parms, *opts = NULL; | 504 | struct nlattr *parms, *opts = NULL; |
500 | int i; | 505 | int i; |
506 | u32 max_p[MAX_DPs]; | ||
501 | struct tc_gred_sopt sopt = { | 507 | struct tc_gred_sopt sopt = { |
502 | .DPs = table->DPs, | 508 | .DPs = table->DPs, |
503 | .def_DP = table->def, | 509 | .def_DP = table->def, |
@@ -509,6 +515,14 @@ static int gred_dump(struct Qdisc *sch, struct sk_buff *skb) | |||
509 | if (opts == NULL) | 515 | if (opts == NULL) |
510 | goto nla_put_failure; | 516 | goto nla_put_failure; |
511 | NLA_PUT(skb, TCA_GRED_DPS, sizeof(sopt), &sopt); | 517 | NLA_PUT(skb, TCA_GRED_DPS, sizeof(sopt), &sopt); |
518 | |||
519 | for (i = 0; i < MAX_DPs; i++) { | ||
520 | struct gred_sched_data *q = table->tab[i]; | ||
521 | |||
522 | max_p[i] = q ? q->parms.max_P : 0; | ||
523 | } | ||
524 | NLA_PUT(skb, TCA_GRED_MAX_P, sizeof(max_p), max_p); | ||
525 | |||
512 | parms = nla_nest_start(skb, TCA_GRED_PARMS); | 526 | parms = nla_nest_start(skb, TCA_GRED_PARMS); |
513 | if (parms == NULL) | 527 | if (parms == NULL) |
514 | goto nla_put_failure; | 528 | goto nla_put_failure; |