aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2017-08-31 14:32:18 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2017-09-01 13:48:59 -0400
commit63ce8449bc1081711eef1add68909e9bd758de62 (patch)
tree38c7f4f56f7de233a504c592b63b678d2a16b160 /tools
parentfc33dccba39584e403436b9cda3edc9c34b62bce (diff)
perf stat: Only auto-merge events that are PMU aliases
Peter reported that when he explicitely asked for multiple events with the same name on the command line it got coalesced into just one line, i.e.: # perf stat -e cycles -e cycles -e cycles usleep 1 Performance counter stats for 'usleep 1': 3,269,652 cycles 0.000884123 seconds time elapsed # And while there is the --no-merges option to disable that auto-merging, this is a blunt change in behaviour for such explicit request, so change the code so that this auto merging is done only when handling the multi PMU aliases with the same name that introduced this coalescing, restoring the previous behaviour for the explicit case: # perf stat -e cycles -e cycles -e cycles usleep 1 Performance counter stats for 'usleep 1': 1,472,837 cycles 1,472,837 cycles 1,472,837 cycles 0.001764870 seconds time elapsed # Reported-by: Peter Zijlstra <peterz@infradead.org> Acked-by: Andi Kleen <ak@linux.intel.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Wang Nan <wangnan0@huawei.com> Fixes: 430daf2dc7af ("perf stat: Collapse identically named events") Link: http://lkml.kernel.org/r/20170831184122.GK4831@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/builtin-stat.c2
-rw-r--r--tools/perf/util/evsel.h1
-rw-r--r--tools/perf/util/parse-events.c24
3 files changed, 18 insertions, 9 deletions
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 866da7aa54bf..85e992d9215b 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -1257,7 +1257,7 @@ static bool collect_data(struct perf_evsel *counter,
1257 if (counter->merged_stat) 1257 if (counter->merged_stat)
1258 return false; 1258 return false;
1259 cb(counter, data, true); 1259 cb(counter, data, true);
1260 if (!no_merge) 1260 if (!no_merge && counter->auto_merge_stats)
1261 collect_all_aliases(counter, cb, data); 1261 collect_all_aliases(counter, cb, data);
1262 return true; 1262 return true;
1263} 1263}
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 351d3b2d8887..dd2c4b5112a5 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -131,6 +131,7 @@ struct perf_evsel {
131 bool cmdline_group_boundary; 131 bool cmdline_group_boundary;
132 struct list_head config_terms; 132 struct list_head config_terms;
133 int bpf_fd; 133 int bpf_fd;
134 bool auto_merge_stats;
134 bool merged_stat; 135 bool merged_stat;
135 const char * metric_expr; 136 const char * metric_expr;
136 const char * metric_name; 137 const char * metric_name;
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index f44aeba51d1f..f6257fb4f08c 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -310,7 +310,7 @@ static struct perf_evsel *
310__add_event(struct list_head *list, int *idx, 310__add_event(struct list_head *list, int *idx,
311 struct perf_event_attr *attr, 311 struct perf_event_attr *attr,
312 char *name, struct cpu_map *cpus, 312 char *name, struct cpu_map *cpus,
313 struct list_head *config_terms) 313 struct list_head *config_terms, bool auto_merge_stats)
314{ 314{
315 struct perf_evsel *evsel; 315 struct perf_evsel *evsel;
316 316
@@ -324,6 +324,7 @@ __add_event(struct list_head *list, int *idx,
324 evsel->cpus = cpu_map__get(cpus); 324 evsel->cpus = cpu_map__get(cpus);
325 evsel->own_cpus = cpu_map__get(cpus); 325 evsel->own_cpus = cpu_map__get(cpus);
326 evsel->system_wide = !!cpus; 326 evsel->system_wide = !!cpus;
327 evsel->auto_merge_stats = auto_merge_stats;
327 328
328 if (name) 329 if (name)
329 evsel->name = strdup(name); 330 evsel->name = strdup(name);
@@ -339,7 +340,7 @@ static int add_event(struct list_head *list, int *idx,
339 struct perf_event_attr *attr, char *name, 340 struct perf_event_attr *attr, char *name,
340 struct list_head *config_terms) 341 struct list_head *config_terms)
341{ 342{
342 return __add_event(list, idx, attr, name, NULL, config_terms) ? 0 : -ENOMEM; 343 return __add_event(list, idx, attr, name, NULL, config_terms, false) ? 0 : -ENOMEM;
343} 344}
344 345
345static int parse_aliases(char *str, const char *names[][PERF_EVSEL__MAX_ALIASES], int size) 346static int parse_aliases(char *str, const char *names[][PERF_EVSEL__MAX_ALIASES], int size)
@@ -1209,9 +1210,9 @@ int parse_events_add_numeric(struct parse_events_state *parse_state,
1209 get_config_name(head_config), &config_terms); 1210 get_config_name(head_config), &config_terms);
1210} 1211}
1211 1212
1212int parse_events_add_pmu(struct parse_events_state *parse_state, 1213static int __parse_events_add_pmu(struct parse_events_state *parse_state,
1213 struct list_head *list, char *name, 1214 struct list_head *list, char *name,
1214 struct list_head *head_config) 1215 struct list_head *head_config, bool auto_merge_stats)
1215{ 1216{
1216 struct perf_event_attr attr; 1217 struct perf_event_attr attr;
1217 struct perf_pmu_info info; 1218 struct perf_pmu_info info;
@@ -1232,7 +1233,7 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
1232 1233
1233 if (!head_config) { 1234 if (!head_config) {
1234 attr.type = pmu->type; 1235 attr.type = pmu->type;
1235 evsel = __add_event(list, &parse_state->idx, &attr, NULL, pmu->cpus, NULL); 1236 evsel = __add_event(list, &parse_state->idx, &attr, NULL, pmu->cpus, NULL, auto_merge_stats);
1236 return evsel ? 0 : -ENOMEM; 1237 return evsel ? 0 : -ENOMEM;
1237 } 1238 }
1238 1239
@@ -1254,7 +1255,7 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
1254 1255
1255 evsel = __add_event(list, &parse_state->idx, &attr, 1256 evsel = __add_event(list, &parse_state->idx, &attr,
1256 get_config_name(head_config), pmu->cpus, 1257 get_config_name(head_config), pmu->cpus,
1257 &config_terms); 1258 &config_terms, auto_merge_stats);
1258 if (evsel) { 1259 if (evsel) {
1259 evsel->unit = info.unit; 1260 evsel->unit = info.unit;
1260 evsel->scale = info.scale; 1261 evsel->scale = info.scale;
@@ -1267,6 +1268,13 @@ int parse_events_add_pmu(struct parse_events_state *parse_state,
1267 return evsel ? 0 : -ENOMEM; 1268 return evsel ? 0 : -ENOMEM;
1268} 1269}
1269 1270
1271int parse_events_add_pmu(struct parse_events_state *parse_state,
1272 struct list_head *list, char *name,
1273 struct list_head *head_config)
1274{
1275 return __parse_events_add_pmu(parse_state, list, name, head_config, false);
1276}
1277
1270int parse_events_multi_pmu_add(struct parse_events_state *parse_state, 1278int parse_events_multi_pmu_add(struct parse_events_state *parse_state,
1271 char *str, struct list_head **listp) 1279 char *str, struct list_head **listp)
1272{ 1280{
@@ -1296,8 +1304,8 @@ int parse_events_multi_pmu_add(struct parse_events_state *parse_state,
1296 return -1; 1304 return -1;
1297 list_add_tail(&term->list, head); 1305 list_add_tail(&term->list, head);
1298 1306
1299 if (!parse_events_add_pmu(parse_state, list, 1307 if (!__parse_events_add_pmu(parse_state, list,
1300 pmu->name, head)) { 1308 pmu->name, head, true)) {
1301 pr_debug("%s -> %s/%s/\n", str, 1309 pr_debug("%s -> %s/%s/\n", str,
1302 pmu->name, alias->str); 1310 pmu->name, alias->str);
1303 ok++; 1311 ok++;