aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/sch_gred.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_gred.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_gred.c')
-rw-r--r--net/sched/sch_gred.c22
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
35struct gred_sched_data { 35struct 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
381static inline int gred_change_vq(struct Qdisc *sch, int dp, 381static 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
414static int gred_change(struct Qdisc *sch, struct nlattr *opt) 416static 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;