aboutsummaryrefslogtreecommitdiff
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.c40
1 files changed, 35 insertions, 5 deletions
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index c941bb640f49..1e5e9b270f5e 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -283,6 +283,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;
@@ -293,16 +295,39 @@ static int create_perf_stat_counter(struct perf_evsel *evsel,
attr->inherit = !no_inherit;
- if (system_wide)
- return perf_evsel__open_per_cpu(evsel, evsel_list->cpus,
+retry:
+ if (exclude_guest_missing)
+ evsel->attr.exclude_guest = evsel->attr.exclude_host = 0;
+
+ if (system_wide) {
+ ret = perf_evsel__open_per_cpu(evsel, evsel_list->cpus,
group, group_fd);
+ if (ret)
+ goto check_ret;
+ return 0;
+ }
+
if (!target_pid && !target_tid && (!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;
}
/*
@@ -463,8 +488,13 @@ static int run_perf_stat(int argc __used, const char **argv)
list_for_each_entry(counter, &evsel_list->entries, node) {
if (create_perf_stat_counter(counter, first) < 0) {
+ /*
+ * PPC returns ENXIO for HW counters until 2.6.37
+ * (behavior changed with commit b0a873e).
+ */
if (errno == EINVAL || errno == ENOSYS ||
- errno == ENOENT || errno == EOPNOTSUPP) {
+ errno == ENOENT || errno == EOPNOTSUPP ||
+ errno == ENXIO) {
if (verbose)
ui__warning("%s event is not supported by the kernel.\n",
event_name(counter));