Commit 3e1e3aae authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller

net_sched: add u64 rate to psched_ratecfg_precompute()

Add an extra u64 rate parameter to psched_ratecfg_precompute()
so that some qdisc can opt-in for 64bit rates in the future,
to overcome the ~34 Gbits limit.

psched_ratecfg_getrate() reports a legacy structure to
tc utility, so if actual rate is above the 32bit rate field,
cap it to the 34Gbit limit.
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 118a7b0e
...@@ -702,13 +702,20 @@ static inline u64 psched_l2t_ns(const struct psched_ratecfg *r, ...@@ -702,13 +702,20 @@ static inline u64 psched_l2t_ns(const struct psched_ratecfg *r,
} }
void psched_ratecfg_precompute(struct psched_ratecfg *r, void psched_ratecfg_precompute(struct psched_ratecfg *r,
const struct tc_ratespec *conf); const struct tc_ratespec *conf,
u64 rate64);
static inline void psched_ratecfg_getrate(struct tc_ratespec *res, static inline void psched_ratecfg_getrate(struct tc_ratespec *res,
const struct psched_ratecfg *r) const struct psched_ratecfg *r)
{ {
memset(res, 0, sizeof(*res)); memset(res, 0, sizeof(*res));
res->rate = r->rate_bytes_ps;
/* legacy struct tc_ratespec has a 32bit @rate field
* Qdisc using 64bit rate should add new attributes
* in order to maintain compatibility.
*/
res->rate = min_t(u64, r->rate_bytes_ps, ~0U);
res->overhead = r->overhead; res->overhead = r->overhead;
res->linklayer = (r->linklayer & TC_LINKLAYER_MASK); res->linklayer = (r->linklayer & TC_LINKLAYER_MASK);
} }
......
...@@ -231,14 +231,14 @@ static int tcf_act_police_locate(struct net *net, struct nlattr *nla, ...@@ -231,14 +231,14 @@ static int tcf_act_police_locate(struct net *net, struct nlattr *nla,
} }
if (R_tab) { if (R_tab) {
police->rate_present = true; police->rate_present = true;
psched_ratecfg_precompute(&police->rate, &R_tab->rate); psched_ratecfg_precompute(&police->rate, &R_tab->rate, 0);
qdisc_put_rtab(R_tab); qdisc_put_rtab(R_tab);
} else { } else {
police->rate_present = false; police->rate_present = false;
} }
if (P_tab) { if (P_tab) {
police->peak_present = true; police->peak_present = true;
psched_ratecfg_precompute(&police->peak, &P_tab->rate); psched_ratecfg_precompute(&police->peak, &P_tab->rate, 0);
qdisc_put_rtab(P_tab); qdisc_put_rtab(P_tab);
} else { } else {
police->peak_present = false; police->peak_present = false;
......
...@@ -910,11 +910,12 @@ void dev_shutdown(struct net_device *dev) ...@@ -910,11 +910,12 @@ void dev_shutdown(struct net_device *dev)
} }
void psched_ratecfg_precompute(struct psched_ratecfg *r, void psched_ratecfg_precompute(struct psched_ratecfg *r,
const struct tc_ratespec *conf) const struct tc_ratespec *conf,
u64 rate64)
{ {
memset(r, 0, sizeof(*r)); memset(r, 0, sizeof(*r));
r->overhead = conf->overhead; r->overhead = conf->overhead;
r->rate_bytes_ps = conf->rate; r->rate_bytes_ps = max_t(u64, conf->rate, rate64);
r->linklayer = (conf->linklayer & TC_LINKLAYER_MASK); r->linklayer = (conf->linklayer & TC_LINKLAYER_MASK);
r->mult = 1; r->mult = 1;
/* /*
......
...@@ -1491,8 +1491,8 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, ...@@ -1491,8 +1491,8 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
cl->prio = TC_HTB_NUMPRIO - 1; cl->prio = TC_HTB_NUMPRIO - 1;
} }
psched_ratecfg_precompute(&cl->rate, &hopt->rate); psched_ratecfg_precompute(&cl->rate, &hopt->rate, 0);
psched_ratecfg_precompute(&cl->ceil, &hopt->ceil); psched_ratecfg_precompute(&cl->ceil, &hopt->ceil, 0);
cl->buffer = PSCHED_TICKS2NS(hopt->buffer); cl->buffer = PSCHED_TICKS2NS(hopt->buffer);
cl->cbuffer = PSCHED_TICKS2NS(hopt->cbuffer); cl->cbuffer = PSCHED_TICKS2NS(hopt->cbuffer);
......
...@@ -341,9 +341,9 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt) ...@@ -341,9 +341,9 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt)
q->tokens = q->buffer; q->tokens = q->buffer;
q->ptokens = q->mtu; q->ptokens = q->mtu;
psched_ratecfg_precompute(&q->rate, &rtab->rate); psched_ratecfg_precompute(&q->rate, &rtab->rate, 0);
if (ptab) { if (ptab) {
psched_ratecfg_precompute(&q->peak, &ptab->rate); psched_ratecfg_precompute(&q->peak, &ptab->rate, 0);
q->peak_present = true; q->peak_present = true;
} else { } else {
q->peak_present = false; q->peak_present = false;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment