[tip:perf/core] perf record: Fix -c/-F options for cpu event aliases

From: tip-bot for Andi Kleen
Date: Sat Nov 18 2017 - 03:26:35 EST


Commit-ID: c2f1cead19b628d7a23d2cfc43e444af669f9eab
Gitweb: https://git.kernel.org/tip/c2f1cead19b628d7a23d2cfc43e444af669f9eab
Author: Andi Kleen <ak@xxxxxxxxxxxxxxx>
AuthorDate: Fri, 20 Oct 2017 13:27:55 -0700
Committer: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
CommitDate: Thu, 16 Nov 2017 14:49:51 -0300

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@xxxxxxxxxxxxxxx>
Acked-by: Jiri Olsa <jolsa@xxxxxxxxxx>
Link: http://lkml.kernel.org/r/20171020202755.21410-2-andi@xxxxxxxxxxxxxx
Signed-off-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
---
tools/perf/util/evsel.c | 12 ++++++++----
tools/perf/util/evsel.h | 1 +
tools/perf/util/parse-events.c | 2 ++
tools/perf/util/parse-events.h | 3 +++
tools/perf/util/pmu.c | 5 +++++
5 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index f894893..bfde6a7 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -733,12 +733,16 @@ static void apply_config_terms(struct perf_evsel *evsel,
list_for_each_entry(term, config_terms, list) {
switch (term->type) {
case PERF_EVSEL__CONFIG_TERM_PERIOD:
- attr->sample_period = term->val.period;
- attr->freq = 0;
+ if (!(term->weak && opts->user_interval != ULLONG_MAX)) {
+ attr->sample_period = term->val.period;
+ attr->freq = 0;
+ }
break;
case PERF_EVSEL__CONFIG_TERM_FREQ:
- attr->sample_freq = term->val.freq;
- attr->freq = 1;
+ if (!(term->weak && opts->user_freq != UINT_MAX)) {
+ attr->sample_freq = term->val.freq;
+ attr->freq = 1;
+ }
break;
case PERF_EVSEL__CONFIG_TERM_TIME:
if (term->val.time)
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 9277df9..157f49e 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -67,6 +67,7 @@ struct perf_evsel_config_term {
bool overwrite;
char *branch;
} val;
+ bool weak;
};

struct perf_stat_evsel;
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index a7fcd95..1703167 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -1116,6 +1116,7 @@ do { \
INIT_LIST_HEAD(&__t->list); \
__t->type = PERF_EVSEL__CONFIG_TERM_ ## __type; \
__t->val.__name = __val; \
+ __t->weak = term->weak; \
list_add_tail(&__t->list, head_terms); \
} while (0)

@@ -2410,6 +2411,7 @@ static int new_term(struct parse_events_term **_term,

*term = *temp;
INIT_LIST_HEAD(&term->list);
+ term->weak = false;

switch (term->type_val) {
case PARSE_EVENTS__TERM_TYPE_NUM:
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index be337c2..88108cd 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -101,6 +101,9 @@ struct parse_events_term {
/* error string indexes for within parsed string */
int err_term;
int err_val;
+
+ /* Coming from implicit alias */
+ bool weak;
};

struct parse_events_error {
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 07cb2ac..80fb159 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -405,6 +405,11 @@ static int pmu_alias_terms(struct perf_pmu_alias *alias,
parse_events_terms__purge(&list);
return ret;
}
+ /*
+ * Weak terms don't override command line options,
+ * which we don't want for implicit terms in aliases.
+ */
+ cloned->weak = true;
list_add_tail(&cloned->list, &list);
}
list_splice(&list, terms);