Commit 8c5421c0 authored by Agustin Vega-Frias's avatar Agustin Vega-Frias Committed by Arnaldo Carvalho de Melo

perf pmu: Display pmu name when printing unmerged events in stat

To simplify creation of events accross multiple instances of the same
type of PMU stat supports two methods for creating multiple events from
a single event specification:

1. A prefix or glob can be used in the PMU name.
2. Aliases, which are listed immediately after the Kernel PMU events
   by perf list, are used.

When the --no-merge option is passed and these events are displayed
individually the 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

    $ 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: default avatarAgustin Vega-Frias <agustinv@codeaurora.org>
Acked-by: default avatarAndi Kleen <ak@linux.intel.com>
Acked-by: default avatarJiri Olsa <jolsa@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Timur Tabi <timur@codeaurora.org>
Cc: linux-arm-kernel@lists.infradead.org
Change-Id: I8056b9eda74bda33e95065056167ad96e97cb1fb
Link: http://lkml.kernel.org/r/1520345084-42646-3-git-send-email-agustinv@codeaurora.orgSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent b2b9d3a3
...@@ -1251,6 +1251,31 @@ static void aggr_update_shadow(void) ...@@ -1251,6 +1251,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, static void collect_all_aliases(struct perf_evsel *counter,
void (*cb)(struct perf_evsel *counter, void *data, void (*cb)(struct perf_evsel *counter, void *data,
bool first), bool first),
...@@ -1279,7 +1304,9 @@ static bool collect_data(struct perf_evsel *counter, ...@@ -1279,7 +1304,9 @@ static bool collect_data(struct perf_evsel *counter,
if (counter->merged_stat) if (counter->merged_stat)
return false; return false;
cb(counter, data, true); 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); collect_all_aliases(counter, cb, data);
return true; return true;
} }
......
...@@ -244,6 +244,7 @@ void perf_evsel__init(struct perf_evsel *evsel, ...@@ -244,6 +244,7 @@ void perf_evsel__init(struct perf_evsel *evsel,
evsel->metric_name = NULL; evsel->metric_name = NULL;
evsel->metric_events = NULL; evsel->metric_events = NULL;
evsel->collect_stat = false; evsel->collect_stat = false;
evsel->pmu_name = NULL;
} }
struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx) struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx)
......
...@@ -142,6 +142,7 @@ struct perf_evsel { ...@@ -142,6 +142,7 @@ struct perf_evsel {
struct perf_evsel **metric_events; struct perf_evsel **metric_events;
bool collect_stat; bool collect_stat;
bool weak_group; bool weak_group;
const char *pmu_name;
}; };
union u64_swap { union u64_swap {
......
...@@ -1247,7 +1247,12 @@ static int __parse_events_add_pmu(struct parse_events_state *parse_state, ...@@ -1247,7 +1247,12 @@ static int __parse_events_add_pmu(struct parse_events_state *parse_state,
if (!head_config) { if (!head_config) {
attr.type = pmu->type; attr.type = pmu->type;
evsel = __add_event(list, &parse_state->idx, &attr, NULL, pmu, NULL, auto_merge_stats); 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)) 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, ...@@ -1276,6 +1281,7 @@ static int __parse_events_add_pmu(struct parse_events_state *parse_state,
evsel->snapshot = info.snapshot; evsel->snapshot = info.snapshot;
evsel->metric_expr = info.metric_expr; evsel->metric_expr = info.metric_expr;
evsel->metric_name = info.metric_name; evsel->metric_name = info.metric_name;
evsel->pmu_name = name;
} }
return evsel ? 0 : -ENOMEM; return evsel ? 0 : -ENOMEM;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment