@@ -1225,6 +1225,31 @@ static void aggr_update_shadow(void)
}
}
+static void uniquify_event_name(struct perf_evsel *counter)
+{
+ char *new_name;
+ char *config;
+
+ if (!counter->pmu_name || !strncmp(counter->name, counter->pmu_name,
+ strlen(counter->pmu_name)))
+ return;
+
+ config = strchr(counter->name, '/');
+ if (config) {
+ if (asprintf(&new_name,
+ "%s%s", counter->pmu_name, config) > 0) {
+ free(counter->name);
+ counter->name = new_name;
+ }
+ } else {
+ if (asprintf(&new_name,
+ "%s [%s]", counter->name, counter->pmu_name) > 0) {
+ free(counter->name);
+ counter->name = new_name;
+ }
+ }
+}
+
static void collect_all_aliases(struct perf_evsel *counter,
void (*cb)(struct perf_evsel *counter, void *data,
bool first),
@@ -1253,7 +1278,9 @@ static bool collect_data(struct perf_evsel *counter,
if (counter->merged_stat)
return false;
cb(counter, data, true);
- if (!no_merge && counter->auto_merge_stats)
+ if (no_merge)
+ uniquify_event_name(counter);
+ else if (counter->auto_merge_stats)
collect_all_aliases(counter, cb, data);
return true;
}
@@ -244,6 +244,7 @@ void perf_evsel__init(struct perf_evsel *evsel,
evsel->metric_name = NULL;
evsel->metric_events = NULL;
evsel->collect_stat = false;
+ evsel->pmu_name = NULL;
}
struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx)
@@ -142,6 +142,7 @@ struct perf_evsel {
struct perf_evsel **metric_events;
bool collect_stat;
bool weak_group;
+ const char *pmu_name;
};
union u64_swap {
@@ -1247,7 +1247,12 @@ static int __parse_events_add_pmu(struct parse_events_state *parse_state,
if (!head_config) {
attr.type = pmu->type;
evsel = __add_event(list, &parse_state->idx, &attr, NULL, pmu, NULL, auto_merge_stats);
- return evsel ? 0 : -ENOMEM;
+ if (evsel) {
+ evsel->pmu_name = name;
+ return 0;
+ } else {
+ return -ENOMEM;
+ }
}
if (perf_pmu__check_alias(pmu, head_config, &info))
@@ -1276,6 +1281,7 @@ static int __parse_events_add_pmu(struct parse_events_state *parse_state,
evsel->snapshot = info.snapshot;
evsel->metric_expr = info.metric_expr;
evsel->metric_name = info.metric_name;
+ evsel->pmu_name = name;
}
return evsel ? 0 : -ENOMEM;
Starting on v4.12 event parsing code for dynamic pmu events supports prefix-based matching of multiple pmus when creating dynamic events. E.g., in a system with the following dynamic pmus: l3cache_0_0 l3cache_0_1 l3cache_0_2 l3cache_0_3 passing l3cache/<config>/ as an event spec will result in the creation of the event in all of the pmus. When this functionality is used in stat the command will by default merge the event counts and display a single value. E.g.: ./perf stat -a -e l3cache/read-miss/ ls > /dev/null Performance counter stats for 'system wide': 328 l3cache/read-miss/ 0.001661809 seconds time elapsed JSON-based alias events behave in the same way: $ ./perf stat -a -e l3cache_read_miss ls > /dev/null Performance counter stats for 'system wide': 229 l3cache_read_miss 0.001656099 seconds time elapsed This behavior can be disabled by the --no-merge option but the real pmu name is lost and it's not possible to see which count corresponds to which pmu: $ ./perf stat -a -e l3cache/read-miss/ --no-merge ls > /dev/null Performance counter stats for 'system wide': 67 l3cache/read-miss/ 67 l3cache/read-miss/ 63 l3cache/read-miss/ 60 l3cache/read-miss/ 0.001675706 seconds time elapsed This is also the case for alias events, e.g.: $ ./perf stat -a -e l3cache_read_miss --no-merge ls > /dev/null Performance counter stats for 'system wide': 12 l3cache_read_miss 17 l3cache_read_miss 10 l3cache_read_miss 8 l3cache_read_miss 0.001661305 seconds time elapsed This change adds the original pmu name to the event. For dynamic pmu events the pmu name is restored in the event name: $ ./perf stat -a -e l3cache/read-miss/ --no-merge ls > /dev/null Performance counter stats for 'system wide': 63 l3cache_0_3/read-miss/ 74 l3cache_0_1/read-miss/ 64 l3cache_0_2/read-miss/ 74 l3cache_0_0/read-miss/ 0.001675706 seconds time elapsed For alias events the name is added after the event name: $ ./perf stat -a -e l3cache_read_miss --no-merge ls > /dev/null Performance counter stats for 'system wide': 10 l3cache_read_miss [l3cache_0_3] 12 l3cache_read_miss [l3cache_0_1] 10 l3cache_read_miss [l3cache_0_2] 17 l3cache_read_miss [l3cache_0_0] 0.001661305 seconds time elapsed Signed-off-by: Agustin Vega-Frias <agustinv@codeaurora.org> --- tools/perf/builtin-stat.c | 29 ++++++++++++++++++++++++++++- tools/perf/util/evsel.c | 1 + tools/perf/util/evsel.h | 1 + tools/perf/util/parse-events.c | 8 +++++++- 4 files changed, 37 insertions(+), 2 deletions(-) -- 2.7.4