summaryrefslogtreecommitdiff
path: root/tools/perf/builtin-stat.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-stat.c')
-rw-r--r--tools/perf/builtin-stat.c47
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);