mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 11:11:45 -04:00
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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
This commit is contained in:
parent
0221cd5154
commit
a73ed26bba
5 changed files with 45 additions and 12 deletions
|
|
@ -394,6 +394,7 @@ static void choke_reset(struct Qdisc *sch)
|
|||
static const struct nla_policy choke_policy[TCA_CHOKE_MAX + 1] = {
|
||||
[TCA_CHOKE_PARMS] = { .len = sizeof(struct tc_red_qopt) },
|
||||
[TCA_CHOKE_STAB] = { .len = RED_STAB_SIZE },
|
||||
[TCA_CHOKE_MAX_P] = { .type = NLA_U32 },
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -415,6 +416,7 @@ static int choke_change(struct Qdisc *sch, struct nlattr *opt)
|
|||
int err;
|
||||
struct sk_buff **old = NULL;
|
||||
unsigned int mask;
|
||||
u32 max_P;
|
||||
|
||||
if (opt == NULL)
|
||||
return -EINVAL;
|
||||
|
|
@ -427,6 +429,8 @@ static int choke_change(struct Qdisc *sch, struct nlattr *opt)
|
|||
tb[TCA_CHOKE_STAB] == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
max_P = tb[TCA_CHOKE_MAX_P] ? nla_get_u32(tb[TCA_CHOKE_MAX_P]) : 0;
|
||||
|
||||
ctl = nla_data(tb[TCA_CHOKE_PARMS]);
|
||||
|
||||
if (ctl->limit > CHOKE_MAX_QUEUE)
|
||||
|
|
@ -476,7 +480,8 @@ static int choke_change(struct Qdisc *sch, struct nlattr *opt)
|
|||
|
||||
red_set_parms(&q->parms, ctl->qth_min, ctl->qth_max, ctl->Wlog,
|
||||
ctl->Plog, ctl->Scell_log,
|
||||
nla_data(tb[TCA_CHOKE_STAB]));
|
||||
nla_data(tb[TCA_CHOKE_STAB]),
|
||||
max_P);
|
||||
|
||||
if (q->head == q->tail)
|
||||
red_end_of_idle_period(&q->parms);
|
||||
|
|
@ -510,6 +515,7 @@ static int choke_dump(struct Qdisc *sch, struct sk_buff *skb)
|
|||
goto nla_put_failure;
|
||||
|
||||
NLA_PUT(skb, TCA_CHOKE_PARMS, sizeof(opt), &opt);
|
||||
NLA_PUT_U32(skb, TCA_CHOKE_MAX_P, q->parms.max_P);
|
||||
return nla_nest_end(skb, opts);
|
||||
|
||||
nla_put_failure:
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ struct gred_sched;
|
|||
|
||||
struct gred_sched_data {
|
||||
u32 limit; /* HARD maximal queue length */
|
||||
u32 DP; /* the drop pramaters */
|
||||
u32 DP; /* the drop parameters */
|
||||
u32 bytesin; /* bytes seen on virtualQ so far*/
|
||||
u32 packetsin; /* packets seen on virtualQ so far*/
|
||||
u32 backlog; /* bytes on the virtualQ */
|
||||
|
|
@ -379,7 +379,8 @@ static inline int gred_change_table_def(struct Qdisc *sch, struct nlattr *dps)
|
|||
}
|
||||
|
||||
static inline int gred_change_vq(struct Qdisc *sch, int dp,
|
||||
struct tc_gred_qopt *ctl, int prio, u8 *stab)
|
||||
struct tc_gred_qopt *ctl, int prio,
|
||||
u8 *stab, u32 max_P)
|
||||
{
|
||||
struct gred_sched *table = qdisc_priv(sch);
|
||||
struct gred_sched_data *q;
|
||||
|
|
@ -400,7 +401,7 @@ static inline int gred_change_vq(struct Qdisc *sch, int dp,
|
|||
|
||||
red_set_parms(&q->parms,
|
||||
ctl->qth_min, ctl->qth_max, ctl->Wlog, ctl->Plog,
|
||||
ctl->Scell_log, stab);
|
||||
ctl->Scell_log, stab, max_P);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -409,6 +410,7 @@ static const struct nla_policy gred_policy[TCA_GRED_MAX + 1] = {
|
|||
[TCA_GRED_PARMS] = { .len = sizeof(struct tc_gred_qopt) },
|
||||
[TCA_GRED_STAB] = { .len = 256 },
|
||||
[TCA_GRED_DPS] = { .len = sizeof(struct tc_gred_sopt) },
|
||||
[TCA_GRED_MAX_P] = { .type = NLA_U32 },
|
||||
};
|
||||
|
||||
static int gred_change(struct Qdisc *sch, struct nlattr *opt)
|
||||
|
|
@ -418,6 +420,7 @@ static int gred_change(struct Qdisc *sch, struct nlattr *opt)
|
|||
struct nlattr *tb[TCA_GRED_MAX + 1];
|
||||
int err, prio = GRED_DEF_PRIO;
|
||||
u8 *stab;
|
||||
u32 max_P;
|
||||
|
||||
if (opt == NULL)
|
||||
return -EINVAL;
|
||||
|
|
@ -433,6 +436,8 @@ static int gred_change(struct Qdisc *sch, struct nlattr *opt)
|
|||
tb[TCA_GRED_STAB] == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
max_P = tb[TCA_GRED_MAX_P] ? nla_get_u32(tb[TCA_GRED_MAX_P]) : 0;
|
||||
|
||||
err = -EINVAL;
|
||||
ctl = nla_data(tb[TCA_GRED_PARMS]);
|
||||
stab = nla_data(tb[TCA_GRED_STAB]);
|
||||
|
|
@ -457,7 +462,7 @@ static int gred_change(struct Qdisc *sch, struct nlattr *opt)
|
|||
|
||||
sch_tree_lock(sch);
|
||||
|
||||
err = gred_change_vq(sch, ctl->DP, ctl, prio, stab);
|
||||
err = gred_change_vq(sch, ctl->DP, ctl, prio, stab, max_P);
|
||||
if (err < 0)
|
||||
goto errout_locked;
|
||||
|
||||
|
|
@ -498,6 +503,7 @@ static int gred_dump(struct Qdisc *sch, struct sk_buff *skb)
|
|||
struct gred_sched *table = qdisc_priv(sch);
|
||||
struct nlattr *parms, *opts = NULL;
|
||||
int i;
|
||||
u32 max_p[MAX_DPs];
|
||||
struct tc_gred_sopt sopt = {
|
||||
.DPs = table->DPs,
|
||||
.def_DP = table->def,
|
||||
|
|
@ -509,6 +515,14 @@ static int gred_dump(struct Qdisc *sch, struct sk_buff *skb)
|
|||
if (opts == NULL)
|
||||
goto nla_put_failure;
|
||||
NLA_PUT(skb, TCA_GRED_DPS, sizeof(sopt), &sopt);
|
||||
|
||||
for (i = 0; i < MAX_DPs; i++) {
|
||||
struct gred_sched_data *q = table->tab[i];
|
||||
|
||||
max_p[i] = q ? q->parms.max_P : 0;
|
||||
}
|
||||
NLA_PUT(skb, TCA_GRED_MAX_P, sizeof(max_p), max_p);
|
||||
|
||||
parms = nla_nest_start(skb, TCA_GRED_PARMS);
|
||||
if (parms == NULL)
|
||||
goto nla_put_failure;
|
||||
|
|
|
|||
|
|
@ -170,6 +170,7 @@ static void red_destroy(struct Qdisc *sch)
|
|||
static const struct nla_policy red_policy[TCA_RED_MAX + 1] = {
|
||||
[TCA_RED_PARMS] = { .len = sizeof(struct tc_red_qopt) },
|
||||
[TCA_RED_STAB] = { .len = RED_STAB_SIZE },
|
||||
[TCA_RED_MAX_P] = { .type = NLA_U32 },
|
||||
};
|
||||
|
||||
static int red_change(struct Qdisc *sch, struct nlattr *opt)
|
||||
|
|
@ -179,6 +180,7 @@ static int red_change(struct Qdisc *sch, struct nlattr *opt)
|
|||
struct tc_red_qopt *ctl;
|
||||
struct Qdisc *child = NULL;
|
||||
int err;
|
||||
u32 max_P;
|
||||
|
||||
if (opt == NULL)
|
||||
return -EINVAL;
|
||||
|
|
@ -191,6 +193,8 @@ static int red_change(struct Qdisc *sch, struct nlattr *opt)
|
|||
tb[TCA_RED_STAB] == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
max_P = tb[TCA_RED_MAX_P] ? nla_get_u32(tb[TCA_RED_MAX_P]) : 0;
|
||||
|
||||
ctl = nla_data(tb[TCA_RED_PARMS]);
|
||||
|
||||
if (ctl->limit > 0) {
|
||||
|
|
@ -209,8 +213,9 @@ static int red_change(struct Qdisc *sch, struct nlattr *opt)
|
|||
}
|
||||
|
||||
red_set_parms(&q->parms, ctl->qth_min, ctl->qth_max, ctl->Wlog,
|
||||
ctl->Plog, ctl->Scell_log,
|
||||
nla_data(tb[TCA_RED_STAB]));
|
||||
ctl->Plog, ctl->Scell_log,
|
||||
nla_data(tb[TCA_RED_STAB]),
|
||||
max_P);
|
||||
|
||||
del_timer(&q->adapt_timer);
|
||||
if (ctl->flags & TC_RED_ADAPTATIVE)
|
||||
|
|
|
|||
Loading…
Reference in a new issue