net_sched: act_police: add 2 new attributes to support police 64bit rate and peakrate
authorDavid Dai <zdai@linux.vnet.ibm.com>
Wed, 4 Sep 2019 15:03:43 +0000 (10:03 -0500)
committerDavid S. Miller <davem@davemloft.net>
Fri, 6 Sep 2019 13:02:16 +0000 (15:02 +0200)
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: David Dai <zdai@linux.vnet.ibm.com>
Signed-off-by: David Dai <zdai@linux.vnet.ibm.com>
Acked-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/uapi/linux/pkt_cls.h
net/sched/act_police.c

index b057aeeb63386442d0e1e8d91321adddc69b4e79..a6aa466fac9e85b2acde80d21ff1e00db89169f6 100644 (file)
@@ -160,6 +160,8 @@ enum {
        TCA_POLICE_RESULT,
        TCA_POLICE_TM,
        TCA_POLICE_PAD,
+       TCA_POLICE_RATE64,
+       TCA_POLICE_PEAKRATE64,
        __TCA_POLICE_MAX
 #define TCA_POLICE_RESULT TCA_POLICE_RESULT
 };
index 6315e0f8d26e3abfb96101bec5f9048db9619c21..89c04c52af3dab3d7fc1fbd1d08a3f112c33ac72 100644 (file)
@@ -40,6 +40,8 @@ static const struct nla_policy police_policy[TCA_POLICE_MAX + 1] = {
        [TCA_POLICE_PEAKRATE]   = { .len = TC_RTAB_SIZE },
        [TCA_POLICE_AVRATE]     = { .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,
@@ -58,6 +60,7 @@ static int tcf_police_init(struct net *net, struct nlattr *nla,
        struct tcf_police_params *new;
        bool exists = false;
        u32 index;
+       u64 rate64, prate64;
 
        if (nla == NULL)
                return -EINVAL;
@@ -155,14 +158,18 @@ static int tcf_police_init(struct net *net, struct nlattr *nla,
        }
        if (R_tab) {
                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);
        } else {
                new->rate_present = false;
        }
        if (P_tab) {
                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);
        } else {
                new->peak_present = false;
@@ -313,10 +320,22 @@ static int tcf_police_dump(struct sk_buff *skb, struct tc_action *a,
                                      lockdep_is_held(&police->tcf_lock));
        opt.mtu = p->tcfp_mtu;
        opt.burst = PSCHED_NS2TICKS(p->tcfp_burst);
-       if (p->rate_present)
+       if (p->rate_present) {
                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);
+               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))
                goto nla_put_failure;
        if (p->tcfp_result &&