From 990a71e904f6ec2d7d84eecb37e5127b75721985 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 14 Mar 2023 16:42:28 -0700 Subject: perf bpf filter: Introduce basic BPF filter expression This implements a tiny parser for the filter expressions used for BPF. Each expression will be converted to struct perf_bpf_filter_expr and be passed to a BPF map. For now, I'd like to start with the very basic comparisons like EQ or GT. The LHS should be a term for sample data and the RHS is a number. The expressions are connected by a comma. For example, period > 10000 ip < 0x1000000000000, cpu == 3 Signed-off-by: Namhyung Kim Acked-by: Jiri Olsa Cc: Adrian Hunter Cc: Andi Kleen Cc: Hao Luo Cc: Ian Rogers Cc: Ingo Molnar Cc: James Clark Cc: Kan Liang Cc: Leo Yan Cc: Peter Zijlstra Cc: Ravi Bangoria Cc: Song Liu Cc: Stephane Eranian Cc: bpf@vger.kernel.org Link: https://lore.kernel.org/r/20230314234237.3008956-2-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/bpf-filter.l | 82 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 tools/perf/util/bpf-filter.l (limited to 'tools/perf/util/bpf-filter.l') diff --git a/tools/perf/util/bpf-filter.l b/tools/perf/util/bpf-filter.l new file mode 100644 index 000000000000..f6c0b74ea285 --- /dev/null +++ b/tools/perf/util/bpf-filter.l @@ -0,0 +1,82 @@ +%option prefix="perf_bpf_filter_" +%option noyywrap + +%{ +#include +#include +#include + +#include "bpf-filter.h" +#include "bpf-filter-bison.h" + +static int sample(unsigned long sample_flag) +{ + perf_bpf_filter_lval.sample = sample_flag; + return BFT_SAMPLE; +} + +static int operator(enum perf_bpf_filter_op op) +{ + perf_bpf_filter_lval.op = op; + return BFT_OP; +} + +static int value(int base) +{ + long num; + + errno = 0; + num = strtoul(perf_bpf_filter_text, NULL, base); + if (errno) + return BFT_ERROR; + + perf_bpf_filter_lval.num = num; + return BFT_NUM; +} + +static int error(const char *str) +{ + printf("perf_bpf_filter: Unexpected filter %s: %s\n", str, perf_bpf_filter_text); + return BFT_ERROR; +} + +%} + +num_dec [0-9]+ +num_hex 0[Xx][0-9a-fA-F]+ +space [ \t]+ +ident [_a-zA-Z][_a-zA-Z0-9]+ + +%% + +{num_dec} { return value(10); } +{num_hex} { return value(16); } +{space} { } + +ip { return sample(PERF_SAMPLE_IP); } +id { return sample(PERF_SAMPLE_ID); } +tid { return sample(PERF_SAMPLE_TID); } +cpu { return sample(PERF_SAMPLE_CPU); } +time { return sample(PERF_SAMPLE_TIME); } +addr { return sample(PERF_SAMPLE_ADDR); } +period { return sample(PERF_SAMPLE_PERIOD); } +txn { return sample(PERF_SAMPLE_TRANSACTION); } +weight { return sample(PERF_SAMPLE_WEIGHT); } +phys_addr { return sample(PERF_SAMPLE_PHYS_ADDR); } +code_pgsz { return sample(PERF_SAMPLE_CODE_PAGE_SIZE); } +data_pgsz { return sample(PERF_SAMPLE_DATA_PAGE_SIZE); } + +"==" { return operator(PBF_OP_EQ); } +"!=" { return operator(PBF_OP_NEQ); } +">" { return operator(PBF_OP_GT); } +"<" { return operator(PBF_OP_LT); } +">=" { return operator(PBF_OP_GE); } +"<=" { return operator(PBF_OP_LE); } +"&" { return operator(PBF_OP_AND); } + +"," { return ','; } + +{ident} { return error("ident"); } +. { return error("input"); } + +%% -- cgit v1.2.3