diff options
Diffstat (limited to 'tools/perf/builtin-stat.c')
-rw-r--r-- | tools/perf/builtin-stat.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 7ce65f52415e..7d98676808d8 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
@@ -278,9 +278,14 @@ struct stats runtime_itlb_cache_stats[MAX_NR_CPUS]; | |||
278 | struct stats runtime_dtlb_cache_stats[MAX_NR_CPUS]; | 278 | struct stats runtime_dtlb_cache_stats[MAX_NR_CPUS]; |
279 | struct stats walltime_nsecs_stats; | 279 | struct stats walltime_nsecs_stats; |
280 | 280 | ||
281 | static int create_perf_stat_counter(struct perf_evsel *evsel) | 281 | static int create_perf_stat_counter(struct perf_evsel *evsel, |
282 | struct perf_evsel *first) | ||
282 | { | 283 | { |
283 | struct perf_event_attr *attr = &evsel->attr; | 284 | struct perf_event_attr *attr = &evsel->attr; |
285 | struct xyarray *group_fd = NULL; | ||
286 | |||
287 | if (group && evsel != first) | ||
288 | group_fd = first->fd; | ||
284 | 289 | ||
285 | if (scale) | 290 | if (scale) |
286 | attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | | 291 | attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | |
@@ -289,14 +294,15 @@ static int create_perf_stat_counter(struct perf_evsel *evsel) | |||
289 | attr->inherit = !no_inherit; | 294 | attr->inherit = !no_inherit; |
290 | 295 | ||
291 | if (system_wide) | 296 | if (system_wide) |
292 | return perf_evsel__open_per_cpu(evsel, evsel_list->cpus, group); | 297 | return perf_evsel__open_per_cpu(evsel, evsel_list->cpus, |
293 | 298 | group, group_fd); | |
294 | if (target_pid == -1 && target_tid == -1) { | 299 | if (target_pid == -1 && target_tid == -1) { |
295 | attr->disabled = 1; | 300 | attr->disabled = 1; |
296 | attr->enable_on_exec = 1; | 301 | attr->enable_on_exec = 1; |
297 | } | 302 | } |
298 | 303 | ||
299 | return perf_evsel__open_per_thread(evsel, evsel_list->threads, group); | 304 | return perf_evsel__open_per_thread(evsel, evsel_list->threads, |
305 | group, group_fd); | ||
300 | } | 306 | } |
301 | 307 | ||
302 | /* | 308 | /* |
@@ -396,7 +402,7 @@ static int read_counter(struct perf_evsel *counter) | |||
396 | static int run_perf_stat(int argc __used, const char **argv) | 402 | static int run_perf_stat(int argc __used, const char **argv) |
397 | { | 403 | { |
398 | unsigned long long t0, t1; | 404 | unsigned long long t0, t1; |
399 | struct perf_evsel *counter; | 405 | struct perf_evsel *counter, *first; |
400 | int status = 0; | 406 | int status = 0; |
401 | int child_ready_pipe[2], go_pipe[2]; | 407 | int child_ready_pipe[2], go_pipe[2]; |
402 | const bool forks = (argc > 0); | 408 | const bool forks = (argc > 0); |
@@ -453,8 +459,10 @@ static int run_perf_stat(int argc __used, const char **argv) | |||
453 | close(child_ready_pipe[0]); | 459 | close(child_ready_pipe[0]); |
454 | } | 460 | } |
455 | 461 | ||
462 | first = list_entry(evsel_list->entries.next, struct perf_evsel, node); | ||
463 | |||
456 | list_for_each_entry(counter, &evsel_list->entries, node) { | 464 | list_for_each_entry(counter, &evsel_list->entries, node) { |
457 | if (create_perf_stat_counter(counter) < 0) { | 465 | if (create_perf_stat_counter(counter, first) < 0) { |
458 | if (errno == EINVAL || errno == ENOSYS || errno == ENOENT) { | 466 | if (errno == EINVAL || errno == ENOSYS || errno == ENOENT) { |
459 | if (verbose) | 467 | if (verbose) |
460 | ui__warning("%s event is not supported by the kernel.\n", | 468 | ui__warning("%s event is not supported by the kernel.\n", |