diff options
Diffstat (limited to 'tools/perf/builtin-stat.c')
-rw-r--r-- | tools/perf/builtin-stat.c | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 147a27e8c937..f17dc601b0f3 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -172,6 +172,7 @@ static bool interval_count; static const char *output_name; static int output_fd; static int print_free_counters_hint; +static int print_mixed_hw_group_error; struct perf_stat { bool record; @@ -1126,6 +1127,30 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg) fprintf(output, "%s%s", csv_sep, evsel->cgrp->name); } +static bool is_mixed_hw_group(struct perf_evsel *counter) +{ + struct perf_evlist *evlist = counter->evlist; + u32 pmu_type = counter->attr.type; + struct perf_evsel *pos; + + if (counter->nr_members < 2) + return false; + + evlist__for_each_entry(evlist, pos) { + /* software events can be part of any hardware group */ + if (pos->attr.type == PERF_TYPE_SOFTWARE) + continue; + if (pmu_type == PERF_TYPE_SOFTWARE) { + pmu_type = pos->attr.type; + continue; + } + if (pmu_type != pos->attr.type) + return true; + } + + return false; +} + static void printout(int id, int nr, struct perf_evsel *counter, double uval, char *prefix, u64 run, u64 ena, double noise, struct runtime_stat *st) @@ -1178,8 +1203,11 @@ static void printout(int id, int nr, struct perf_evsel *counter, double uval, counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, csv_sep); - if (counter->supported) + if (counter->supported) { print_free_counters_hint = 1; + if (is_mixed_hw_group(counter)) + print_mixed_hw_group_error = 1; + } fprintf(stat_config.output, "%-*s%s", csv_output ? 0 : unit_width, @@ -1256,7 +1284,8 @@ static void uniquify_event_name(struct perf_evsel *counter) char *new_name; char *config; - if (!counter->pmu_name || !strncmp(counter->name, counter->pmu_name, + if (counter->uniquified_name || + !counter->pmu_name || !strncmp(counter->name, counter->pmu_name, strlen(counter->pmu_name))) return; @@ -1274,6 +1303,8 @@ static void uniquify_event_name(struct perf_evsel *counter) counter->name = new_name; } } + + counter->uniquified_name = true; } static void collect_all_aliases(struct perf_evsel *counter, @@ -1757,6 +1788,11 @@ static void print_footer(void) " echo 0 > /proc/sys/kernel/nmi_watchdog\n" " perf stat ...\n" " echo 1 > /proc/sys/kernel/nmi_watchdog\n"); + + if (print_mixed_hw_group_error) + fprintf(output, + "The events in group usually have to be from " + "the same PMU. Try reorganizing the group.\n"); } static void print_counters(struct timespec *ts, int argc, const char **argv) |