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

perf record: Fix -c/-F options for cpu event aliases

The Intel PMU event aliases have a implicit period= specifier to set the
default period.

Unfortunately this breaks overriding these periods with -c or -F,
because the alias terms look like they are user specified to the
internal parser, and user specified event qualifiers override the
command line options.

Track that they are coming from aliases by adding a "weak" state to the
term. Any weak terms don't override command line options.

I only did it for -c/-F for now, I think that's the only case that's
broken currently.

Before:

$ perf record -c 1000 -vv -e uops_issued.any
...
{ sample_period, sample_freq } 2000003

After:

$ perf record -c 1000 -vv -e uops_issued.any
...
{ sample_period, sample_freq } 1000

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Link: http://lkml.kernel.org/r/20171020202755.21410-2-andi@firstfloor.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Andi Kleen and committed by
Arnaldo Carvalho de Melo
59622fd4 dffdcbdb

+19 -4
+8 -4
tools/perf/util/evsel.c
··· 733 733 list_for_each_entry(term, config_terms, list) { 734 734 switch (term->type) { 735 735 case PERF_EVSEL__CONFIG_TERM_PERIOD: 736 - attr->sample_period = term->val.period; 737 - attr->freq = 0; 736 + if (!(term->weak && opts->user_interval != ULLONG_MAX)) { 737 + attr->sample_period = term->val.period; 738 + attr->freq = 0; 739 + } 738 740 break; 739 741 case PERF_EVSEL__CONFIG_TERM_FREQ: 740 - attr->sample_freq = term->val.freq; 741 - attr->freq = 1; 742 + if (!(term->weak && opts->user_freq != UINT_MAX)) { 743 + attr->sample_freq = term->val.freq; 744 + attr->freq = 1; 745 + } 742 746 break; 743 747 case PERF_EVSEL__CONFIG_TERM_TIME: 744 748 if (term->val.time)
+1
tools/perf/util/evsel.h
··· 67 67 bool overwrite; 68 68 char *branch; 69 69 } val; 70 + bool weak; 70 71 }; 71 72 72 73 struct perf_stat_evsel;
+2
tools/perf/util/parse-events.c
··· 1116 1116 INIT_LIST_HEAD(&__t->list); \ 1117 1117 __t->type = PERF_EVSEL__CONFIG_TERM_ ## __type; \ 1118 1118 __t->val.__name = __val; \ 1119 + __t->weak = term->weak; \ 1119 1120 list_add_tail(&__t->list, head_terms); \ 1120 1121 } while (0) 1121 1122 ··· 2411 2410 2412 2411 *term = *temp; 2413 2412 INIT_LIST_HEAD(&term->list); 2413 + term->weak = false; 2414 2414 2415 2415 switch (term->type_val) { 2416 2416 case PARSE_EVENTS__TERM_TYPE_NUM:
+3
tools/perf/util/parse-events.h
··· 101 101 /* error string indexes for within parsed string */ 102 102 int err_term; 103 103 int err_val; 104 + 105 + /* Coming from implicit alias */ 106 + bool weak; 104 107 }; 105 108 106 109 struct parse_events_error {
+5
tools/perf/util/pmu.c
··· 405 405 parse_events_terms__purge(&list); 406 406 return ret; 407 407 } 408 + /* 409 + * Weak terms don't override command line options, 410 + * which we don't want for implicit terms in aliases. 411 + */ 412 + cloned->weak = true; 408 413 list_add_tail(&cloned->list, &list); 409 414 } 410 415 list_splice(&list, terms);