Skip to content

Commit 1b11482

Browse files
captain5050acmel
authored andcommitted
perf stat: Introduce skippable evsels
'perf stat' with no arguments will use default events and metrics. These events may fail to open even with kernel and hypervisor disabled. When these fail then the permissions error appears even though they were implicitly selected. This is particularly a problem with the automatic selection of the TopdownL1 metric group on certain architectures like Skylake: $ perf stat true Error: Access to performance monitoring and observability operations is limited. Consider adjusting /proc/sys/kernel/perf_event_paranoid setting to open access to performance monitoring and observability operations for processes without CAP_PERFMON, CAP_SYS_PTRACE or CAP_SYS_ADMIN Linux capability. More information can be found at 'Perf events and tool security' document: https://www.kernel.org/doc/html/latest/admin-guide/perf-security.html perf_event_paranoid setting is 2: -1: Allow use of (almost) all events by all users Ignore mlock limit after perf_event_mlock_kb without CAP_IPC_LOCK >= 0: Disallow raw and ftrace function tracepoint access >= 1: Disallow CPU event access >= 2: Disallow kernel profiling To make the adjusted perf_event_paranoid setting permanent preserve it in /etc/sysctl.conf (e.g. kernel.perf_event_paranoid = <setting>) $ This patch adds skippable evsels that when they fail to open won't cause termination and will appear as "<not supported>" in output. The TopdownL1 events, from the metric group, are marked as skippable. This turns the failure above to: $ perf stat perf bench internals synthesize Computing performance of single threaded perf event synthesis by synthesizing events on the perf process itself: Average synthesis took: 49.287 usec (+- 0.083 usec) Average num. events: 3.000 (+- 0.000) Average time per event 16.429 usec Average data synthesis took: 49.641 usec (+- 0.085 usec) Average num. events: 11.000 (+- 0.000) Average time per event 4.513 usec Performance counter stats for 'perf bench internals synthesize': 1,222.38 msec task-clock:u # 0.993 CPUs utilized 0 context-switches:u # 0.000 /sec 0 cpu-migrations:u # 0.000 /sec 162 page-faults:u # 132.529 /sec 774,445,184 cycles:u # 0.634 GHz (49.61%) 1,640,969,811 instructions:u # 2.12 insn per cycle (59.67%) 302,052,148 branches:u # 247.102 M/sec (59.69%) 1,807,718 branch-misses:u # 0.60% of all branches (59.68%) 5,218,927 CPU_CLK_UNHALTED.REF_XCLK:u # 4.269 M/sec # 17.3 % tma_frontend_bound # 56.4 % tma_retiring # nan % tma_backend_bound # nan % tma_bad_speculation (60.01%) 536,580,469 IDQ_UOPS_NOT_DELIVERED.CORE:u # 438.965 M/sec (60.33%) <not supported> INT_MISC.RECOVERY_CYCLES_ANY:u 5,223,936 CPU_CLK_UNHALTED.ONE_THREAD_ACTIVE:u # 4.274 M/sec (40.31%) 774,127,250 CPU_CLK_UNHALTED.THREAD:u # 633.297 M/sec (50.34%) 1,746,579,518 UOPS_RETIRED.RETIRE_SLOTS:u # 1.429 G/sec (50.12%) 1,940,625,702 UOPS_ISSUED.ANY:u # 1.588 G/sec (49.70%) 1.231055525 seconds time elapsed 0.258327000 seconds user 0.965749000 seconds sys $ The event INT_MISC.RECOVERY_CYCLES_ANY:u is skipped as it can't be opened with paranoia 2 on Skylake. With a lower paranoia, or as root, all events/metrics are computed. Signed-off-by: Ian Rogers <[email protected]> Tested-by: Kan Liang <[email protected]> Cc: Adrian Hunter <[email protected]> Cc: Ahmad Yasin <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Andi Kleen <[email protected]> Cc: Athira Rajeev <[email protected]> Cc: Caleb Biggers <[email protected]> Cc: Edward Baker <[email protected]> Cc: Florian Fischer <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: James Clark <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: John Garry <[email protected]> Cc: Kajol Jain <[email protected]> Cc: Kang Minchul <[email protected]> Cc: Leo Yan <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Perry Taylor <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Ravi Bangoria <[email protected]> Cc: Rob Herring <[email protected]> Cc: Samantha Alt <[email protected]> Cc: Stephane Eranian <[email protected]> Cc: Sumanth Korikkar <[email protected]> Cc: Suzuki Poulouse <[email protected]> Cc: Thomas Richter <[email protected]> Cc: Tiezhu Yang <[email protected]> Cc: Weilin Wang <[email protected]> Cc: Xing Zhengjun <[email protected]> Cc: Yang Jihong <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent 2a939c8 commit 1b11482

