|
@@ -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));
|