|
@@ -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;
|
|
|
}
|
|
|
|
|
|
/*
|