Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf tools: Fail on using multiple bits long terms without value

Currently we allow not to specify value for numeric terms and we set
them to value 1. This was originaly meant just for single bit terms to
allow user to type:

$ perf record -e 'cpu/cpu-cycles,any'

instead of:

$ perf record -e 'cpu/cpu-cycles,any=1'

However it works also for multi bits terms like:

$ perf record -e 'cpu/event/' ls
...
$ perf evlist -v
..., config: 0x1, ...

After discussion with Peter we decided making such term usage to fail,
like:

$ perf record -e 'cpu/event/' ls
event syntax error: 'cpu/event/'
\___ no value assigned for term
...

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1487340058-10496-4-git-send-email-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Jiri Olsa and committed by
Arnaldo Carvalho de Melo
99e7138e 67b49b38

+22 -9
+2
tools/perf/util/parse-events.c
··· 2349 2349 2350 2350 int parse_events_term__num(struct parse_events_term **term, 2351 2351 int type_term, char *config, u64 num, 2352 + bool no_value, 2352 2353 void *loc_term_, void *loc_val_) 2353 2354 { 2354 2355 YYLTYPE *loc_term = loc_term_; ··· 2359 2358 .type_val = PARSE_EVENTS__TERM_TYPE_NUM, 2360 2359 .type_term = type_term, 2361 2360 .config = config, 2361 + .no_value = no_value, 2362 2362 .err_term = loc_term ? loc_term->first_column : 0, 2363 2363 .err_val = loc_val ? loc_val->first_column : 0, 2364 2364 };
+2
tools/perf/util/parse-events.h
··· 94 94 int type_term; 95 95 struct list_head list; 96 96 bool used; 97 + bool no_value; 97 98 98 99 /* error string indexes for within parsed string */ 99 100 int err_term; ··· 123 122 int parse_events__is_hardcoded_term(struct parse_events_term *term); 124 123 int parse_events_term__num(struct parse_events_term **term, 125 124 int type_term, char *config, u64 num, 125 + bool novalue, 126 126 void *loc_term, void *loc_val); 127 127 int parse_events_term__str(struct parse_events_term **term, 128 128 int type_term, char *config, char *str,
+7 -7
tools/perf/util/parse-events.y
··· 252 252 if (!strcasecmp(alias->name, $1)) { 253 253 ALLOC_LIST(head); 254 254 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, 255 - $1, 1, &@1, NULL)); 255 + $1, 1, false, &@1, NULL)); 256 256 list_add_tail(&term->list, head); 257 257 258 258 if (!parse_events_add_pmu(data, list, ··· 282 282 283 283 ALLOC_LIST(head); 284 284 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, 285 - &pmu_name, 1, &@1, NULL)); 285 + &pmu_name, 1, false, &@1, NULL)); 286 286 list_add_tail(&term->list, head); 287 287 288 288 ALLOC_LIST(list); ··· 548 548 struct parse_events_term *term; 549 549 550 550 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, 551 - $1, $3, &@1, &@3)); 551 + $1, $3, false, &@1, &@3)); 552 552 $$ = term; 553 553 } 554 554 | ··· 566 566 struct parse_events_term *term; 567 567 568 568 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, 569 - $1, 1, &@1, NULL)); 569 + $1, 1, true, &@1, NULL)); 570 570 $$ = term; 571 571 } 572 572 | ··· 591 591 { 592 592 struct parse_events_term *term; 593 593 594 - ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, $3, &@1, &@3)); 594 + ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, $3, false, &@1, &@3)); 595 595 $$ = term; 596 596 } 597 597 | ··· 599 599 { 600 600 struct parse_events_term *term; 601 601 602 - ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, 1, &@1, NULL)); 602 + ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, 1, true, &@1, NULL)); 603 603 $$ = term; 604 604 } 605 605 | ··· 620 620 struct parse_events_term *term; 621 621 622 622 ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, 623 - $1, $4, &@1, &@4)); 623 + $1, $4, false, &@1, &@4)); 624 624 term->array = $2; 625 625 $$ = term; 626 626 }
+11 -2
tools/perf/util/pmu.c
··· 834 834 * Either directly use a numeric term, or try to translate string terms 835 835 * using event parameters. 836 836 */ 837 - if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) 837 + if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) { 838 + if (term->no_value && 839 + bitmap_weight(format->bits, PERF_PMU_FORMAT_BITS) > 1) { 840 + if (err) { 841 + err->idx = term->err_val; 842 + err->str = strdup("no value assigned for term"); 843 + } 844 + return -EINVAL; 845 + } 846 + 838 847 val = term->val.num; 839 - else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) { 848 + } else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) { 840 849 if (strcmp(term->val.str, "?")) { 841 850 if (verbose) { 842 851 pr_info("Invalid sysfs entry %s=%s\n",