diff options
| -rw-r--r-- | tools/perf/builtin-stat.c | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 147a27e8c937..30e6b374e095 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
| @@ -172,6 +172,7 @@ static bool interval_count; | |||
| 172 | static const char *output_name; | 172 | static const char *output_name; |
| 173 | static int output_fd; | 173 | static int output_fd; |
| 174 | static int print_free_counters_hint; | 174 | static int print_free_counters_hint; |
| 175 | static int print_mixed_hw_group_error; | ||
| 175 | 176 | ||
| 176 | struct perf_stat { | 177 | struct perf_stat { |
| 177 | bool record; | 178 | bool record; |
| @@ -1126,6 +1127,30 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg) | |||
| 1126 | fprintf(output, "%s%s", csv_sep, evsel->cgrp->name); | 1127 | fprintf(output, "%s%s", csv_sep, evsel->cgrp->name); |
| 1127 | } | 1128 | } |
| 1128 | 1129 | ||
| 1130 | static bool is_mixed_hw_group(struct perf_evsel *counter) | ||
| 1131 | { | ||
| 1132 | struct perf_evlist *evlist = counter->evlist; | ||
| 1133 | u32 pmu_type = counter->attr.type; | ||
| 1134 | struct perf_evsel *pos; | ||
| 1135 | |||
| 1136 | if (counter->nr_members < 2) | ||
| 1137 | return false; | ||
| 1138 | |||
| 1139 | evlist__for_each_entry(evlist, pos) { | ||
| 1140 | /* software events can be part of any hardware group */ | ||
| 1141 | if (pos->attr.type == PERF_TYPE_SOFTWARE) | ||
| 1142 | continue; | ||
| 1143 | if (pmu_type == PERF_TYPE_SOFTWARE) { | ||
| 1144 | pmu_type = pos->attr.type; | ||
| 1145 | continue; | ||
| 1146 | } | ||
| 1147 | if (pmu_type != pos->attr.type) | ||
| 1148 | return true; | ||
| 1149 | } | ||
| 1150 | |||
| 1151 | return false; | ||
| 1152 | } | ||
| 1153 | |||
| 1129 | static void printout(int id, int nr, struct perf_evsel *counter, double uval, | 1154 | static void printout(int id, int nr, struct perf_evsel *counter, double uval, |
| 1130 | char *prefix, u64 run, u64 ena, double noise, | 1155 | char *prefix, u64 run, u64 ena, double noise, |
| 1131 | struct runtime_stat *st) | 1156 | struct runtime_stat *st) |
| @@ -1178,8 +1203,11 @@ static void printout(int id, int nr, struct perf_evsel *counter, double uval, | |||
| 1178 | counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, | 1203 | counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, |
| 1179 | csv_sep); | 1204 | csv_sep); |
| 1180 | 1205 | ||
| 1181 | if (counter->supported) | 1206 | if (counter->supported) { |
| 1182 | print_free_counters_hint = 1; | 1207 | print_free_counters_hint = 1; |
| 1208 | if (is_mixed_hw_group(counter)) | ||
| 1209 | print_mixed_hw_group_error = 1; | ||
| 1210 | } | ||
| 1183 | 1211 | ||
| 1184 | fprintf(stat_config.output, "%-*s%s", | 1212 | fprintf(stat_config.output, "%-*s%s", |
| 1185 | csv_output ? 0 : unit_width, | 1213 | csv_output ? 0 : unit_width, |
| @@ -1757,6 +1785,11 @@ static void print_footer(void) | |||
| 1757 | " echo 0 > /proc/sys/kernel/nmi_watchdog\n" | 1785 | " echo 0 > /proc/sys/kernel/nmi_watchdog\n" |
| 1758 | " perf stat ...\n" | 1786 | " perf stat ...\n" |
| 1759 | " echo 1 > /proc/sys/kernel/nmi_watchdog\n"); | 1787 | " echo 1 > /proc/sys/kernel/nmi_watchdog\n"); |
| 1788 | |||
| 1789 | if (print_mixed_hw_group_error) | ||
| 1790 | fprintf(output, | ||
| 1791 | "The events in group usually have to be from " | ||
| 1792 | "the same PMU. Try reorganizing the group.\n"); | ||
| 1760 | } | 1793 | } |
| 1761 | 1794 | ||
| 1762 | static void print_counters(struct timespec *ts, int argc, const char **argv) | 1795 | static void print_counters(struct timespec *ts, int argc, const char **argv) |
