Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7da36e94 authored by Arnaldo Carvalho de Melo's avatar Arnaldo Carvalho de Melo Committed by Arnaldo Carvalho de Melo
Browse files

perf evsel: Fix write_backwards fallback

Commit b90dc17a "perf evsel: Add overwrite attribute and check
write_backward" misunderstood the 'order' should be obeyed in
__perf_evsel__open.

But the way this was done for attr.write_backwards was buggy, as we need
to check features in the inverse order of their introduction to the
kernel, so that a newer tool checks first the newest perf_event_attr
fields, detecting that the older kernel doesn't have support for them.

Also, we can avoid calling sys_perf_event_open() if we have already
detected the missing of write_backward.

Cc: He Kuang <hekuang@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Fixes: b90dc17a ("perf evsel: Add overwrite attribute and check write_backward")
Link: http://lkml.kernel.org/r/1466419645-75551-2-git-send-email-wangnan0@huawei.com
Link: http://lkml.kernel.org/r/20160616214724.GI13337@kernel.org


Signed-off-by: default avatarWang Nan <wangnan0@huawei.com>
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 0aab2136
Loading
Loading
Loading
Loading
+10 −13
Original line number Diff line number Diff line
@@ -1389,8 +1389,11 @@ static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
	if (perf_missing_features.lbr_flags)
		evsel->attr.branch_sample_type &= ~(PERF_SAMPLE_BRANCH_NO_FLAGS |
				     PERF_SAMPLE_BRANCH_NO_CYCLES);
	if (perf_missing_features.write_backward)
	if (perf_missing_features.write_backward) {
		if (evsel->overwrite)
			return -EINVAL;
		evsel->attr.write_backward = false;
	}
retry_sample_id:
	if (perf_missing_features.sample_id_all)
		evsel->attr.sample_id_all = 0;
@@ -1453,12 +1456,6 @@ static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
				err = -EINVAL;
				goto out_close;
			}

			if (evsel->overwrite &&
			    perf_missing_features.write_backward) {
				err = -EINVAL;
				goto out_close;
			}
		}
	}

@@ -1496,7 +1493,10 @@ static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
	 * Must probe features in the order they were added to the
	 * perf_event_attr interface.
	 */
	if (!perf_missing_features.clockid_wrong && evsel->attr.use_clockid) {
	if (!perf_missing_features.write_backward && evsel->attr.write_backward) {
		perf_missing_features.write_backward = true;
		goto fallback_missing_features;
	} else if (!perf_missing_features.clockid_wrong && evsel->attr.use_clockid) {
		perf_missing_features.clockid_wrong = true;
		goto fallback_missing_features;
	} else if (!perf_missing_features.clockid && evsel->attr.use_clockid) {
@@ -1521,12 +1521,7 @@ static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
			  PERF_SAMPLE_BRANCH_NO_FLAGS))) {
		perf_missing_features.lbr_flags = true;
		goto fallback_missing_features;
	} else if (!perf_missing_features.write_backward &&
			evsel->attr.write_backward) {
		perf_missing_features.write_backward = true;
		goto fallback_missing_features;
	}

out_close:
	do {
		while (--thread >= 0) {
@@ -2409,6 +2404,8 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target,
	"We found oprofile daemon running, please stop it and try again.");
		break;
	case EINVAL:
		if (evsel->overwrite && perf_missing_features.write_backward)
			return scnprintf(msg, size, "Reading from overwrite event is not supported by this kernel.");
		if (perf_missing_features.clockid)
			return scnprintf(msg, size, "clockid feature not supported.");
		if (perf_missing_features.clockid_wrong)