Commit d1967e49 authored by David Dai's avatar David Dai Committed by David S. Miller

net_sched: act_police: add 2 new attributes to support police 64bit rate and peakrate

For high speed adapter like Mellanox CX-5 card, it can reach upto
100 Gbits per second bandwidth. Currently htb already supports 64bit rate
in tc utility. However police action rate and peakrate are still limited
to 32bit value (upto 32 Gbits per second). Add 2 new attributes
TCA_POLICE_RATE64 and TCA_POLICE_RATE64 in kernel for 64bit support
so that tc utility can use them for 64bit rate and peakrate value to
break the 32bit limit, and still keep the backward binary compatibility.
Tested-by: default avatarDavid Dai <zdai@linux.vnet.ibm.com>
Signed-off-by: default avatarDavid Dai <zdai@linux.vnet.ibm.com>
Acked-by: default avatarCong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 95a7233c
...@@ -160,6 +160,8 @@ enum { ...@@ -160,6 +160,8 @@ enum {
TCA_POLICE_RESULT, TCA_POLICE_RESULT,
TCA_POLICE_TM, TCA_POLICE_TM,
TCA_POLICE_PAD, TCA_POLICE_PAD,
TCA_POLICE_RATE64,
TCA_POLICE_PEAKRATE64,
__TCA_POLICE_MAX __TCA_POLICE_MAX
#define TCA_POLICE_RESULT TCA_POLICE_RESULT #define TCA_POLICE_RESULT TCA_POLICE_RESULT
}; };
......
...@@ -40,6 +40,8 @@ static const struct nla_policy police_policy[TCA_POLICE_MAX + 1] = { ...@@ -40,6 +40,8 @@ static const struct nla_policy police_policy[TCA_POLICE_MAX + 1] = {
[TCA_POLICE_PEAKRATE] = { .len = TC_RTAB_SIZE }, [TCA_POLICE_PEAKRATE] = { .len = TC_RTAB_SIZE },
[TCA_POLICE_AVRATE] = { .type = NLA_U32 }, [TCA_POLICE_AVRATE] = { .type = NLA_U32 },
[TCA_POLICE_RESULT] = { .type = NLA_U32 }, [TCA_POLICE_RESULT] = { .type = NLA_U32 },
[TCA_POLICE_RATE64] = { .type = NLA_U64 },
[TCA_POLICE_PEAKRATE64] = { .type = NLA_U64 },
}; };
static int tcf_police_init(struct net *net, struct nlattr *nla, static int tcf_police_init(struct net *net, struct nlattr *nla,
...@@ -58,6 +60,7 @@ static int tcf_police_init(struct net *net, struct nlattr *nla, ...@@ -58,6 +60,7 @@ static int tcf_police_init(struct net *net, struct nlattr *nla,
struct tcf_police_params *new; struct tcf_police_params *new;
bool exists = false; bool exists = false;
u32 index; u32 index;
u64 rate64, prate64;
if (nla == NULL) if (nla == NULL)
return -EINVAL; return -EINVAL;
...@@ -155,14 +158,18 @@ static int tcf_police_init(struct net *net, struct nlattr *nla, ...@@ -155,14 +158,18 @@ static int tcf_police_init(struct net *net, struct nlattr *nla,
} }
if (R_tab) { if (R_tab) {
new->rate_present = true; new->rate_present = true;
psched_ratecfg_precompute(&new->rate, &R_tab->rate, 0); rate64 = tb[TCA_POLICE_RATE64] ?
nla_get_u64(tb[TCA_POLICE_RATE64]) : 0;
psched_ratecfg_precompute(&new->rate, &R_tab->rate, rate64);
qdisc_put_rtab(R_tab); qdisc_put_rtab(R_tab);
} else { } else {
new->rate_present = false; new->rate_present = false;
} }
if (P_tab) { if (P_tab) {
new->peak_present = true; new->peak_present = true;
psched_ratecfg_precompute(&new->peak, &P_tab->rate, 0); prate64 = tb[TCA_POLICE_PEAKRATE64] ?
nla_get_u64(tb[TCA_POLICE_PEAKRATE64]) : 0;
psched_ratecfg_precompute(&new->peak, &P_tab->rate, prate64);
qdisc_put_rtab(P_tab); qdisc_put_rtab(P_tab);
} else { } else {
new->peak_present = false; new->peak_present = false;
...@@ -313,10 +320,22 @@ static int tcf_police_dump(struct sk_buff *skb, struct tc_action *a, ...@@ -313,10 +320,22 @@ static int tcf_police_dump(struct sk_buff *skb, struct tc_action *a,
lockdep_is_held(&police->tcf_lock)); lockdep_is_held(&police->tcf_lock));
opt.mtu = p->tcfp_mtu; opt.mtu = p->tcfp_mtu;
opt.burst = PSCHED_NS2TICKS(p->tcfp_burst); opt.burst = PSCHED_NS2TICKS(p->tcfp_burst);
if (p->rate_present) if (p->rate_present) {
psched_ratecfg_getrate(&opt.rate, &p->rate); psched_ratecfg_getrate(&opt.rate, &p->rate);
if (p->peak_present) if ((police->params->rate.rate_bytes_ps >= (1ULL << 32)) &&
nla_put_u64_64bit(skb, TCA_POLICE_RATE64,
police->params->rate.rate_bytes_ps,
TCA_POLICE_PAD))
goto nla_put_failure;
}
if (p->peak_present) {
psched_ratecfg_getrate(&opt.peakrate, &p->peak); psched_ratecfg_getrate(&opt.peakrate, &p->peak);
if ((police->params->peak.rate_bytes_ps >= (1ULL << 32)) &&
nla_put_u64_64bit(skb, TCA_POLICE_PEAKRATE64,
police->params->peak.rate_bytes_ps,
TCA_POLICE_PAD))
goto nla_put_failure;
}
if (nla_put(skb, TCA_POLICE_TBF, sizeof(opt), &opt)) if (nla_put(skb, TCA_POLICE_TBF, sizeof(opt), &opt))
goto nla_put_failure; goto nla_put_failure;
if (p->tcfp_result && if (p->tcfp_result &&
......
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