File tree

3 files changed

+43
-11
lines changed

3 files changed

+43
-11
lines changed

tools/perf/builtin-stat.c

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,13 @@ static enum counter_recovery stat_handle_error(struct evsel *counter)
667667
evsel_list->core.threads->err_thread = -1;
668668
return COUNTER_RETRY;
669669
}
670+
} else if (counter->skippable) {
671+
if (verbose > 0)
672+
ui__warning("skipping event %s that kernel failed to open .\n",
673+
evsel__name(counter));
674+
counter->supported = false;
675+
counter->errored = true;
676+
return COUNTER_SKIP;
670677
}
671678

672679
evsel__open_strerror(counter, &target, errno, msg, sizeof(msg));
@@ -1890,15 +1897,28 @@ static int add_default_attributes(void)
18901897
* caused by exposing latent bugs. This is fixed properly in:
18911898
* https://lore.kernel.org/lkml/[email protected]/
18921899
*/
1893-
if (metricgroup__has_metric("TopdownL1") && !perf_pmu__has_hybrid() &&
1894-
metricgroup__parse_groups(evsel_list, "TopdownL1",
1895-
/*metric_no_group=*/false,
1896-
/*metric_no_merge=*/false,
1897-
/*metric_no_threshold=*/true,
1898-
stat_config.user_requested_cpu_list,
1899-
stat_config.system_wide,
1900-
&stat_config.metric_events) < 0)
1901-
return -1;
1900+
if (metricgroup__has_metric("TopdownL1") && !perf_pmu__has_hybrid()) {
1901+
struct evlist *metric_evlist = evlist__new();
1902+
struct evsel *metric_evsel;
1903+
1904+
if (!metric_evlist)
1905+
return -1;
1906+
1907+
if (metricgroup__parse_groups(metric_evlist, "TopdownL1",
1908+
/*metric_no_group=*/false,
1909+
/*metric_no_merge=*/false,
1910+
/*metric_no_threshold=*/true,
1911+
stat_config.user_requested_cpu_list,
1912+
stat_config.system_wide,
1913+
&stat_config.metric_events) < 0)
1914+
return -1;
1915+
1916+
evlist__for_each_entry(metric_evlist, metric_evsel) {
1917+
metric_evsel->skippable = true;
1918+
}
1919+
evlist__splice_list_tail(evsel_list, &metric_evlist->core.entries);
1920+
evlist__delete(metric_evlist);
1921+
}
19021922

19031923
/* Platform specific attrs */
19041924
if (evlist__add_default_attrs(evsel_list, default_null_attrs) < 0)

tools/perf/util/evsel.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ void evsel__init(struct evsel *evsel,
290290
evsel->per_pkg_mask = NULL;
291291
evsel->collect_stat = false;
292292
evsel->pmu_name = NULL;
293+
evsel->skippable = false;
293294
}
294295

295296
struct evsel *evsel__new_idx(struct perf_event_attr *attr, int idx)
@@ -1725,9 +1726,13 @@ static int get_group_fd(struct evsel *evsel, int cpu_map_idx, int thread)
17251726
return -1;
17261727

17271728
fd = FD(leader, cpu_map_idx, thread);
1728-
BUG_ON(fd == -1);
1729+
BUG_ON(fd == -1 && !leader->skippable);
17291730

1730-
return fd;
1731+
/*
1732+
* When the leader has been skipped, return -2 to distinguish from no
1733+
* group leader case.
1734+
*/
1735+
return fd == -1 ? -2 : fd;
17311736
}
17321737

17331738
static void evsel__remove_fd(struct evsel *pos, int nr_cpus, int nr_threads, int thread_idx)
@@ -2109,6 +2114,12 @@ static int evsel__open_cpu(struct evsel *evsel, struct perf_cpu_map *cpus,
21092114

21102115
group_fd = get_group_fd(evsel, idx, thread);
21112116

2117+
if (group_fd == -2) {
2118+
pr_debug("broken group leader for %s\n", evsel->name);
2119+
err = -EINVAL;
2120+
goto out_close;
2121+
}
2122+
21122123
test_attr__ready();
21132124

21142125
/* Debug message used by test scripts */

tools/perf/util/evsel.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ struct evsel {
9595
bool weak_group;
9696
bool bpf_counter;
9797
bool use_config_name;
98+
bool skippable;
9899
int bpf_fd;
99100
struct bpf_object *bpf_obj;
100101
struct list_head config_terms;

0 commit comments

Comments
 (0)