Find the Right Performance Events with perf list
You copied an event name from a blog post into perf stat or perf record and watched it fail. perf list is how you read the actual catalogue your kernel and processor expose instead of guessing.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes for a first pass. The examples describe the perf interface shipped with linux-tools-common version 6.8.0-142.142, the version used for this guide.
This is a pure inspection workflow: nothing here starts a recording, touches kernel settings or changes a service. The installed wrapper may need a kernel-specific linux-tools package before it runs at all, so check that first rather than guessing at what your CPU supports.
1. Check the installed command
Confirm the binary resolves and ask its version:
$ command -v perf
$ perf --version
On this host, the perf wrapper warns that it cannot find a tool for kernel 6.8.0-139, even with linux-tools-common installed. That is a packaging mismatch, not evidence the event list is empty. Install the matching tools through your normal package process, then repeat the check. There is no reason to sudo just to list a version number.
Checkpoint
Continue only once perf --version prints a version rather than the missing-kernel-tools warning. The manpage describes the interface, but the actual events on offer still depend on the running kernel, the CPU, the PMUs and the tracepoints compiled in.
2. List the catalogue without descriptions
Start wide:
$ perf list --no-desc
With no category argument, perf list dumps every known symbolic event type. Descriptions are on by default, so --no-desc trims the output when you are searching or piping it somewhere. Every name printed is a candidate for the -e option on other perf commands, but appearing in the list is not a guarantee: your account might not be allowed to open it, and your processor might not implement it.
For a smaller, interactive slice:
$ perf list --no-desc | less
$ perf list --no-desc | grep -i 'cache'
Grepping rendered text is a quick way to scan, but it is fragile for automation and it throws away the surrounding context of a match. Keep the full listing on hand when you need to double-check what sits either side of a hit.
3. Choose the right event family
An argument narrows the listing to one category:
hworhardwarefor hardware events.sworsoftwarefor software events.cacheorhwcachefor hardware cache events.tracepointfor tracepoints.pmufor kernel-supplied PMU events.sdtfor statically defined tracepoints.metricormetricgroupfor metrics, or metric groups with their metrics.
$ perf list --no-desc hw cache
$ perf list --no-desc tracepoint
Anything that is not a recognised category name is treated as an event glob instead. A tracepoint can also be filtered by subsystem and pattern, like sched:*. Quote patterns containing *, or your shell will happily expand them against files in the current directory rather than passing them through:
$ perf list --no-desc 'sched:*'
$ perf list --no-desc '*cache*'
If the text you gave matches neither a category nor a glob, perf falls back to a plain substring search in event names. Handy for poking around, but it can return more than you bargained for compared with an exact name.
4. Inspect descriptions and resolution details
Once you have a likely candidate, ask for more:
$ perf list --long-desc 'cache'
$ perf list --details 'cycles'
--long-desc gives you the fuller description; --details shows how a named event actually resolves internally, plus any extra expressions perf stat computes from it. If you have inherited an old script referencing an event that no longer shows up by default, add --deprecated:
$ perf list --deprecated 'cycles'
Do not quietly swap in a similarly named event when the one you want is missing or deprecated. Write down the exact name and the machine you found it on: event meanings and availability are processor-specific, particularly for PMU and raw events.
5. Save a listing for review or automation
For something a parser can chew on, ask for JSON and write it out:
$ perf list --json --output=perf-events.json hw
Standard output is the default destination; --output= redirects to a file and --json picks the format. Check what you got before trusting it:
$ test -s perf-events.json && echo 'event listing written'
$ head -c 200 perf-events.json
Warning
Both redirection and --output= will silently overwrite an existing file of the same name. If an older listing matters, rename it or copy it first. This is the only state-changing step in the whole guide, and it only touches the named output file. Remove a temporary listing you no longer need with your normal file-management process.
6. Treat permissions and placeholders as separate problems
Listing an event and being allowed to use it are two different checks, and conflating them wastes debugging time. The manpage states that ordinary users generally get access only to context-switched events, the CPU PMU's predefined events, and some software events; other PMUs and global measurements are normally root-only. Tracepoints also need read access to /sys/kernel/tracing. If a later measurement fails, work out which of these it is before assuming you spelled the event wrong.
An administrator can loosen the kernel's kernel.perf_event_paranoid setting, but that is a security-sensitive, host-wide change and well outside a discovery guide. Do not touch it as a blind fix. If elevated access is genuinely approved for one specific measurement, run only that measurement with sudo, and note why it needed it.
A few PMU entries carry a literal ?, for example hv_gpci/dtbp_ptitc,phys_processor_idx=?/. That question mark is a placeholder, not part of the event name: it means you must supply a value before the event is usable. Fill it in from the displayed PMU syntax and the hardware documentation, not by trial and error.
Done means
- Version confirmed:
perf --versionsucceeds with tools that match the running kernel. - Catalogue searched: you can list everything or one family with
--no-desc. - Globs handled safely: shell patterns are quoted, and you know whether a result came from a category, a glob or a substring search.
- Detail pulled on demand: long descriptions, deprecated entries and resolution details were requested only when you actually needed them.
- Output checked: any JSON listing is non-empty, and any privilege change is a deliberate, documented decision rather than a reflex.