aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/cls_basic.c
diff options
context:
space:
mode:
authorCong Wang <xiyou.wangcong@gmail.com>2019-01-17 20:14:01 -0500
committerDavid S. Miller <davem@davemloft.net>2019-01-19 19:05:42 -0500
commit5954894ba3723995fbeab77bef62bb4878a654bb (patch)
tree7d65d45dbfc9d06dfe83f60b369c2699cea2aee3 /net/sched/cls_basic.c
parent0726f558d88ecc15b4dd461bdb2ac6bb763cadcb (diff)
net_sched: add performance counters for basic filter
Similar to u32 filter, it is useful to know how many times we reach each basic filter and how many times we pass the ematch attached to it. Sample output: filter protocol arp pref 49152 basic chain 0 filter protocol arp pref 49152 basic chain 0 handle 0x1 (rule hit 3 success 3) action order 1: gact action pass random type none pass val 0 index 1 ref 1 bind 1 installed 81 sec used 4 sec Action statistics: Sent 126 bytes 3 pkt (dropped 0, overlimits 0 requeues 0) backlog 0b 0p requeues 0 Cc: Jamal Hadi Salim <jhs@mojatatu.com> Cc: Jiri Pirko <jiri@resnulli.us> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sched/cls_basic.c')
-rw-r--r--net/sched/cls_basic.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c
index 6a5dce8baf19..4a57fec6f306 100644
--- a/net/sched/cls_basic.c
+++ b/net/sched/cls_basic.c
@@ -18,6 +18,7 @@
18#include <linux/rtnetlink.h> 18#include <linux/rtnetlink.h>
19#include <linux/skbuff.h> 19#include <linux/skbuff.h>
20#include <linux/idr.h> 20#include <linux/idr.h>
21#include <linux/percpu.h>
21#include <net/netlink.h> 22#include <net/netlink.h>
22#include <net/act_api.h> 23#include <net/act_api.h>
23#include <net/pkt_cls.h> 24#include <net/pkt_cls.h>
@@ -35,6 +36,7 @@ struct basic_filter {
35 struct tcf_result res; 36 struct tcf_result res;
36 struct tcf_proto *tp; 37 struct tcf_proto *tp;
37 struct list_head link; 38 struct list_head link;
39 struct tc_basic_pcnt __percpu *pf;
38 struct rcu_work rwork; 40 struct rcu_work rwork;
39}; 41};
40 42
@@ -46,8 +48,10 @@ static int basic_classify(struct sk_buff *skb, const struct tcf_proto *tp,
46 struct basic_filter *f; 48 struct basic_filter *f;
47 49
48 list_for_each_entry_rcu(f, &head->flist, link) { 50 list_for_each_entry_rcu(f, &head->flist, link) {
51 __this_cpu_inc(f->pf->rcnt);
49 if (!tcf_em_tree_match(skb, &f->ematches, NULL)) 52 if (!tcf_em_tree_match(skb, &f->ematches, NULL))
50 continue; 53 continue;
54 __this_cpu_inc(f->pf->rhit);
51 *res = f->res; 55 *res = f->res;
52 r = tcf_exts_exec(skb, &f->exts, res); 56 r = tcf_exts_exec(skb, &f->exts, res);
53 if (r < 0) 57 if (r < 0)
@@ -89,6 +93,7 @@ static void __basic_delete_filter(struct basic_filter *f)
89 tcf_exts_destroy(&f->exts); 93 tcf_exts_destroy(&f->exts);
90 tcf_em_tree_destroy(&f->ematches); 94 tcf_em_tree_destroy(&f->ematches);
91 tcf_exts_put_net(&f->exts); 95 tcf_exts_put_net(&f->exts);
96 free_percpu(f->pf);
92 kfree(f); 97 kfree(f);
93} 98}
94 99
@@ -208,6 +213,11 @@ static int basic_change(struct net *net, struct sk_buff *in_skb,
208 if (err) 213 if (err)
209 goto errout; 214 goto errout;
210 fnew->handle = handle; 215 fnew->handle = handle;
216 fnew->pf = alloc_percpu(struct tc_basic_pcnt);
217 if (!fnew->pf) {
218 err = -ENOMEM;
219 goto errout;
220 }
211 221
212 err = basic_set_parms(net, tp, fnew, base, tb, tca[TCA_RATE], ovr, 222 err = basic_set_parms(net, tp, fnew, base, tb, tca[TCA_RATE], ovr,
213 extack); 223 extack);
@@ -231,6 +241,7 @@ static int basic_change(struct net *net, struct sk_buff *in_skb,
231 241
232 return 0; 242 return 0;
233errout: 243errout:
244 free_percpu(fnew->pf);
234 tcf_exts_destroy(&fnew->exts); 245 tcf_exts_destroy(&fnew->exts);
235 kfree(fnew); 246 kfree(fnew);
236 return err; 247 return err;
@@ -265,8 +276,10 @@ static void basic_bind_class(void *fh, u32 classid, unsigned long cl)
265static int basic_dump(struct net *net, struct tcf_proto *tp, void *fh, 276static int basic_dump(struct net *net, struct tcf_proto *tp, void *fh,
266 struct sk_buff *skb, struct tcmsg *t) 277 struct sk_buff *skb, struct tcmsg *t)
267{ 278{
279 struct tc_basic_pcnt gpf = {};
268 struct basic_filter *f = fh; 280 struct basic_filter *f = fh;
269 struct nlattr *nest; 281 struct nlattr *nest;
282 int cpu;
270 283
271 if (f == NULL) 284 if (f == NULL)
272 return skb->len; 285 return skb->len;
@@ -281,6 +294,18 @@ static int basic_dump(struct net *net, struct tcf_proto *tp, void *fh,
281 nla_put_u32(skb, TCA_BASIC_CLASSID, f->res.classid)) 294 nla_put_u32(skb, TCA_BASIC_CLASSID, f->res.classid))
282 goto nla_put_failure; 295 goto nla_put_failure;
283 296
297 for_each_possible_cpu(cpu) {
298 struct tc_basic_pcnt *pf = per_cpu_ptr(f->pf, cpu);
299
300 gpf.rcnt += pf->rcnt;
301 gpf.rhit += pf->rhit;
302 }
303
304 if (nla_put_64bit(skb, TCA_BASIC_PCNT,
305 sizeof(struct tc_basic_pcnt),
306 &gpf, TCA_BASIC_PAD))
307 goto nla_put_failure;
308
284 if (tcf_exts_dump(skb, &f->exts) < 0 || 309 if (tcf_exts_dump(skb, &f->exts) < 0 ||
285 tcf_em_tree_dump(skb, &f->ematches, TCA_BASIC_EMATCHES) < 0) 310 tcf_em_tree_dump(skb, &f->ematches, TCA_BASIC_EMATCHES) < 0)
286 goto nla_put_failure; 311 goto nla_put_failure;