diff options
Diffstat (limited to 'tools/perf/builtin-stat.c')
| -rw-r--r-- | tools/perf/builtin-stat.c | 47 |
1 files changed, 36 insertions, 11 deletions
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index d0605689bad9..62ae30d34fa6 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -282,6 +282,8 @@ static int create_perf_stat_counter(struct perf_evsel *evsel, { struct perf_event_attr *attr = &evsel->attr; struct xyarray *group_fd = NULL; + bool exclude_guest_missing = false; + int ret; if (group && evsel != first) group_fd = first->fd; @@ -292,16 +294,39 @@ static int create_perf_stat_counter(struct perf_evsel *evsel, attr->inherit = !no_inherit; - if (!perf_target__no_cpu(&target)) - return perf_evsel__open_per_cpu(evsel, evsel_list->cpus, - group, group_fd); - if (perf_target__no_task(&target) && (!group || evsel == first)) { +retry: + if (exclude_guest_missing) + evsel->attr.exclude_guest = evsel->attr.exclude_host = 0; + + if (perf_target__has_cpu(&target)) { + ret = perf_evsel__open_per_cpu(evsel, evsel_list->cpus, + group, group_fd); + if (ret) + goto check_ret; + return 0; + } + + if (!perf_target__has_task(&target) && (!group || evsel == first)) { attr->disabled = 1; attr->enable_on_exec = 1; } - return perf_evsel__open_per_thread(evsel, evsel_list->threads, - group, group_fd); + ret = perf_evsel__open_per_thread(evsel, evsel_list->threads, + group, group_fd); + if (!ret) + return 0; + /* fall through */ +check_ret: + if (ret && errno == EINVAL) { + if (!exclude_guest_missing && + (evsel->attr.exclude_guest || evsel->attr.exclude_host)) { + pr_debug("Old kernel, cannot exclude " + "guest or host samples.\n"); + exclude_guest_missing = true; + goto retry; + } + } + return ret; } /* @@ -972,7 +997,7 @@ static void print_stat(int argc, const char **argv) if (!csv_output) { fprintf(output, "\n"); fprintf(output, " Performance counter stats for "); - if (perf_target__no_task(&target)) { + if (!perf_target__has_task(&target)) { fprintf(output, "\'%s", argv[0]); for (i = 1; i < argc; i++) fprintf(output, " %s", argv[i]); @@ -1194,13 +1219,13 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used) } else if (big_num_opt == 0) /* User passed --no-big-num */ big_num = false; - if (!argc && perf_target__no_task(&target)) + if (!argc && !perf_target__has_task(&target)) usage_with_options(stat_usage, options); if (run_count <= 0) usage_with_options(stat_usage, options); /* no_aggr, cgroup are for system-wide only */ - if ((no_aggr || nr_cgroups) && perf_target__no_cpu(&target)) { + if ((no_aggr || nr_cgroups) && !perf_target__has_cpu(&target)) { fprintf(stderr, "both cgroup and no-aggregation " "modes only available in system-wide mode\n"); @@ -1213,9 +1238,9 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used) perf_target__validate(&target); if (perf_evlist__create_maps(evsel_list, &target) < 0) { - if (!perf_target__no_task(&target)) + if (perf_target__has_task(&target)) pr_err("Problems finding threads of monitor\n"); - if (!perf_target__no_cpu(&target)) + if (perf_target__has_cpu(&target)) perror("failed to parse CPUs map"); usage_with_options(stat_usage, options); |
