diff options
| author | Namhyung Kim <namhyung@kernel.org> | 2023-03-14 16:42:28 -0700 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2023-03-15 10:33:37 -0300 |
| commit | 990a71e904f6ec2d7d84eecb37e5127b75721985 (patch) | |
| tree | 3610fcde18c8cbb4852f138d7e784d6be1c9dc04 /tools/perf/util/bpf-filter.l | |
| parent | 6e57f69f23d02b8c67d7428ee708b7d903ed22b2 (diff) | |
| download | linux-990a71e904f6ec2d7d84eecb37e5127b75721985.tar.gz linux-990a71e904f6ec2d7d84eecb37e5127b75721985.tar.bz2 linux-990a71e904f6ec2d7d84eecb37e5127b75721985.zip | |
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 <namhyung@kernel.org>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Hao Luo <haoluo@google.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: James Clark <james.clark@arm.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Leo Yan <leo.yan@linaro.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Song Liu <song@kernel.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: bpf@vger.kernel.org
Link: https://lore.kernel.org/r/20230314234237.3008956-2-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/bpf-filter.l')
| -rw-r--r-- | tools/perf/util/bpf-filter.l | 82 |
1 files changed, 82 insertions, 0 deletions
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 <stdio.h> +#include <stdlib.h> +#include <linux/perf_event.h> + +#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"); } + +%% |
