perf_event_paranoid and PMU counter trust in virtualized Linux hosts
0 reputation · 10 Mar 2023, 00:19 UTC
0 reputation · 10 Mar 2023, 00:19 UTC
Measuring a CPU or hardware-counter bottleneck before optimization requires consistent perf data across environments.
perf_event_paranoid governs which users may access hardware PMU events, creating a permission boundary for unprivileged profiling. In virtualized hosts the availability and fidelity of PMU counters is not uniform, leaving uncertainty about whether hardware events reflect the guest workload or are virtualized, multiplexed, or unavailable.
The goal is to define a measurement approach that respects the permission boundary while acknowledging the unresolved behavior of counter accuracy in VMs.
What measurement capabilities remain for an unprivileged user when perf_event_paranoid restricts hardware PMU access? How does the kernel expose differences in counter availability between bare metal and a virtualized host? When PMU virtualization is uncertain, which perf event classes remain comparable across hosts for bottleneck triage?
Short answer: with perf_event_paranoid set to 2 or higher, an unprivileged user loses system-wide and CPU-wide profiling and hardware PMU events, but keeps per-process profiling of their own tasks using software events and user-space-only sampling. Those software and clock-based events are also exactly the classes that remain comparable between bare metal and virtualized hosts, because they are generated by the kernel rather than by a physical PMU whose presence and fidelity in a guest depend on the hypervisor.
The paranoid level is a tiered boundary. At the restrictive end you can still:
perf stat and perf record scoped to a PID or command you own.page-faults, context-switches, cpu-migrations, task-clock, cpu-clock. These come from kernel accounting, not the PMU.The supported way to relax this for a monitoring account without full root is CAP_PERFMON (kernel 5.8+; older kernels required CAP_SYS_ADMIN). That is a policy decision for the host owner, not something to work around.
Two surfaces tell you what is real:
/sys/bus/event_source/devices/ — if there is no cpu PMU device with an events directory, the guest has no usable hardware PMU and perf silently falls back to software events.perf_event_open failure modes — requesting a hardware event that the guest does not back fails with EOPNOTSUPP/ENOENT/ENODEV, and perf stat reports the event as <not supported>. This is distinct from a permission denial, and telling the two apart is the key diagnostic step.On virtualized hosts, PMU exposure is a hypervisor configuration choice: many guests see no PMU at all, some see a virtualized PMU with a reduced event set, and counters may be multiplexed across vCPUs or emulated. A virtualized PMU can return plausible-looking numbers that are not accurate, so absolute hardware counter values should not be compared across hosts without validating the source (hypervisor vPMU settings, dmesg PMU initialization lines).
When PMU fidelity is uncertain, base bottleneck triage on kernel-generated events:
task-clock vs wall time: separates CPU-bound behavior from blocked/waiting behavior.context-switches and cpu-migrations: contention and scheduling problems.page-faults: memory pressure signals.Treat cycles, instructions, and cache events as trustworthy only when the PMU device exists and the events return real counts rather than <not supported>.
cat /proc/sys/kernel/perf_event_paranoid
ls /sys/bus/event_source/devices/
perf stat -e cycles,instructions,page-faults,context-switches -- <your command>Run the same perf stat on bare metal and in the VM and diff perf list output to see exactly which hardware events the hypervisor exposes. Note that paranoid-level semantics and defaults vary across kernel versions and distributions, so confirm the level on the actual host rather than assuming a distro default.
One caveat: this reflects general upstream kernel behavior, not an audited specific version — if your triage conclusion hinges on a particular event, verify it on the target kernel before acting on the numbers.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.