This patch introduce a new syntax to perf event parser: # perf record -e bpf_file.c/maps.mymap.value[0,3-5,7]=1234/ ...
By utilizing the basic facilities in bpf-loader.c which allow setting different slots in a BPF map separately, the newly introduced syntax allows perf to control specific elements in a BPF map. Signed-off-by: Wang Nan <wangn...@huawei.com> Cc: Arnaldo Carvalho de Melo <a...@redhat.com> Cc: Alexei Starovoitov <a...@plumgrid.com> Cc: Brendan Gregg <brendan.d.gr...@gmail.com> Cc: Daniel Borkmann <dan...@iogearbox.net> Cc: David Ahern <dsah...@gmail.com> Cc: He Kuang <heku...@huawei.com> Cc: Jiri Olsa <jo...@kernel.org> Cc: Kaixu Xia <xiaka...@huawei.com> Cc: Masami Hiramatsu <masami.hiramatsu...@hitachi.com> Cc: Namhyung Kim <namhy...@kernel.org> Cc: Paul Mackerras <pau...@samba.org> Cc: Peter Zijlstra <a.p.zijls...@chello.nl> Cc: Zefan Li <lize...@huawei.com> Cc: pi3or...@163.com --- tools/perf/util/parse-events.c | 4 +- tools/perf/util/parse-events.l | 11 +++++ tools/perf/util/parse-events.y | 92 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 42ac1cb..a2af5a8 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -654,7 +654,9 @@ parse_events_config_bpf(struct parse_events_evlist *data, err, errbuf, sizeof(errbuf)); data->error->help = strdup( "Hint:\tValid config term:\n" -" \tmaps.<mapname>.value\n" +" \tmaps.<mapname>.value<indics>\n" +"\n" +" \twhere <indics> is something like [0,3-4]\n" " \t(add -v to see detail)"); data->error->str = strdup(errbuf); if (err == -EINVAL) diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l index eeea4e1..0d92a4d 100644 --- a/tools/perf/util/parse-events.l +++ b/tools/perf/util/parse-events.l @@ -111,6 +111,7 @@ do { \ %x mem %s config %x event +%x array group [^,{}/]*[{][^}]*[}][^,{}/]* event_pmu [^,{}/]+[/][^/]*[/][^,{}/]* @@ -176,6 +177,14 @@ modifier_bp [rwx]{1,3} } +<array>{ +"]" { BEGIN(config); return ']'; } +{num_dec} { return value(yyscanner, 10); } +{num_hex} { return value(yyscanner, 16); } +, { return ','; } +- { return '-'; } +} + <config>{ /* * Please update parse_events_formats_error_string any time @@ -194,6 +203,8 @@ stack-size { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_STACKSIZE); } , { return ','; } "/" { BEGIN(INITIAL); return '/'; } {name_minus} { return str(yyscanner, PE_NAME); } +\[all\] { return PE_ARRAY_ALL; } +"[" { BEGIN(array); return '['; } } <mem>{ diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index 255387a..81fe702 100644 --- a/tools/perf/util/parse-events.y +++ b/tools/perf/util/parse-events.y @@ -48,6 +48,7 @@ static inc_group_count(struct list_head *list, %token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP %token PE_ERROR %token PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT +%token PE_ARRAY_ALL %type <num> PE_VALUE %type <num> PE_VALUE_SYM_HW %type <num> PE_VALUE_SYM_SW @@ -84,6 +85,9 @@ static inc_group_count(struct list_head *list, %type <head> group_def %type <head> group %type <head> groups +%type <array> array +%type <array> array_term +%type <array> array_terms %union { @@ -95,6 +99,10 @@ static inc_group_count(struct list_head *list, char *sys; char *event; } tracepoint_name; + struct array { + size_t nr_indics; + u64 *indics; + } array; } %% @@ -599,6 +607,90 @@ PE_TERM ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, 1, &@1, NULL)); $$ = term; } +| +PE_NAME array '=' PE_NAME +{ + struct parse_events_term *term; + int i; + + ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER, + $1, $4, &@1, &@4)); + + term->nr_indics = $2.nr_indics; + term->indics = $2.indics; + $$ = term; +} +| +PE_NAME array '=' PE_VALUE +{ + struct parse_events_term *term; + + ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, + $1, $4, &@1, &@4)); + term->nr_indics = $2.nr_indics; + term->indics = $2.indics; + $$ = term; +} + +array: +'[' array_terms ']' +{ + $$ = $2; +} +| +PE_ARRAY_ALL +{ + $$.nr_indics = 0; + $$.indics = NULL; +} + +array_terms: +array_terms ',' array_term +{ + struct array array = $1; + struct array new_array = $3; + u64 *new_indics; + + new_indics = realloc(array.indics, + (array.nr_indics + new_array.nr_indics) * sizeof(u64)); + ABORT_ON(!new_indics); + + memcpy(&new_indics[array.nr_indics], new_array.indics, + sizeof(u64) * new_array.nr_indics); + + array.nr_indics += new_array.nr_indics; + array.indics = new_indics; + free(new_array.indics); + $$ = array; +} +| +array_term + +array_term: +PE_VALUE +{ + struct array array; + array.nr_indics = 1; + array.indics = malloc(sizeof(u64)); + ABORT_ON(!array.indics); + array.indics[0] = $1; + $$ = array; +} +| +PE_VALUE '-' PE_VALUE +{ + struct array array; + int i; + + ABORT_ON($3 < $1); + array.nr_indics = $3 - $1 + 1; + array.indics = malloc(sizeof(u64) * array.nr_indics); + ABORT_ON(!array.indics); + + for (i = 0; i < array.nr_indics; i++) + array.indics[i] = $1 + i; + $$ = array; +} sep_dc: ':' | -- 1.8.3.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/