summaryrefslogtreecommitdiff
path: root/tools/perf
AgeCommit message (Collapse)Author
6 daysMerge tag 'perf-tools-for-v7.4-1-2026-10-30' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next Pull perf tool updates from Arnaldo Carvalho de Melo: - Support instruction tracking on arm64 for data type profiling, resolving stack, global, per-CPU and 'current' variable accesses, so that 'perf annotate --data-type' resolves types on arm64 the way it does on x86. - Port the Python scripts to the perf module and standalone execution, and improve the module: lazy sample callchains and event copies, GIL handling, better session/thread lookup, new treport, flamegraph and sqlite/postgres exporters. - Reenable and fix the attribute expectation test suite: per-PMU bit masks, other core PMUs' events, dummy tracking events, group checks and spelled out skip reasons. - perf trace: filter the target's tasks in BPF, open the BPF output event on every CPU, add an option to disable syscall augmentation and raise TRACE_AUG_MAX_BUF. - perf jitdump: harden record parsing, validating unwinding sizes and symbol names, byte-swapping debug entries via safe accessors and fixing frees on error paths. - perf annotate-data fixes: bound the member nesting recursion, resolve type DIEs in the debug file they came from, adjust the offset for flex-arrays and show the sample count in the data-type browser. - perf symbol and debug info: try linked debug files for DSOs, avoid repeated failing searches, set binary/symtab types for split kallsyms, JIT maps and the build-id cache, fix libbfd symbol loading. - perf config: serialize config file access with a mutex, add the DEFINE_MUTEX() and DO_ONCE() primitives and a robust process shared mutex, add the core.hybrid-merge option. - perf report: add --progress and --no-progress options. - perf mem: add a false sharing workload to 'perf test', request PERF_SAMPLE_CPU by default, use the IBS swfilt filter when available and decode L0 in the memory level. - perf test: take turns using the perf mlock budget in the mmaping tests, add the 'needs_mlock' suite flag, scope the probe based tests to their PID and make more tests non-exclusive. - perf vendor events intel: update events and metrics to TMA 5.2, refresh the event tables and fix umask encodings. - perf build: run shellcheck, mypy and pylint in parallel, make pylint opt-out with NO_PYLINT=1, fix clean and install dependencies. - Add a script and a 'make sync-headers' target to sync the tools/ copies of kernel headers with the kernel sources, plus the resulting syncs of the cpufeatures, KVM, fs, mount, fcntl, socket, rtnetlink, if_addr and sound headers. - Fix cs-etm HW_ID mapping synthesis for raw trace, queue teardown leaks and duplicate v0 global mappings. - Add a 'perf bench atomic' benchmark for atomic operations. - Filter events before creating lock_stat in 'perf lock contention'. - Add a 'perf test' case for events re-armed with PERF_EVENT_IOC_REFRESH. - Fix memory leaks on 'perf c2c' output fields and add function view stdio coverage to its test. - Fix a NULL dereference resolving callchains in 'perf machine'. - Optimize the libdw fallback when DWARF is missing and try the symbol file first when checking for debuginfo. - Don't call eprintf() in pr_debugN() when not verbose. - Don't delete cumulative caller entries before the stat_acc decays in 'perf report'. - Fix ring buffer cursor handling: keep the consumed cursor in forward mode and use the head selected by read_init. - Fix 'perf test mmap-basic' user rdpmc detection and only test userspace reading on supported platforms. - Build fixes: include sys/types.h for ssize_t, errno.h before kernel headers and fix jevents.py type annotations for mypy 2.x. * tag 'perf-tools-for-v7.4-1-2026-10-30' of git://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools-next: (425 commits) perf machine: Fix NULL deref in thread__resolve_callchain_sample() perf pmu-events: Fix jevents.py type annotations for mypy 2.x perf parse-events: Include errno.h before kernel headers perf print_insn: Include sys/types.h for ssize_t perf tests mmap-basic: Fix user rdpmc detection logic perf tests mmap-basic: Only test userspace reading on supported platforms perf mmap: Preserve the consumed cursor in forward mode perf mmap: Use the head selected by read_init perf hist: Do not delete cumulative caller entries before stat_acc decays perf debug: Avoid calling eprintf() in pr_debugN() when verbose < n perf libdw: Optimize fallback logic for missing DWARF tools headers: Sync KVM headers with the kernel sources tools headers: Sync UAPI sound/asound.h with the kernel sources tools headers: Sync UAPI linux/mount.h with the kernel sources tools headers: Sync UAPI linux/fs.h with the kernel sources tools headers: Sync UAPI linux/fcntl.h with the kernel sources tools headers: Sync linux/socket.h with the kernel sources tools arch x86: Sync the cpufeatures.h copy with the kernel sources tools headers UAPI: Sync linux/rtnetlink.h with the kernel sources tools headers UAPI: Sync linux/if_addr.h with the kernel sources ...
9 daysperf machine: Fix NULL deref in thread__resolve_callchain_sample()lvyating
When recording with -j stack, resolve_lbr_callchain_sample() can dereference a NULL 'chain' pointer while resolving the branch stack. $ perf record -j stack -e branches:u uname perf: Segmentation fault Fix it by checking 'chain' for NULL before dereferencing it. Fixes: 29be60c93d2d9300 ("perf build-id: Mark DSO in sample callchains") Reviewed-by: Ian Rogers <irogers@google.com> Reviewed-by: Shengming Hu <hu.shengming@zte.com.cn> Signed-off-by: lvyating <lv.yating@zte.com.cn> Tested-by: Ian Rogers <irogers@google.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Dai Hualiang <dai.hualiang@zte.com.cn> Cc: he.yilin@zte.com.cn Cc: Ian Rogers <irogers@google.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: James Clark <james.clark@linaro.org> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Qingtao Liu <liu.qingtao2@zte.com.cn> Cc: Shen Lin <shen.lin1@zte.com.cn> Cc: stable@vger.kernel.org Cc: ye.zhihao1@zte.com.cn Cc: zhang.cheng35@zte.com.cn Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
9 daysperf pmu-events: Fix jevents.py type annotations for mypy 2.xLalit Maganti
Since the build runs mypy whenever it is installed, the perf build fails with mypy 2.4 on 7 errors in jevents.py, e.g.: pmu-events/jevents.py:542: error: Item "None" of "str | None" has no attribute "replace" [union-attr] pmu-events/jevents.py:563: error: Item "None" of "BigCString | None" has no attribute "offsets" [union-attr] Both come from wrong annotations rather than from code that can see None: - unit_to_pmu() is annotated as returning Optional[str] but always returns a string, so JsonEvent.pmu is typed as optional where it is used as a str. - _bcs is set to None before the BigCString class is defined and only assigned an instance after it, so mypy types it as BigCString | None. Correct the return type and declare _bcs with its type instead of the None placeholder. The generated pmu-events.c and pmu-events-string.c are unchanged, and mypy 1.9 still passes. Fixes: b3e9c396d0acab27 ("perf build: Make mypy build test opt-out (NO_MYPY=1)") Signed-off-by: Lalit Maganti <lalitmaganti@gmail.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Ian Rogers <irogers@google.com> Cc: James Clark <james.clark@linaro.org> Cc: Namhyung Kim <namhyung@kernel.org> Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
9 daysperf parse-events: Include errno.h before kernel headersFlorian Fainelli
Building perf against uClibc fails in config_term_common(): util/parse-events.c:954:30: error: 'ERANGE' undeclared The kernel headers included before errno.h pull in asm/errno.h. uClibc's bits/errno.h undefines EDOM, EILSEQ and ERANGE before including linux/errno.h, but the kernel header include guards prevent these macros from being defined again. Include errno.h before the kernel headers so ERANGE remains defined. Fixes: 6b9c0261b3fb298b ("perf record: Add ratio-to-prev term") Reviewed-by: James Clark <james.clark@linaro.org> Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Faisal Bukhari <faisalbukhari523@gmail.com> Cc: Ian Rogers <irogers@google.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Qinxin Xia <xiaqinxin@huawei.com> Cc: Thomas Falcon <thomas.falcon@intel.com> Cc: Thomas Richter <tmricht@linux.ibm.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
9 daysperf print_insn: Include sys/types.h for ssize_tFlorian Fainelli
print_insn.h declares fprintf_insn_asm() with an ssize_t return type but does not include the header defining that type. This causes builds where stdio.h does not provide ssize_t to fail when compiling util/print_insn.c: util/print_insn.h:21:1: error: unknown type name 'ssize_t' Include sys/types.h so the header provides its own dependency for ssize_t. Fixes: 218c200f677d8af4 ("perf script: Consolidate capstone print functions") Reviewed-by: James Clark <james.clark@linaro.org> Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: Ian Rogers <irogers@google.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
9 daysperf tests mmap-basic: Fix user rdpmc detection logicJames Clark
RISC-V and Arm control userspace counter access through /proc/sys/kernel/perf_user_access. Add that as a fallback to set_user_read() so the test can exercise both enabled and disabled states on those platforms. Document disabled, enabled and legacy states in user_read_state and fail on values outside the known 0-2 range. Preserve and restore any value in this range, rather than just 0 or 1. Skip when the control files exist but can't be written to (USER_READ_ERR_PERM). We can't rely on always being able to write to them when an exclude_kernel=0 event can be opened because opening events might succeed for non-root users when perf_event_paranoid=-1. This test isn't run on unsupported platforms since the previous commit, so we can simplify the following things: * Test that cap_user_rdpmc is always equal to the requested state rather than checking it only when disabled. As long as we stop setting the cap in the attr unconditionally on Arm, this is ok. * Remove the USER_READ_UNKNOWN/rdpmc_supported fallback in the checks. Now the expected state is always the one requested. USER_READ_UNKNOWN only controls whether to skip restoration of the state on unsupported platforms, so call it USER_READ_ERR_NO_FILE. Signed-off-by: James Clark <james.clark@linaro.org> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Albert Ou <aou@eecs.berkeley.edu> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Alexandre Ghiti <alex@ghiti.fr> Cc: Ian Rogers <irogers@google.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Leo Yan <leo.yan@arm.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Michael Petlan <mpetlan@redhat.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Palmer Dabbelt <palmer@dabbelt.com> Cc: Paul Walmsley <pjw@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Assisted-by: Codex:GPT-6.1-Sol [Re-write: [Re-write to fix bugs in set_user_read() and simplify tests] Signed-off-by: Qiao Zhao <qzhao@redhat.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
9 daysperf tests mmap-basic: Only test userspace reading on supported platformsJames Clark
mmap_user_read_instr() and mmap_user_read_instr_disabled() are the same test for platforms that libperf doesn't support userspace counter reading for. Only run the 'enabled' test for platforms that do support it in order to simplify it in the next commit and not run the same test twice. The test can then assert stronger guarantees and have fewer edge cases to handle as we know it only runs in places where 'rdmpc_supported' will be true. "unsupported" hasn't been a relevant skip reason since commit 588d22b40480 ("perf test: Expand user space event reading (rdpmc) tests") added the UNKNOWN fallback for unsupported platforms. Remove it and leave only "permissions". Signed-off-by: James Clark <james.clark@linaro.org> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Albert Ou <aou@eecs.berkeley.edu> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Alexandre Ghiti <alex@ghiti.fr> Cc: Ian Rogers <irogers@google.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Leo Yan <leo.yan@arm.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Michael Petlan <mpetlan@redhat.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Palmer Dabbelt <palmer@dabbelt.com> Cc: Paul Walmsley <pjw@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Qiao Zhao <qzhao@redhat.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
9 daysperf mmap: Use the head selected by read_initPaul Moses
perf_mmap__push() reads the producer head before calling perf_mmap__read_init(), which reads it again to select the range to copy. If the producer advances between those reads, push() copies through the newer head but stores the earlier head in prev. The next drain starts at that earlier position and can write the same records to perf.data again. Use the head selected by read_init(): end for forward buffers and start for overwrite buffers. Save it before the copy loop advances start so prev matches the range that was copied. Fixes: 8872481bd04850b1 ("perf mmap: Introduce perf_mmap__read_init()") Signed-off-by: Paul Moses <p@1g4.org> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Ian Rogers <irogers@google.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: James Clark <james.clark@linaro.org> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Kan Liang <kan.liang@intel.com> Cc: Kan Liang <kan.liang@linux.intel.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
9 daysperf hist: Do not delete cumulative caller entries before stat_acc decaysIan Rogers
When symbol_conf.cumulate_callchain is enabled (the default in 'perf top -g'), callchain parent/caller entries have he->stat.period == 0 and accumulate their period in he->stat_acc->period. hists__decay_entry() decays both he->stat.period and he->stat_acc->period, but only checks if he->stat.period == 0 as the return condition for deleting the entry in hists__decay_entries(). As a result, every callchain caller entry with 0 self-period is unconditionally deleted from the histogram on the first decay pass, destroying its callchain tree while it still has non-zero cumulative period. Only mark an entry for deletion in hists__decay_entry() when both he->stat.period == 0 and (when cumulate_callchain is active) he->stat_acc->period == 0. Signed-off-by: Ian Rogers <irogers@google.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alessio Podda <aleph.pi.gh@gmail.com> Cc: Alireza Haghdoost <haghdoost@uber.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: James Clark <james.clark@linaro.org> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Michael Liang <mliang@purestorage.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Shimin Guo <shimin.guo@skydio.com> Cc: Tanushree Shah <tshah@linux.ibm.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
9 daysperf debug: Avoid calling eprintf() in pr_debugN() when verbose < nIan Rogers
pr_debugN() unconditionally evaluated its arguments and called eprintf() -> veprintf() before checking if verbose >= n. In hot paths such as dso__load_sym_internal(), two pr_debug4() calls per symbol accounted for ~15% of total CPU time in 'perf top' even at the default verbose == 0. Guard eprintf() in pr_debugN() with unlikely(verbose >= (n)) and define pr_debug() in terms of pr_debugN(1, ...). In test__parsing_callback() (tools/perf/tests/pmu-events.c), move the test_generic_metric(mexp, 0) call out of the pr_debug() argument list so the metric evaluation continues to run during 'perf test' when verbose == 0. Signed-off-by: Ian Rogers <irogers@google.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alessio Podda <aleph.pi.gh@gmail.com> Cc: Alireza Haghdoost <haghdoost@uber.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: James Clark <james.clark@linaro.org> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Michael Liang <mliang@purestorage.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Shimin Guo <shimin.guo@skydio.com> Cc: Tanushree Shah <tshah@linux.ibm.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
9 daysperf libdw: Optimize fallback logic for missing DWARFIan Rogers
When libdw encounters a DWARF definition it cannot accurately un-inline or an address block natively missing structural line maps, dwfl_module_getsrc() returns NULL. Previously, libdw__addr2line() returned -1 in both dwfl_module_getdwarf() and dwfl_module_getsrc() failure paths while addr2line() in srcline.c only stopped its fallback loop on ret > 0. This caused perf's addr2line_style loop to fall back to llvm, libbfd, and the cmd__addr2line() subprocess wrapper on every unmapped address or stripped DSO. Update the addr2line_style pipeline return semantics consistently: 1. Backends return 0 to denote conclusively missing information (e.g. valid ELF but no DWARF inside, or parsed DWARF with no mapped lines), stopping the fallback loop. 2. Backends (and uncompiled stubs) return < 0 to denote initialization or backend errors, instructing the loop to iterate to the next configured fallback. 3. Backends return > 0 on successful source line resolution. Fixes: bf96e296d52d74a1 ("perf libdw: Fix Dwfl discovery with split files") Signed-off-by: Ian Rogers <irogers@google.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alessio Podda <aleph.pi.gh@gmail.com> Cc: Alireza Haghdoost <haghdoost@uber.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: James Clark <james.clark@linaro.org> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Michael Liang <mliang@purestorage.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Shimin Guo <shimin.guo@skydio.com> Cc: Tanushree Shah <tshah@linux.ibm.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
13 daysMerge tag 'modules-7.4-rc1' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/modules/linux Pull module updates from Petr Pavlu: - Ignore local labels and mapping symbols during module load These symbols were already ignored during kallsyms address-to-symbol lookups. Filter them out earlier during module loading to reduce lookup overhead and prevent them from appearing in /proc/kallsyms. - Fix potentially incorrect access of SetOnce<T> when setting Rust module parameters. - Fix a potential read of an uninitialized count when printing taint information for unloaded modules. - Allocate the kmod argument array using kmalloc_array() in preparation for conversion to type-aware allocators. - Clean up includes in linux/kmod.h Add explicit includes of linux/umh.h to files that use usermode helpers. Then clean up the #include list in linux/kmod.h, notably removing the compatibility linux/umh.h include. - Remove the error-injection.h include from linux/module.h Add explicit includes of linux/error-injection.h to files that use the ALLOW_ERROR_INJECTION() macro and currently rely on it being provided indirectly via linux/module.h. Then remove the unnecessary linux/error-injection.h include from linux/module.h. - Replace __MODULE_STRING() with __stringify() in various drivers in preparation for removing the former macro. * tag 'modules-7.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/modules/linux: drivers: Replace __MODULE_STRING() with __stringify() module: Fix uninitialized count read of unloaded taint tracking record rust: module_param: Fix potentially incorrect access of `SetOnce<T>` module: Remove the error-injection.h include from linux/module.h drm/xe: Include error-injection.h for ALLOW_ERROR_INJECTION() drm/i915: Include error-injection.h for ALLOW_ERROR_INJECTION() syscalls: Include error-injection.h for ALLOW_ERROR_INJECTION() net: Include error-injection.h for ALLOW_ERROR_INJECTION() block: Include error-injection.h for ALLOW_ERROR_INJECTION() module: Bring includes in linux/kmod.h up to date time/jiffies: Include linux/sysctl.h for proc_int_u2k_conv_uop(), ... umh, treewide: Explicitly include linux/umh.h where needed modules/kmod: Allocate argv with kmalloc_array() module/kallsyms: Ignore local labels and mapping symbols during module load module/kallsyms: Refactor current symbol filtering into is_core_symbol() module/kallsyms: Rename is_mapping_symbol() to is_ignored_kernel_symbol()
13 daystools headers: Sync UAPI sound/asound.h with the kernel sourcesArnaldo Carvalho de Melo
To pick up the changes in: 91415225fbfb ("ALSA: uapi: Drop __bitwise and __force prefix") 86cac980c966 ("ALSA: control: add ioctl to retrieve full card components") That introduce these new entries in the string tables: $ tools/perf/trace/beauty/sndrv_ctl_ioctl.sh tools/perf/trace/beauty/include/uapi/sound > before.txt $ cp include/uapi/sound/asound.h tools/perf/trace/beauty/include/uapi/sound/asound.h $ tools/perf/trace/beauty/sndrv_ctl_ioctl.sh tools/perf/trace/beauty/include/uapi/sound > after.txt $ diff -u before.txt after.txt @@ -1,6 +1,7 @@ static const char *sndrv_ctl_ioctl_cmds[] = { [0x00] = "PVERSION", [0x01] = "CARD_INFO", + [0x02] = "CARD_BYTES", [0x10] = "ELEM_LIST", [0x11] = "ELEM_INFO", [0x12] = "ELEM_READ", This addresses this perf build warning: Warning: Kernel ABI header differences: diff -u tools/perf/trace/beauty/include/uapi/sound/asound.h include/uapi/sound/asound.h Please see tools/include/uapi/README for further details. Reviewed-by: Ian Rogers <irogers@google.com> Cc: Maciej Strozek <mstrozek@opensource.cirrus.com> Cc: Takashi Iwai <tiwai@suse.de> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
13 daystools headers: Sync UAPI linux/mount.h with the kernel sourcesArnaldo Carvalho de Melo
To pick up the changes in: 73b40395c71c ("mount: add OPEN_TREE_DROP_MNTNS_MOUNTS") That don't result in changes to the string tables generated from this header. This addresses this perf build warning: Warning: Kernel ABI header differences: diff -u tools/perf/trace/beauty/include/uapi/linux/mount.h include/uapi/linux/mount.h Please see tools/include/uapi/README for further details. Reviewed-by: Ian Rogers <irogers@google.com> Cc: Kir Kolyshkin <kolyshkin@gmail.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
13 daystools headers: Sync UAPI linux/fs.h with the kernel sourcesArnaldo Carvalho de Melo
To pick up the changes in: 21a62663d473 ("fs: fix typos in comments") 338964881982 ("mm/pagemap: add PAGE_IS_ACCESSED for RWP tracking") That don't result in changes to the string tables generated from this header. This addresses this perf build warning: Warning: Kernel ABI header differences: diff -u tools/perf/trace/beauty/include/uapi/linux/fs.h include/uapi/linux/fs.h Please see tools/include/uapi/README for further details. Reviewed-by: Ian Rogers <irogers@google.com> Cc: Hemanth Selam <hemanth.selam@gmail.com> Cc: Kiryl Shutsemau (Meta) <kas@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
13 daystools headers: Sync UAPI linux/fcntl.h with the kernel sourcesArnaldo Carvalho de Melo
To pick up the changes in: cdf930a00949 ("fs: support FD_FAILFS_ROOT in fchdir()") That don't result in changes to the string tables generated from this header. This addresses this perf build warning: Warning: Kernel ABI header differences: diff -u tools/perf/trace/beauty/include/uapi/linux/fcntl.h include/uapi/linux/fcntl.h Please see tools/include/uapi/README for further details. Reviewed-by: Ian Rogers <irogers@google.com> Cc: Christian Brauner <brauner@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-22tools headers: Sync linux/socket.h with the kernel sourcesArnaldo Carvalho de Melo
To pick up the changes in: be3a5e06b962 ("net: add SO_PASSPIDFD_THREAD to get a thread-specific SCM_PIDFD") 5bd369c05576 ("net: Add connect_socket() helper") That don't result in changes to the string tables generated from this header. This addresses this perf build warning: Warning: Kernel ABI header differences: diff -u tools/perf/trace/beauty/include/linux/socket.h include/linux/socket.h Please see tools/include/uapi/README for further details. Reviewed-by: Ian Rogers <irogers@google.com> Acked-by: Mahe Tardy <mahe.tardy@gmail.com> Cc: Christian Brauner <brauner@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-22perf tools: Add script and make target to sync the header copies with the kernelArnaldo Carvalho de Melo
This is to be used by the perf maintainers to sync the header copies with the kernel originals, see the description below for how it works. A copy is left alone when only the tools/ side changed or when it carries intentional edits, and both sides having content the other lacks needs a manual look, --force then syncs and records the tools/ additions that are dropped. $ tools/perf/scripts/sync-headers.sh --help Usage: sync-headers.sh [OPTIONS] Sync tools/ header copies with the kernel sources and create commits. Options: -n, --dry-run Show what would be done without making changes -N, --no-build Skip the perf build verification step -C, --no-commit Copy files but do not create git commits -f, --filter PAT Only process headers matching PAT (substring match against the kernel-side path) -F, --force Sync also when both copies have content the other lacks, after manual investigation; tools/ additions dropped are recorded in the commit -o, --output DIR Build output directory (default: /tmp/build/perf-tools-1000) -v, --verbose Show more details -h, --help Show this help Environment: SIGN_OFF_NAME Override git user.name for Signed-off-by SIGN_OFF_EMAIL Override git user.email for Signed-off-by OUTPUT_DIR Build output directory Through make: SYNC_HEADERS_ARGS Options to pass to this script, e.g.: make -C tools/perf sync-headers SYNC_HEADERS_ARGS='-n' The script: 1. Runs 'make -C tools/perf check-headers' to find stale copies. 2. For each stale header, identifies the kernel commits that changed it, including the merges that brought content of their own. 3. Copies the kernel header into the tools/ tree, skipping it when only the tools/ copy changed (it is ahead) or when it carries intentional edits, and stopping for manual investigation when both sides have content the other lacks. 4. For beauty headers, runs the relevant beauty script(s) before and after, showing new/changed string table entries. 5. Builds perf and the other consumers of the header to verify nothing breaks. 6. Creates a git commit per header (or group) with the standard commit message format. $ It is also available as: $ make -C tools/perf sync-headers ==> Running check-headers to detect stale copies... Stale headers found: tools/include/uapi/linux/if_addr.h include/uapi/linux/if_addr.h tools/include/uapi/linux/kvm.h include/uapi/linux/kvm.h tools/include/uapi/linux/perf_event.h include/uapi/linux/perf_event.h ... tools/perf/trace/beauty/include/uapi/sound/asound.h include/uapi/sound/asound.h ==> Processing: include/uapi/linux/if_addr.h Kernel commits since last sync: 7cb8198761e6 ("net: ipv4: report multicast group user count") ==> Copied include/uapi/linux/if_addr.h -> tools/include/uapi/linux/if_addr.h ==> Build-testing consumers of if_addr.h: perf (tools/perf) ==> Build OK. ==> Committed: tools headers UAPI: Sync linux/if_addr.h with the kernel sources ==> Processing: include/uapi/linux/perf_event.h Warning: tools/include/uapi/linux/perf_event.h is ahead of the kernel sources, leaving it alone ==> Processing: include/uapi/linux/rtnetlink.h Kernel commits since last sync: cc17e386f8a5 ("ipv6: add ip6_del_rt_reason()") ==> Copied include/uapi/linux/rtnetlink.h -> tools/include/uapi/linux/rtnetlink.h ==> Build-testing consumers of rtnetlink.h: libbpf (tools/lib/bpf) bpftool (tools/bpf/bpftool) perf (tools/perf) ==> Build OK. ==> Committed: tools headers UAPI: Sync linux/rtnetlink.h with the kernel sources ... ==> Processing: include/linux/socket.h Kernel commits since last sync: be3a5e06b962 ("net: add SO_PASSPIDFD_THREAD to get a thread-specific SCM_PIDFD") 5bd369c05576 ("net: Add connect_socket() helper") ==> Copied include/linux/socket.h -> tools/perf/trace/beauty/include/linux/socket.h ==> Build-testing consumers of socket.h: perf (tools/perf) ==> Build OK. ==> Committed: tools headers: Sync linux/socket.h with the kernel sources ... ==> Processing group: KVM headers (3 files) ... ==> Build-testing consumers of group KVM headers: perf (tools/perf) ==> Build OK. ... ========================================= Summary ========================================= ==> Synced successfully (11): tools/include/uapi/linux/if_addr.h tools/include/uapi/linux/rtnetlink.h tools/arch/x86/include/asm/cpufeatures.h tools/perf/trace/beauty/include/linux/socket.h tools/perf/trace/beauty/include/uapi/linux/fcntl.h tools/perf/trace/beauty/include/uapi/linux/fs.h tools/perf/trace/beauty/include/uapi/linux/mount.h tools/perf/trace/beauty/include/uapi/sound/asound.h tools/include/uapi/linux/kvm.h tools/arch/powerpc/include/uapi/asm/kvm.h tools/arch/arm64/include/uapi/asm/kvm.h Warning: tools/ copies ahead of the kernel, left alone (2): tools/include/uapi/linux/perf_event.h tools/arch/x86/include/uapi/asm/perf_regs.h Error: Left for manual investigation (2): tools/include/linux/gfp_types.h tools/arch/x86/include/asm/msr-index.h Warning: Headers still out of sync: tools/include/uapi/linux/perf_event.h include/uapi/linux/perf_event.h tools/include/linux/gfp_types.h include/linux/gfp_types.h tools/arch/x86/include/asm/msr-index.h arch/x86/include/asm/msr-index.h tools/arch/x86/include/uapi/asm/perf_regs.h arch/x86/include/uapi/asm/perf_regs.h Reviewed-by: Ian Rogers <irogers@google.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Ian Rogers <irogers@google.com> Cc: James Clark <james.clark@linaro.org> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Namhyung Kim <namhyung@kernel.org> Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-22perf test: Add test for events re-armed with PERF_EVENT_IOC_REFRESHFrancesco Nigro
Open a sampling event with sample_period 1, re-arm it with PERF_EVENT_IOC_REFRESH from its overflow signal handler, as self-profilers such as async-profiler do, and check that each of 1000 events delivers a signal. One case uses a software event (page faults), the other the syscalls:sys_enter_getppid tracepoint. The signal is a real-time one, so overflows cannot be coalesced, and the page fault buffer is marked MADV_NOHUGEPAGE so that each touched page faults once. The tracepoint case fails since commit 18dbcbfabfffc4a5 ("perf: Fix the POLL_HUP delivery breakage") only the first overflow is delivered. The re-arming ioctl succeeds, but the event count stays at 1. It passes on the parent commit. The software case passes on both. The test was written with an AI coding assistant (Claude) from a standalone reproducer; I reviewed it and ran it in QEMU on current mainline, on that commit and on its parent. Reviewed-by: Ian Rogers <irogers@google.com> Signed-off-by: Francesco Nigro <nigro.fra@gmail.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-22perf annotate-arm64: Support 'mrs' instruction to track 'current' pointerTengda Wu
Extend update_insn_state_arm64() to handle the 'mrs' instruction, enabling the tracking of the 'current' task pointer in the kernel. On arm64, the kernel uses the 'sp_el0' system register to store the address of the currently executing 'struct task_struct'. This is typically accessed via the 'get_current()' inline function, resulting in the instruction 'mrs xN, sp_el0'. To resolve the data type of the target register, first verify the access is to 'sp_el0' within a kernel DSO. Then, locate the 'get_current()' inline function's DWARF Die at the current PC and extract its return type (which should be 'struct task_struct*'). A real-world example is shown below: ffff8000800deee8 <kthread_blkcg>: ffff8000800deef0: mrs x0, sp_el0 // x0 = current * ffff8000800deef4: ldr w1, [x0, #44] Before this commit, the type flow starts with no information: chk [c] reg0 offset=0x2c ok=0 kind=0 cfa : no type information final result: no type information After this commit, the tracker identifies the 'current' pointer from the system register: mrs [8] sp_el0 -> reg0 type='struct task_struct*' chk [c] reg0 offset=0x2c ok=1 kind=1 (struct task_struct*) : Good! found by insn track: 0x2c(reg0) type-offset=0x2c final result: type='struct task_struct' Reviewed-by: Ian Rogers <irogers@google.com> Reviewed-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Li Huafei <lihuafei1@huawei.com> Signed-off-by: Tengda Wu <wutengda@huaweicloud.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-22perf annotate-arm64: Support per-cpu variable access trackingTengda Wu
Extend update_insn_state_arm64() to handle per-cpu variable addressing. On arm64, per-cpu variables are accessed by adding a per-cpu offset (typically from the '__per_cpu_offset' array) to the address of a global variable or a structure field with '__percpu' modifier (e.g., 's32 __percpu *counters' in struct percpu_counter). This results in instruction patterns like: ldr x0, [x6, x5] // Pattern A: direct load per-cpu instance add x0, x6, x5 // Pattern B: compute per-cpu address where x6 holds the per-cpu offset retrieved from: adrp x4, <page> add x4, x4, #offset // x4 = &__per_cpu_offset ldr x6, [x4, w0, sxtw #3] // x6 = __per_cpu_offset[cpu] And x5 holds the base address being offset, which can come from one of two cases: Case 1: global variable adrp x5, <page> add x5, x5, #offset // x5 = &global_var Case 2: '__percpu' field embedded in a structure ldr x5, [x25, #32] // x5 = &percpu_field To handle such cases: 1. Identify per-cpu base initialization: Detect 'adrp + ldr' pairs that resolve to the '__per_cpu_offset' symbol and mark the destination register as TSR_KIND_PERCPU_BASE. 2. Propagate type information: During subsequent 'ldr' or 'add' instructions, if one register is TSR_KIND_PERCPU_BASE, attempt to resolve the type from the other register. A real-world example is shown below: ffff8000808f2d28 <cppc_set_perf>: ffff8000808f2d38: adrp x2, ffff800082033000 ffff8000808f2d3c: add x5, x2, #0x3f8 // x5 = &__per_cpu_offset ffff8000808f2d44: adrp x2, ffff800081f73000 ffff8000808f2d48: add x2, x2, #0x6b8 // x2 = &cpu_pcc_subspace_idx ffff8000808f2d6c: ldr x5, [x5, w0, sxtw #3] // x5 = __per_cpu_offset[cpu] * ffff8000808f2d80: ldr w23, [x5, x2] // per_cpu_var(cpu_pcc_subspace_idx) Before this commit, the tracker could not link x5 back to a per-cpu context, resulting in an incorrect data type resolution: adrp [10] global addr=0xffff800082033000 -> reg2 add [14] global 0x3f8(reg2) -> reg5 adrp [1c] global addr=0xffff800081f73000 -> reg2 add [20] global 0x6b8(reg2) -> reg2 ldr [44] global (reg5, reg0) -> reg5 type='long unsigned int[]' size=0x1000 chk [58] reg5 offset=0 ok=1 kind=1 (long unsigned int[]) : Good! found by insn track: 0(reg5, reg2) type-offset=0 final result: type='long unsigned int' size=0x8 After this commit, the tracker correctly identifies the per-cpu flow and resolves the actual variable type: ldr [44] global (reg5, reg0) -> reg5 percpu base chk [58] reg5 offset=0 ok=1 kind=2 percpu var : retry chk [58] reg2 offset=0 ok=1 kind=7 global addr : Good! found by insn track: 0(reg5, reg2) type-offset=0 final result: type='int' size=0x4 Reviewed-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Tengda Wu <wutengda@huaweicloud.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-22perf annotate-arm64: Support 'adrp' instruction to track global variablesTengda Wu
Extend update_insn_state_arm64() to track global variable types calculated via page-relative addressing. On arm64, global variables are typically accessed by first calculating the page address using 'adrp', followed by an 'add' or 'ldr' to get the specific symbol address. Without tracking 'adrp', the instruction tracker loses the base address, making it impossible to resolve global symbols and their associated DWARF types. Introduce TSR_KIND_GLOBAL_ADDR to represent a partial global address state. When encountering 'adrp', store the page-aligned target address in the register's type state. Upon a subsequent 'add' or 'ldr' instruction that references a TSR_KIND_GLOBAL_ADDR register, combine the page address with the immediate offset. A real-world example is shown below: ffff80008032e008 <folios_put_refs>: ffff80008032e048: adrp x24, ffff80008202f000 <nr_cpu_ids> ffff80008032e050: add x24, x24, #0xd40 * ffff80008032e078: ldr x0, [x24] Before this commit, x24 was unknown, leading to no type information: chk [70] reg24 offset=0 ok=0 kind=0 cfa : no type information final result: no type information After this commit, the tracker correctly follows the adrp/add flow: adrp [40] global addr=0xffff80008202f000 -> reg24 add [48] global 0xd40(reg24) -> reg24 chk [70] reg24 offset=0 ok=1 kind=7 global addr : Good! final result: type='struct folio*' Reviewed-by: Ian Rogers <irogers@google.com> Reviewed-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Li Huafei <lihuafei1@huawei.com> Signed-off-by: Tengda Wu <wutengda@huaweicloud.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-22perf annotate-arm64: Support 'add' instruction trackingTengda Wu
Extend update_insn_state_arm64() to track 'add' instructions for structure member address calculation. Unlike x86, the arm64 'add' instruction has an extra base register among its source operands. Therefore, in terms of propagating the data type, it is essentially performing a 'mov', except that before the 'mov', it first needs to be updated by adding the offset or reg2. A real-world example is shown below: ffff80008001c9a8 <flush_ptrace_hw_breakpoint>: ffff80008001c9c4: add x19, x0, #0xeb8 // x0 (task_struct*) + 0xeb8 -> x19 * ffff80008001c9d0: ldr x0, [x19] Before this commit, the type flow broke at the 'add' instruction, leaving the subsequent load with no type information: chk [28] reg19 offset=0 ok=0 kind=0 cfa : no type information final result: no type information After this commit, the tracker correctly follows the member address calculation: var [0] reg0 offset 0 type='struct task_struct*' add [1c] address of 0xeb8(reg0) -> reg19 type='struct task_struct*' chk [28] reg19 offset=0 ok=1 kind=1 (struct task_struct*) : Good! found by insn track: 0(reg19) type-offset=0xeb8 final result: type='struct task_struct' Reviewed-by: Ian Rogers <irogers@google.com> Reviewed-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Tengda Wu <wutengda@huaweicloud.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-22perf annotate-arm64: Support 'mov' instruction trackingTengda Wu
Extend update_insn_state_arm64() to support register-to-register and immediate-to-register 'mov' instructions. For register-to-register 'mov' (e.g., mov dreg, sreg), propagate data type information from the source register to the destination register. For immediate-to-register 'mov' (e.g., mov dreg, #imm), store the immediate value in the destination register's imm_value field and set its kind to TSR_KIND_CONST, allowing subsequent instructions to resolve it as a constant. A real-world example is shown below: ffff8000803eebf8 <get_vma_policy>: ffff8000803eec20: mov x21, x0 // x0 (struct vm_area_struct*) -> x21 ffff8000803eec28: ldr x2, [x0, #112] ffff8000803eec2c: cbz x2, ffff8000803eec94 <get_vma_policy+0x9c> * ffff8000803eec94: ldr x0, [x21, #152] Before this commit, the type of x21 was unknown, causing the subsequent inference to fail: var [0] reg0 offset 0 type='struct vm_area_struct*' size=0x8 chk [9c] reg21 offset=0x98 ok=0 kind=0 cfa : no type information final result: no type information After this commit, the type of x21 is correctly inferred as 'vm_area_struct': var [0] reg0 offset 0 type='struct vm_area_struct*' size=0x8 mov [28] reg0 -> reg21 type='struct vm_area_struct*' size=0x8 chk [9c] reg21 offset=0x98 ok=1 kind=1 (struct vm_area_struct*) : Good! found by insn track: 0x98(reg21) type-offset=0x98 final result: type='struct vm_area_struct' size=0xb0 Reviewed-by: Ian Rogers <irogers@google.com> Reviewed-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Tengda Wu <wutengda@huaweicloud.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-22perf annotate-arm64: Support stack variable trackingTengda Wu
Extend update_insn_state_arm64() to track data types stored on the stack. The implementation handles: 1. Stack Loads: Identify when a register is loaded from a stack slot and update the register's type state based on the tracked stack content or compound member types. 2. Stack Stores: Update or create new stack state entries when a tracked register type is stored to the stack. Similar to loads, stores also support saving one or two registers (in the case of 'stp'). Therefore, propagate_store_reg_state() is introduced. With these changes, the instruction tracker can now follow data types as they move between registers and memory, specifically for function local variables and compiler-spilled values on arm64. Reviewed-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Tengda Wu <wutengda@huaweicloud.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-22perf annotate-x86: Delete stale stack state on store of untracked registerTengda Wu
When a register without a tracked type is stored to a stack slot that previously held a valid type, the code currently performs an early return. This leaves the old type information intact in the stack state. As a result, a stale type bug occurs: 1. A tracked register is stored into a stack slot. 2. The register becomes untracked/invalid (e.g., across a function call). 3. The now-untracked register is stored into the same stack slot. 4. Subsequent loads from that slot erroneously pick up the old stale type because the stack entry was never invalidated. Fix this by introducing delete_stack_state() to search and free a stack entry for a given offset. When storing an untracked or invalid source register into a stack location, call delete_stack_state() to delete the stale entry before returning. Reviewed-by: Ian Rogers <irogers@google.com> Reviewed-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Tengda Wu <wutengda@huaweicloud.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-22perf annotate-data: Track imm_value for stack variablesTengda Wu
Currently, imm_value is tracked in registers but dropped when values are saved to or loaded from stack variables during type profiling. If a register of type TSR_KIND_CONST is stored to the stack, its value will be lost. Add an imm_value field to struct type_state_stack and update set_stack_state() and findnew_stack_state() to accept and preserve the immediate value when updating stack state. Reviewed-by: Shuai Xue <xueshuai@linux.alibaba.com> Reviewed-by: Ian Rogers <irogers@google.com> Reviewed-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Tengda Wu <wutengda@huaweicloud.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-22perf annotate-data: Expand type_state_reg imm_value to u64Tengda Wu
The arm64 'adrp + add/ldr' instruction pair involves global variable address calculation and passing, which requires storing the 64-bit address in type_state_reg. Currently, there is no field in type_state_reg that can hold such an address. The most likely candidate for reuse is imm_value, but it is defined as u32, which limits the size of values it can carry. To address this, expand imm_value from u32 to u64. Also update related compilation warnings and fix the sign-extension issue introduced by this change. Reviewed-by: Ian Rogers <irogers@google.com> Reviewed-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Tengda Wu <wutengda@huaweicloud.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-22perf annotate-arm64: Support store instruction trackingTengda Wu
Extend update_insn_state_arm64() to handle standard store instructions (str, stur, stlr, stp). Exclusive stores (e.g., stxr, stxp) are excluded from this path since their operand semantics differ. Unlike load instructions, a store instruction writes a value into the memory location addressed by the destination register, without changing that register's type. As a result, no type transfer is needed here. The only thing to keep in mind is that store instructions support pre-index and post-index addressing modes, so adjust_reg_index_state() still needs to be called to handle their addressing. In addition, exclusive stores (stxr, stxp, stlxr, stlxp, etc.) write their execution status (0 or 1) into the status register, which is parsed into src->reg1. Invalidate this status register in invalidate_unhandled_insn_regs() so that stale types are not propagated. Reviewed-by: Ian Rogers <irogers@google.com> Signed-off-by: Tengda Wu <wutengda@huaweicloud.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-22perf annotate-arm64: Support load instruction trackingTengda Wu
Extend update_insn_state_arm64() to handle load instructions, tracking register state changes when data is loaded from memory to registers. Two main categories are considered: standard load (e.g, ldr variants) and load pair (ldp), for example: ldr dst, [src, #imm] ldp dst1, dst2, [src, #imm] For data type propagation, a load pair can be treated as two standard loads combined, first loading dst1 and then dst2. The difference is that when loading dst2, an additional memory spacing 'mem_spacing' after the first load must be added. This mem_spacing can be derived from the instruction mnemonic and the size of the dst register. Each load operation is handled by introducing propagate_load_reg_state(). When processing a load pair, the case where dst and src registers are the same (e.g., ldp x0, x1, [x0]) also needs to be considered. Therefore, before propagating data types, a snapshot of the src register's state must be saved and then passed to propagate_load_reg_state(). Finally, handle the side effects of pre-index and post-index addressing via adjust_reg_index_state(). A real-world example is shown below: ffff80008011f5b0 <pick_task_stop>: ffff80008011f5b8: ldr x0, [x0, #2712] // x0: struct rq* -> task_struct* * ffff80008011f5c0: ldr w1, [x0, #104] Before this commit, the type of x0 was incorrectly inferred as 'struct rq': find data type for 0x68(reg0) at pick_task_stop+0x10 var [8] reg0 offset 0 type='struct rq*' chk [10] reg0 offset=0x68 ok=1 kind=1 (struct rq*) : Good! final result: type='struct rq' After this commit, the type of x0 is correctly inferred as 'struct task_struct': find data type for 0x68(reg0) at pick_task_stop+0x10 var [8] reg0 offset 0 type='struct rq*' ldr [8] 0xa98(reg0) -> reg0 type='struct task_struct*' chk [10] reg0 offset=0x68 ok=1 kind=1 (struct task_struct*) : Good! final result: type='struct task_struct' Reviewed-by: Ian Rogers <irogers@google.com> Reviewed-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Li Huafei <lihuafei1@huawei.com> Signed-off-by: Tengda Wu <wutengda@huaweicloud.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-22perf annotate-arm64: Track return type after call instructionsTengda Wu
Enable data type profiling to track function return values in arm64 annotations by looking up the DWARF return type of called functions. Reviewed-by: Ian Rogers <irogers@google.com> Reviewed-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Tengda Wu <wutengda@huaweicloud.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-22perf annotate-data: Add arch_get_reg_offset helperTengda Wu
Add a helper to compute the effective offset from a base register for instruction operands. Currently handles arm64 addressing modes including post-indexed, single-register, SIB-style indexed with shift/extension, and constant-offset register pairs. Fallback to instruction's raw offset for other architectures. Reviewed-by: Ian Rogers <irogers@google.com> Reviewed-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Tengda Wu <wutengda@huaweicloud.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-22perf annotate-arm64: Enable instruction tracking supportTengda Wu
Enable basic instruction tracking for arm64 by implementing three essential functions in the find_data_type_block() call path: find_data_type_block -> arch_supports_insn_tracking (1) -> find_data_type_insn -> init_type_state (2) -> update_var_state -> update_insn_state (3) Changes: * arch_supports_insn_tracking(): add arm64 to the list of supported architectures, allowing find_data_type_block() to proceed with data type analysis. * init_type_state(): correctly identify ret_reg, stack_reg, and caller-saved registers for arm64 during type state initialization. * update_insn_state(): add the update_insn_state_arm64() callback with conservative register invalidation for call instructions and those with destination register(s), preventing stale type propagation. For now the invalidation path does not treat special instructions individually; doing so for every such instruction up front would be costly. A TODO is therefore left in invalidate_unhandled_insn_regs() marking where per-instruction invalidation handling is to be extended in future patches. With these changes, arm64 gains support for basic variable type inference during instruction tracking. Reviewed-by: Ian Rogers <irogers@google.com> Signed-off-by: Li Huafei <lihuafei1@huawei.com> Signed-off-by: Tengda Wu <wutengda@huaweicloud.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-22perf annotate-data: Extract invalidate_reg_state() as a common helperTengda Wu
The invalidate_reg_state() function is currently static and only used within the x86 data type profiling implementation. To prepare for adding arm64 instruction tracking support, extract it as a common helper that can be shared across architectures. No functional change intended. Reviewed-by: Shuai Xue <xueshuai@linux.alibaba.com> Reviewed-by: Ian Rogers <irogers@google.com> Reviewed-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Tengda Wu <wutengda@huaweicloud.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-21perf bench: Add atomic operations benchmarkChangbin Du
Add a new 'atomic' collection to perf bench for benchmarking atomic read-modify-write operations with multi-threaded contention testing. It provides two subcommands: - atomic cas: contended compare-and-swap operations (__atomic_compare_exchange_n) - atomic inc: contended fetch-add operations (__atomic_fetch_add) Both support a configurable thread count and runtime to measure atomic contention effects. Why this benchmark is needed: - Atomic read-modify-write operations are fundamental to lock-free algorithms and data structures. Understanding their performance characteristics under contention is critical for designing high-performance concurrent applications. - The benchmark helps identify atomic operation latency and scalability issues across different thread counts, revealing contention patterns that are not visible in single-threaded tests. - Useful for evaluating atomic implementation quality on different architectures and for regression testing after changes to atomic primitives or memory ordering. Measurement methodology: - By default two threads contend for the counter, enough to expose the contention effect; use -t to scale the count. - Each thread starts a private timer (clock_gettime CLOCK_MONOTONIC) after synchronizing on a pthread_barrier, ensuring all threads begin simultaneously. - Each thread performs a hot loop of the selected atomic operation (compare-and-swap or fetch-add) on a shared unsigned long counter for a fixed runtime. It counts its own completed operations in a local variable, and the loop runs in batches so the termination flag is only polled between batches. - The main thread sleeps for the runtime and then sets the flag; the throughput of a repeat is the total operation count divided by the measured wall time (the max per-thread runtime). - The shared counter is cache-line aligned (64 bytes) to isolate contention to the target cache line and avoid false sharing. - The per-thread operation counts of the last repeat show whether any thread failed to make progress under contention. - The first repeat is excluded from statistics as a warmup phase to avoid cache-cold effects. Example usage: $ perf bench atomic all # Running atomic/cas benchmark... Threads: 2, runtime: 2 sec, repeats: 10 (warmup: 1) Avg throughput: 68,599,954 ops/sec (+- 0.13%) Per-thread ops (last repeat): fastest: 74,842,112 ops slowest: 63,176,704 ops avg: 69,009,408 ops # Running atomic/inc benchmark... Threads: 2, runtime: 2 sec, repeats: 10 (warmup: 1) Avg throughput: 128,428,772 ops/sec (+- 0.54%) Per-thread ops (last repeat): fastest: 146,230,272 ops slowest: 112,825,344 ops avg: 129,527,808 ops Output fields explained: - Threads: number of contending threads - runtime: seconds each thread runs per repeat - repeats: number of test runs (first is warmup) - Avg throughput: mean aggregate ops/sec across repeats - +- %: relative standard error of the mean throughput across repeats - Per-thread ops: fastest/slowest/avg operations per thread in the last repeat (shows scheduling imbalance and lack of progress) Reviewed-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Changbin Du <changbin.du@gmail.com> Assisted-by: opencode:DeepSeek-V4-Pro Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-21perf lock contention: Filter events before creating lock_statIan Rogers
In report_lock_contention_begin_event(), lock_stat_findnew() was called before checking filters.nr_types (-Y), filters.nr_addrs (-L), and match_callstack_filter() (-S). When a filtered-out lock event (such as a mutex contention when running with -Y spinlock) shared the same aggregation key as a subsequent matching event (for example, contention on the mutex's internal wait_lock spinlock from the same caller), the first event created the lock_stat entry with the filtered-out lock's flags and the second event reused that entry, causing non-spinlock entries to appear in -Y spinlock output. Check the type, address, and callstack filters before looking up or creating the lock_stat entry. Fixes: b4a7eff93c39f985 ("perf lock contention: Add -Y/--type-filter option") Reviewed-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Ian Rogers <irogers@google.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-21perf cs-etm: Respect --no-itrace optionJames Clark
If there is a bug in decoding then Perf will exit early and you can't investigate by using the raw dump mode. Make the --no-itrace option stop Coresight decoding after printing the aux header so decode errors don't stop the rest of the samples being printed. pmu_type and evsel_is_auxtrace need to be set so that the unleader_auxtrace() behavior is the same as without --no-itrace. Reviewed-by: Adrian Hunter <adrian.hunter@intel.com> Reviewed-by: Leo Yan <leo.yan@arm.com> Signed-off-by: James Clark <james.clark@linaro.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-21perf cs-etm: Synthesize missing HW_ID mappings for raw traceLeo Yan
The CoreSight driver emits PERF_RECORD_AUX_OUTPUT_HW_ID via perf_report_aux_output_id(). If the perf ring buffer is full, perf_report_aux_output_id() can fail to emit the record and return silently. When at least one HW_ID record is present in the file, perf skips the legacy metadata-only trace ID mapping path. Therefore any raw AUX queue whose HW_ID record was dropped can be left with an empty traceid_list, and cs_etm__create_queue_decoders() will not create a decoder for that queue. Fix it by ignoring all HW_IDs for unformatted queues and always create one decoder per queue unconditionally. Trace ID is unused so we can hard code it to 1 (0 is a special value used in 'pending_timestamp_chan_id' to indicate not pending). We also need put the same trace ID in the CPU metadata because the relationship between CPU metadata and traceid_list is bidirectional. Moving cs_etm__metadata_set_trace_id() into the mapping function solves this and simplifies existing code. cs_etm__insert_trace_id_node() now does two things, so rename it to a more generic cs_etm__map_trace_id(). Signed-off-by: Leo Yan <leo.yan@arm.com> Signed-off-by: James Clark <james.clark@linaro.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-21perf cs-etm: Free partially created queuesJames Clark
cs_etm__create_decoders() can fail half way through and the err_free_queues label won't free them. Call the full queue free function here instead. If no decoders were created it's a nop. Reviewed-by: Leo Yan <leo.yan@arm.com> Signed-off-by: James Clark <james.clark@linaro.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-21perf cs-etm: Don't add global v0 HW_IDs to unformatted queuesJames Clark
In the case of mixed formatted and unformatted trace with v0 HW_IDs, or no HW_IDs at all resulting in the cs_etm__map_trace_ids_metadata() fallback, formatted queues will write their HW_IDs to unformatted queues. This will result in an assert because of multiple decoders on an unformatted queue. Fix it by not inserting trace ID nodes on other unformatted queues. This isn't an issue for v0.1 HW_IDs because they aren't global so will only add to their own queue. Fixes: 19c3e4db38c5bf30 ("perf: cs-etm: Create decoders based on the trace ID mappings") Reviewed-by: Leo Yan <leo.yan@arm.com> Signed-off-by: James Clark <james.clark@linaro.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-21perf c2c: Fix memory leaks on output fieldsNamhyung Kim
The perf_hpp_list was not freed after use. Let's add it for the main c2c hists list in perf c2c report and a local list in print_pareto(). Previously it was detected by ASAN like below. ================================================================= ==42183==ERROR: LeakSanitizer: detected memory leaks Indirect leak of 1064 byte(s) in 7 object(s) allocated from: #0 0x7f17334ef24f in calloc (/lib64/libasan.so.8+0xef24f) (BuildId: 61e8165ca90f7a4f06b73f064a938c76deaae079) #1 0x0000005fa099 in zalloc ../../lib/zalloc.c:8 #2 0x0000004faf6d in get_format tools/perf/builtin-c2c.c:1978 #3 0x0000004fb45e in c2c_hists__init_output tools/perf/builtin-c2c.c:2004 #4 0x0000004fb7de in __hpp_list__parse tools/perf/builtin-c2c.c:2047 #5 0x0000004fbae9 in hpp_list__parse tools/perf/builtin-c2c.c:2085 #6 0x0000004fee13 in print_pareto tools/perf/builtin-c2c.c:2563 #7 0x0000004ffcd7 in perf_c2c__hists_fprintf tools/perf/builtin-c2c.c:2708 #8 0x000000500ab5 in perf_c2c_display tools/perf/builtin-c2c.c:2949 #9 0x0000005045c3 in perf_c2c__report tools/perf/builtin-c2c.c:3522 #10 0x000000505caa in cmd_c2c tools/perf/builtin-c2c.c:3676 #11 0x0000005df50e in run_builtin tools/perf/perf.c:383 #12 0x0000005df9b1 in handle_internal_command tools/perf/perf.c:436 #13 0x0000005dfd7f in run_argv tools/perf/perf.c:480 #14 0x0000005e02d6 in main tools/perf/perf.c:581 #15 0x7f1729450680 in __libc_start_call_main (/lib64/libc.so.6+0x3680) (BuildId: 85075e2ae2e13352a1413d41c327dacf6461526c) #16 0x7f1729450797 in __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x3797) (BuildId: 85075e2ae2e13352a1413d41c327dacf6461526c) #17 0x000000409c34 in _start (tools/perf/perf+0x409c34) (BuildId: 36a64600776d92e4ab7dfd5ca20c92280d72a645) SUMMARY: AddressSanitizer: 1064 byte(s) leaked in 7 allocation(s). Fixes: c75540e3160fb586 ("perf c2c report: Add dimension support") Reviewed-by: Aaron Tomlin <atomlin@atomlin.com> Reviewed-by: Dmitry Ilvokhin <d@ilvokhin.com> Reviewed-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org> Cc: Jiri Olsa <jolsa@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-19perf test: Avoid stack trace noise in verbose=1 failure snippetsIan Rogers
When a test fails with a signal or times out, child_test_sig_handler() appends '---- unexpected signal (<sig>) ----' followed by a multi-line stack trace (' #0 ...' through '_start'). In verbose=1 mode, print_test_failure_snippet() selects up to failure_snippet_lines (10) lines: - Pass 1 selects lines matching failure keywords plus their immediate next line (' #0 ... in child_test_sig_handler'). - Pass 2 fills the remaining quota by scanning backwards from the end of the output buffer, which consumes the remaining lines on outermost stack frames ('handle_internal_command', 'run_argv', 'main', '__libc_start_main', '_start') and hides the trailing test output showing where the test had run to. Improve print_test_failure_snippet() by: - Skipping blank lines and stack trace lines (' #<digit>...') when selecting context in Pass 1 and when scanning backwards from the end in Pass 2, with a Pass 3 fallback from the top of the buffer if quota still remains. - Prioritizing the non-blank line immediately preceding '---- unexpected signal' so there is no '...' gap before the signal message. - Only printing '...' between selected lines when at least one non-blank line was omitted between them. Assisted-by: Antigravity:gemini-3.1-pro Signed-off-by: Ian Rogers <irogers@google.com> Acked-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-19perf treport: Fix profile builder type narrowing in progress callbackJames Clark
Mypy does not retain the narrowing of an optional local variable inside the nested progress callback, causing the perf build to fail with: python/treport.py:649: error: Item "None" of "ProfileBuilder | None" has no attribute "cancelled" [union-attr] Check the loading builder before assigning it to profile so the captured variable is inferred as ProfileBuilder rather than Optional[ProfileBuilder]. Keep the existing assertion and background loading behavior. Fixes: b379b70b7b7b ("perf treport: Show the profile while it loads") Assisted-by: Codex:GPT-6.1-Sol Signed-off-by: James Clark <james.clark@linaro.org> Reviewed-by: Ian Rogers <irogers@google.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-19perf timechart: Fix task row type narrowing in goto_task()James Clark
Mypy cannot narrow Row to TaskRow or IoRow when the class passed to isinstance() comes from a loop variable, causing the perf build to fail with: python/ttimechart.py:1686: error: "Row" has no attribute "task" [attr-defined] Check against TaskRow and IoRow explicitly so mypy can verify access to the task attribute. The tasks and I/O views contain TaskRow and IoRow instances respectively, so task navigation behaves as before. Fixes: e7a72d6919804e5e ("perf timechart: Add an interactive --tui mode") Reviewed-by: Ian Rogers <irogers@google.com> Assisted-by: Codex:GPT-6.1-Sol Signed-off-by: James Clark <james.clark@linaro.org> Cc: Alice Rogers <alice.mei.rogers@gmail.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-17perf kvm: Cast tv_usec to long to fix build on MIPS 32-bitsArnaldo Carvalho de Melo
Using the same cast we use in util/debug.c with tv_usec. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-17perf test: Take turns using the perf mlock budget in the mmaping testsArnaldo Carvalho de Melo
The mmap size used when none is asked for is derived from kernel.perf_event_mlock_kb itself (see perf_event_mlock_kb_in_pages()), that after rounding down to a power of two number of pages ends up being about all of a single CPU's share of that per user budget, so with 'perf test' starting all the selected tests at once, any further mapping done while another test still has its ring buffers mapped fails with: Permission error mapping pages. Consider increasing /proc/sys/kernel/perf_event_mlock_kb, or try again with a smaller value of -m/--mmap_pages. that then shows up as a failure or, worse, as an "unsupp" skip in tests like the attr ones, i.e. as a false pass. Instead of making those tests exclusive, which would serialize them against every other test, keep them running in parallel with the tests that don't map ring buffers and have them take turns using the budget, via a robust, process-shared mutex (see mutex_init_pshared_robust()) in a MAP_SHARED|MAP_ANONYMOUS area that is inherited by the forked test processes: a test killed by a signal doesn't leave the budget locked, the kernel marks the mutex owner-died and the next locker takes it over; a signal that is caught rather than kills ends up the same way, with the longjmp out of child_test_sig_handler() leaving it held until the child exits and the kernel hands it over. Perf's struct mutex is used, so the lock discipline is checked in clang builds via -Wthread-safety; as the thread safety analysis can't verify conditionally held locks, the tests that map ring buffers run through a helper taking the mutex unconditionally around the test function call. Robust mutexes aren't always available, at build time or, as glibc and musl can do when get_robust_list(2)/set_robust_list(2) aren't usable, at run time: in that case the budget is not shared and the tests run as before, failing or skipping on starvation instead of hanging on a lock left behind by a test killed by a signal. Taking turns is unnecessary when nothing can exhaust the budget: once it is spent, whatever maps on top of it is charged against RLIMIT_MEMLOCK and the mapping is refused with EPERM when that runs out too, but only for the processes the kernel is paranoid about and that have no CAP_IPC_LOCK to lift the check, see perf_mmap_calc_limits(). Root, then, has no turns to take: it never has a mapping refused, so the turnstile only buys it the wall clock cost measured below, for a budget nothing is contending for. The area is shared by the tests of one 'perf test' invocation only: a second invocation running at the same time maps its own, so the two don't take turns with each other. The sysctl is left alone. Growing it, to leave room for whatever else the user has running, would need the original value shared between the invocations, so that the last one out puts it back, and it only helps a user who can write the sysctl but lacks CAP_IPC_LOCK, the one capability that lifts the limit. Raising the soft RLIMIT_MEMLOCK to the hard one when a mapping is refused is left for a follow-up: it would buy back the wall clock above without taking turns, where the hard limit allows the raise. None of this is done when just one of the selected tests maps ring buffers, as there is nothing to share the budget with in that case. Taking turns isn't free: a test that hangs while holding the budget now holds with it every other test mapping ring buffers, where before it would fail, or skip, by itself. And there is a cost even when nothing goes wrong, this being the whole suite on a Ryzen 9 9950X3D, kernel 7.2.7, 32 CPUs, with the default 516 KiB budget, before and after taking turns: budget not shared: 42 s wall clock, 72 tests Ok, 28 failed tests take turns: 133 s wall clock, 101 tests Ok, 10 failed Both are non-root runs of the whole series applied, the shell test markings included, and none of the ten failures is about the budget: eight of them pass as root, where it can't be exhausted, and the two that fail there too, the addr2line inline unwinding one, with no branch stack sampling to ask this machine for, and the BPF metadata collection one, whose output isn't what the test expects, are not budget related either. Reviewed-by: Ian Rogers <irogers@google.com> Tested-by: Ian Rogers <irogers@google.com> Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-17perf mutex: Add a robust, process-shared mutex initializerArnaldo Carvalho de Melo
A mutex held by a process that can die before unlocking it, like the tests forked by 'perf test' that will take turns using the per user budget set in kernel.perf_event_mlock_kb, has to be taken over by the next locker instead of staying locked forever. Robust mutexes, on top of the kernel's robust futexes, do that: when an owner dies while holding it the kernel marks the futex word owner-died and the next pthread_mutex_lock() returns EOWNERDEAD, then mutex_lock() makes it consistent and takes it over; mutex_trylock() and cond_wait() come back with EOWNERDEAD too, so they take it over the same way, with mutex_trylock() giving the mutex back when it can't be taken over: it is held all the same, and a failed trylock must not leak it. Add mutex_init_pshared_robust(), returning false when robust mutexes aren't available: from libcs without the API, gated by a feature check, to musl and glibc refusing them at runtime, when get_robust_list(2) or set_robust_list(2) aren't usable. glibc only sets a flag in pthread_mutexattr_setrobust(), refusing the mutex itself in pthread_mutex_init() with ENOTSUP instead, other errors from it still being reported. Robust mutexes being unavailable isn't an error, just a debug message for whoever then falls back. Reviewed-by: Ian Rogers <irogers@google.com> Tested-by: Ian Rogers <irogers@google.com> Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-17perf tests: Mark the shell tests not mapping perf ring buffersArnaldo Carvalho de Melo
Shell tests run perf, that maps ring buffers, so they take a turn using the per user budget in kernel.perf_event_mlock_kb by default; the ones that don't map them, like the ones running just 'perf stat', say " (no_mlock)" in their description line and thus keep running in parallel with the ones taking turns. The 'perf sched stats' tests are among them, they synthesize the samples from /proc/schedstat without mapping a ring buffer, and the tests already marked " (exclusive)" don't need it, exclusive implies every other requisite and keeps them running alone. Reviewed-by: Ian Rogers <irogers@google.com> Tested-by: Ian Rogers <irogers@google.com> Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-17perf tests: Mark the C tests mapping perf ring buffersArnaldo Carvalho de Melo
The C tests that run 'perf record' in the test process itself map ring buffers and so need room in the per user budget set in kernel.perf_event_mlock_kb: mark them with the new 'needs_mlock' suite flag, read by the turnstile added later in the series, so that they take turns using that budget while the tests that don't map them keep running in parallel. Reviewed-by: Ian Rogers <irogers@google.com> Tested-by: Ian Rogers <irogers@google.com> Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-10-17perf tests: Introduce a 'needs_mlock' suite flagArnaldo Carvalho de Melo
Each perf instance maps one ring buffer per CPU, all charged to the same per user budget set in kernel.perf_event_mlock_kb, so suites that map them need to be told apart from the ones that don't, to later have them take turns using that budget while the other tests keep running in parallel. Add the flag to 'struct test_suite' and a DEFINE_SUITE_NEEDS_MLOCK() variant for the suites using the DEFINE_SUITE() form. Shell tests run perf, that maps ring buffers, so they are taken to need room in that budget by default; the requisites, a comma separated list in the parens ending their description line, name what a test needs and take a "no_" prefix to waive it, e.g.: # perf stat tests (no_mlock) "mlock" is room in that budget, so stating it only spells the default out, "no_mlock" waives it, and "exclusive" is the catch-all that keeps a test from running alongside any other, so it runs alone, in sequence, and implies every other requisite, which is why it can't be waived either. More requisites are to come, each stating what a test needs, till the catch-all isn't needed anymore. 'perf test requisites' lists what each test needs, reusing the listing routine and taking the same test name fragments and numbers as 'list'. Reviewed-by: Ian Rogers <irogers@google.com> Tested-by: Ian Rogers <irogers@google.com> Assisted-by: LLM Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>