Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf evsel: Fix write_backwards fallback

Commit b90dc17a5d14 "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: b90dc17a5d14 ("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: Wang Nan <wangnan0@huawei.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Arnaldo Carvalho de Melo and committed by
Arnaldo Carvalho de Melo
7da36e94 0aab2136

+10 -13
+10 -13
tools/perf/util/evsel.c
··· 1389 1389 if (perf_missing_features.lbr_flags) 1390 1390 evsel->attr.branch_sample_type &= ~(PERF_SAMPLE_BRANCH_NO_FLAGS | 1391 1391 PERF_SAMPLE_BRANCH_NO_CYCLES); 1392 - if (perf_missing_features.write_backward) 1392 + if (perf_missing_features.write_backward) { 1393 + if (evsel->overwrite) 1394 + return -EINVAL; 1393 1395 evsel->attr.write_backward = false; 1396 + } 1394 1397 retry_sample_id: 1395 1398 if (perf_missing_features.sample_id_all) 1396 1399 evsel->attr.sample_id_all = 0; ··· 1456 1453 err = -EINVAL; 1457 1454 goto out_close; 1458 1455 } 1459 - 1460 - if (evsel->overwrite && 1461 - perf_missing_features.write_backward) { 1462 - err = -EINVAL; 1463 - goto out_close; 1464 - } 1465 1456 } 1466 1457 } 1467 1458 ··· 1493 1496 * Must probe features in the order they were added to the 1494 1497 * perf_event_attr interface. 1495 1498 */ 1496 - if (!perf_missing_features.clockid_wrong && evsel->attr.use_clockid) { 1499 + if (!perf_missing_features.write_backward && evsel->attr.write_backward) { 1500 + perf_missing_features.write_backward = true; 1501 + goto fallback_missing_features; 1502 + } else if (!perf_missing_features.clockid_wrong && evsel->attr.use_clockid) { 1497 1503 perf_missing_features.clockid_wrong = true; 1498 1504 goto fallback_missing_features; 1499 1505 } else if (!perf_missing_features.clockid && evsel->attr.use_clockid) { ··· 1521 1521 PERF_SAMPLE_BRANCH_NO_FLAGS))) { 1522 1522 perf_missing_features.lbr_flags = true; 1523 1523 goto fallback_missing_features; 1524 - } else if (!perf_missing_features.write_backward && 1525 - evsel->attr.write_backward) { 1526 - perf_missing_features.write_backward = true; 1527 - goto fallback_missing_features; 1528 1524 } 1529 - 1530 1525 out_close: 1531 1526 do { 1532 1527 while (--thread >= 0) { ··· 2404 2409 "We found oprofile daemon running, please stop it and try again."); 2405 2410 break; 2406 2411 case EINVAL: 2412 + if (evsel->overwrite && perf_missing_features.write_backward) 2413 + return scnprintf(msg, size, "Reading from overwrite event is not supported by this kernel."); 2407 2414 if (perf_missing_features.clockid) 2408 2415 return scnprintf(msg, size, "clockid feature not supported."); 2409 2416 if (perf_missing_features.clockid_wrong)