summaryrefslogtreecommitdiff
path: root/tools/perf
AgeCommit message (Collapse)Author
2026-07-15perf vendor events intel: Update clearwaterforest events from 1.02 to 1.04Chun-Tse Shao
The updated events were published in: https://github.com/intel/perfmon/commit/13983cd535d18b2bfd86a3b9daa374039f78a836 Signed-off-by: Chun-Tse Shao <ctshao@google.com> Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-15perf vendor events intel: Update arrowlake events from 1.19 to 1.20Chun-Tse Shao
The updated events were published in: https://github.com/intel/perfmon/commit/b23ebe7bc25add0c835565e4bc87e063cb620a02 Signed-off-by: Chun-Tse Shao <ctshao@google.com> Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-15perf vendor events intel: Update alderlaken events from 1.39 to 1.40Chun-Tse Shao
The updated events were published in: https://github.com/intel/perfmon/commit/7a14cc8feaf86772deb6708e96c8e9fee6d5b1ca Signed-off-by: Chun-Tse Shao <ctshao@google.com> Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-15perf vendor events intel: Update alderlake events from 1.39 to 1.40Chun-Tse Shao
The updated events were published in: https://github.com/intel/perfmon/commit/7a14cc8feaf86772deb6708e96c8e9fee6d5b1ca Signed-off-by: Chun-Tse Shao <ctshao@google.com> Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-15perf: evsel: Fix error handling in tp_format lookupHongling Zeng
In evsel__tp_format(), when trace_event__tp_format*() returns an error, IS_ERR() checks the local variable 'tp_format', but PTR_ERR() incorrectly uses 'evsel->tp_format' which hasn't been assigned yet. Fix this by using PTR_ERR(tp_format) to extract the error code from the correct variable. Fixes: 6c8310e8380d ("perf evsel: Allow evsel__newtp without libtraceevent") Signed-off-by: Hongling Zeng <zenghongling@kylinos.cn> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-15perf doc: Fix mmap failure checks in topdown exampleHongfu Li
Use MAP_FAILED instead of NULL to detect mmap errors, and fix the slots_p variable name typo in the sample code. Signed-off-by: Hongfu Li <lihongfu@kylinos.cn> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-15perf jevents: Add Intel OMR MSR mappingsDapeng Mi
New OMR MSRs are introduced for OMR events on DMR and NVL. Perf continues to reuse the existing offcore_rsp attribute to encode the MSR value, similar to existing OCR event handling. Add the corresponding OMR MSR mappings in lookup_msr() so jevents can translate these events and generate the correct offcore_rsp attribute. Link: https://lore.kernel.org/all/20260114011750.350569-2-dapeng1.mi@linux.intel.com/ Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-15perf test: Remove duplicate include of util/term.hChen Ni
Remove duplicate inclusion of util/term.h in builtin-test.c to clean up redundant code. Signed-off-by: Chen Ni <nichen@iscas.ac.cn> Reviewed-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-13perf record: Fix multiple PERF_RECORD_COMPRESSED2 records per pushDmitry Ilvokhin
With Zstd compression enabled ('perf record -z'), a single mmap push whose compressed output exceeds the maximum record size makes zstd_compress_stream_to_records() emit several PERF_RECORD_COMPRESSED2 records back to back. record__pushfn() however rewrote only the first record's header to describe the whole blob as one record: event->data_size = compressed - sizeof(struct perf_record_compressed2); event->header.size = PERF_ALIGN(compressed, sizeof(u64)); padding = event->header.size - compressed; ... record__write(rec, map, &pad, padding); perf_event_header::size is a __u16, so once the compressed blob no longer fits in it the header.size assignment truncates and 'padding' (size_t) underflows. write() is then handed that bogus length and fails with EFAULT, aborting the recording: failed to write perf data, error: Bad address The bytes that did reach the file are mis-framed, so reading it back cannot be decompressed. This is easy to hit with a high event rate and a large buffer, e.g.: perf record -z -F max -m 32M --per-thread -- perf test -w thloop 5 1 The single-record fixup is wrong by construction: because header.size is 16 bits a compressed record cannot exceed 64KB, so the compressor must split a push into a chain of records, and the session reader already consumes them as such. Frame each record where it is produced instead: make process_comp_header() set the per-record data_size, 8-byte-align header.size and zero the trailing padding, and let record__pushfn() write the resulting blob, as the AIO path already does. Reduce max_record_size by sizeof(u64) so the per-record alignment padding cannot push header.size past its u16 field. process_comp_header() returns -1 when that padding would not fit the space left in 'dst', so the compressor stops instead of overrunning the output buffer. There is no on-disk format change; a perf.data written by the fixed tool is still read by existing perf. Fixes: 208c0e168344 ("perf record: Add 8-byte aligned event type PERF_RECORD_COMPRESSED2") Reported-by: Farid Zakaria <fmzakari@meta.com> Signed-off-by: Dmitry Ilvokhin <d@ilvokhin.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-13perf record: Return the written size from process_comp_header()Dmitry Ilvokhin
process_comp_header() is called from zstd_compress_stream_to_records() twice per record: once with data_size == 0 to write the record header, and once with the payload size to finalize it. It returns the increment it was passed, and the loop separately decides whether a record still fits by comparing the remaining 'dst_size' against the header size. With the fit check split from the code that writes the record, process_comp_header() cannot reject a record on its own, so any bytes it writes into 'dst' have to be bounds-checked by the caller instead of where they are produced. Pass the space left in 'dst' to process_comp_header(), let it return the number of bytes written or -1 when the header does not fit, and account the compressed payload in the loop. No functional change intended. Signed-off-by: Dmitry Ilvokhin <d@ilvokhin.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-13perf build: Do not pass -static to dlfiltersNamhyung Kim
The recent commit caused a failure in make build-test for static builds. Let's not pass -static the option to dlfilters which is dynamically loaded as it's hard-coded with -shared even for static builds. Tested-by: Leo Yan <leo.yan@arm.com> Cc: Trevor Allison <tallison@redhat.com> Fixes: e1065ed188cf ("perf build: Add LDFLAGS to dlfilters .so link") Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-10perf metricgroup: Fix metric expression copy leaksYu Peng
metricgroup__copy_metric_events() allocates a new metric expression and duplicates metric_name before linking the expression into the destination metric event. Free new_expr when strdup() fails, and free the duplicated metric_name on the later error paths. Fixes: b85a4d61d302 ("perf metric: Allow modifiers on metrics") Signed-off-by: Yu Peng <pengyu@kylinos.cn> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-10perf clang-format: Prioritize Python.h and expand other categoriesIan Rogers
This commit updates the .clang-format rules for the perf tools. It prioritizes Python.h sorting and expands the regex lists for C standard library and OS specific headers. - Prioritize Python.h by sorting it first (Priority -1), ensuring it is sorted before even the main header (Priority 0). - Keep other header priorities (1 and 2) to maintain their relative order. - Sanity check and complete "C Standard Library Headers" up to C23 (added stdbit.h, stdckdint.h). - Sanity check and complete "OS/System-Specific Headers" based on actual usage in tools/perf (added asm-generic, uapi, and various flat POSIX/system headers). Signed-off-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-10perf record: Fix teardown hang on system-wide multi-threaded sessionsIan Rogers
Under system-wide (-a) parallel streaming mode (--threads=cpu), background recording threads can be inundated by a continuous firehose of hardware samples generated by the OS. In this state, a background thread's local hit count remains unequal to its sample count, causing it to bypass the blocking fdarray__poll() call entirely on each iteration of its recording loop. Because the termination check relies on the POLLHUP event status populated specifically by fdarray__poll(), bypassing it prevents the background thread from ever recognizing that its control pipe was closed by the main thread. This traps the background thread in an infinite recording loop, hanging the main thread indefinitely as it awaits a termination acknowledgment that never arrives. Ensure teardown completion by adding explicit evlist__disable() calls in the main thread's cleanup paths at out_child: and out_child_no_flush:. Additionally, patch fdarray__filter() to respect the fdarray_flag__nonfilterable flag, preventing it from incorrectly setting the background thread's control pipe file descriptor to -1 and clearing its revents mask upon processing termination POLLHUP signals. Fixes: f94563fac269 ("perf record: fix poll storm when monitored threads exit") Assisted-by: Antigravity:gemini-3.5-flash Signed-off-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-09perf capstone: Fix kernel map reference count leakTengda Wu
In print_capstone_detail(), maps__find() is used to locate the kernel map. This function increments the reference count of the found map object. However, the current implementation fails to call map__put() after the map is no longer needed, leading to a reference count leak. Fix this by adding a map__put(map) call to properly release the reference after use. Fixes: 92dfc59463d5 ("perf annotate: Add symbol name when using capstone") Signed-off-by: Tengda Wu <wutengda@huaweicloud.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-09perf tests: Restore -p flag to lock contention testIan Rogers
Commit ae42a2a2a3ae ("perf tests: Speed up lock contention analysis shell test") in linux-next heavily optimized the test runtimes by switching the workload from the default of 10 process groups down to 1 (`perf bench sched messaging -g 1`). However, this change inadvertently dropped the original `-p` flag, causing the benchmark to default to `socketpair()` instead of `pipe()`. While `socketpair()` still generates some lock events on x86, it fails to trigger enough samples on architectures like s390, causing the test suite to fail due to lack of captured data. Restore the omitted `-p` pipe flag. The test retains the massive speedups achieved through the `-g 1` scaling, while producing a massive density of lock events across all architectures to fully satisfy the BPF trace filtering logic. Fixes: ae42a2a2a3ae ("perf tests: Speed up lock contention analysis shell test") Signed-off-by: Ian Rogers <irogers@google.com> Tested-by: Thomas Richter <tmricht@linux.ibm.com> Assisted-by: Antigravity:gemini-3.1-pro Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-08perf dso: Fix kallsyms DSO detection with fallback logicTanushree Shah
The current kallsyms detection in dso__is_kallsyms() uses the dso_binary_type enum which fixes the issue of kallsyms being cached in the build-id cache for out-of-tree modules. However, during build-id injection in perf record/inject, dso_binary_type has not been explicitly set yet,so dso__binary_type() returns DSO_BINARY_TYPE__NOT_FOUND instead of DSO_BINARY_TYPE__KALLSYMS for the kernel DSO. The current check then fails to identify it as kallsyms, causing build-id symlinks to not be created in ~/.debug/.build-id/ and perf archive to fail with "Cannot stat" errors. Steps to reproduce the issue: 1. rm -rf ~/.debug/.build-id 2. perf record sleep 1 3. perf archive Fix by falling back to matching long_name against the known kallsyms strings explicitly when binary_type is not yet set (== DSO_BINARY_TYPE__NOT_FOUND). Use strcmp() for exact matching of fixed names and strict validation for guest kallsyms with embedded PID to prevent path traversal attacks. Fixes: ebf0b332732d ("perf dso: fix dso__is_kallsyms() check") Signed-off-by: Tanushree Shah <tshah@linux.ibm.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-08perf stat: reject --field-separator and --json-output combinationIvan Lazaric
Specifying --field-separator option is stating you want CSV output. Passing both --field-separator and --json-output is then stating you want output to be in CSV and JSON format at same time. Currently this combination is not rejected, and the outcome is a malformed combination of CSV and JSON output. This is because of inconsistencies in various printing functions, some of them have if-else chains that start with "Should I print JSON?", and some start with "Should I print CSV?". Example of current output: $ tools/perf/perf stat -x , -j -e cpu-migrations true {"counter-value" : "0.000000", "unit" : "", "event" : "cpu-migrations", "event-runtime" : 474817, "pcnt-running" : 100.00,, Instead reject the option combination, with a helpful error message and non-zero exit code. Example of new output: $ tools/perf/perf stat -x , -j true cannot use both --field-separator and --json-output Usage: perf stat [<options>] [<command>] -x, --field-separator <separator> print counts with custom separator -j, --json-output print counts in JSON format Signed-off-by: Ivan Lazaric <ivan.lazaric1@gmail.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-08perf vendor events amd: Reintroduce deprecated Zen 5 core eventsSandipan Das
Maintain backward compatibility by reintroducing the events that were previously removed by commit 047979af3bf6 ("perf vendor events amd: Update Zen 5 core events"). Also set the deprecated flag and update the descriptions to point users to the correct alternative. Reported-by: Ian Rogers <irogers@google.com> Closes: https://lore.kernel.org/all/CAP-5=fV_czvd-z4N7K+_SabxuOm9UUHRyBxNuchrtAgJL3OqOw@mail.gmail.com/ Fixes: 047979af3bf6 ("perf vendor events amd: Update Zen 5 core events") Signed-off-by: Sandipan Das <sandipan.das@amd.com> Reviewed-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-07perf data convert json: Fix trace_seq memory leak in process_sample_event()Tanushree Shah
Unlike the in-kernel trace_seq which uses a statically allocated buffer, the userspace traceevent library's trace_seq uses a dynamically allocated one. Therefore, every trace_seq_init() call must be paired with a trace_seq_destroy(), otherwise it produces a memory leak. In process_sample_event(), a trace_seq is initialized for each field when formatting tracepoint raw_data, but the matching trace_seq_destroy() is never called, leaking memory for every field of every sample processed. Add the missing trace_seq_destroy() after using the trace_seq buffer to properly free the allocated memory. Detected with Valgrind on a perf.data file with 2,729 tracepoint samples: Before: definitely lost: 55,537,664 bytes in 13,559 blocks After: definitely lost: 0 bytes in 0 blocks Fixes: 9d895e468429 ("perf data: Add tracepoint fields when converting to JSON") Signed-off-by: Tanushree Shah <tshah@linux.ibm.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-07perf record: fix poll storm when monitored threads exitJiawei Sun
When `perf record` samples a multi-threaded process and one of the target threads exits during the session, perf itself may start burning 100% CPU (up to 200% across two cores) until the session ends. A single dead fd is sufficient to trigger this; it can be reproduced with 15 pthreads in a compute loop where one thread exits halfway through. The root cause is two independent instances of the same defect: dead perf_event ring-buffer fds are left in a pollfd array. When a monitored thread exits, the kernel closes its ring-buffer fd, which then returns POLLHUP. POSIX specifies that poll() always reports POLLHUP and POLLERR regardless of the events mask, so any dead fd left in the array makes poll() return immediately every time, spinning in a tight loop: 3 seconds: 256,600 poll() calls, 0 context switches, only 21 write() Woken up count goes from ~0 to 1,300,000+ There are two affected poll paths, fixed together here: 1. Record main loop, via fdarray__filter() (tools/lib/api/fd/array.c). Since commit 59b4412f27f1 ("libperf: Avoid internal moving of fdarray fds") it only zeroes events/revents without setting fd to -1, so poll() keeps reporting POLLHUP for the entry. Setting fd = -1 makes poll() skip it, matching the pattern already used in the control-fd path at tools/perf/builtin-record.c:1673. 2. BPF sideband thread, perf_evlist__poll_thread() (tools/perf/util/sideband_evlist.c). This thread polls for PERF_RECORD_BPF_EVENT but, unlike the main record loop, never calls fdarray__filter() at all, so dead fds accumulate forever and it spins at 100% CPU: Before fix: dJiffies=101, wchan=0 (running) After fix: dJiffies=0, wchan=do_sys_poll (blocking) Fixed by calling the existing evlist__filter_pollfd() helper after evlist__poll(), mirroring the main record loop. <poll.h> is included for the POLLERR/POLLHUP macros (previously unused there). The two fixes compose: fix 1 makes poll() ignore dead fds (fd=-1); fix 2 ensures the sideband thread actually performs the filtering. Both paths are affected in all kernels from v5.1/v5.9 to the current master (7.2-rc1); the source of both functions is byte-identical across them. BPF event recording is preserved: after the fix, perf.data still contains PERF_RECORD_BPF_EVENT records and bpf_prog_info entries. Verified on perf 6.1.76, 6.6.143 and 7.2-rc1 with a minimal reproducer (Woken up 1,300,000 -> 3, CPU 100% -> 0%) and an A/B orthogonal test: keeping the unpatched binary but preventing the target thread from exiting also makes the storm disappear, confirming the trigger. Fixes: 59b4412f27f1 ("libperf: Avoid internal moving of fdarray fds") Fixes: 657ee5531903 ("perf evlist: Introduce side band thread") Signed-off-by: Jiawei Sun <abyssmystery@gmail.com> Reviewed-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-04perf tests: Add auto counter reload (ACR) sampling testDapeng Mi
Add auto counter reload sampling test to verify that the intended event records can be captured and the self-reloaded events won't generate any records. Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-04perf vendor events amd: Update Zen 6 core eventsSandipan Das
Update definitions for the following events. * PMCx00A - Fix descriptions * PMCx00C - Add missing unit masks * PMCx00D - Add missing unit masks and fix descriptions * PMCx013 - Fix incorrect unit masks Fixes: 2f42fb0661d9 ("perf vendor events amd: Add Zen 6 core events") Signed-off-by: Sandipan Das <sandipan.das@amd.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-04perf vendor events amd: Update Zen 5 core eventsSandipan Das
Update definitions for the following events. * PMCx00A - Add missing unit masks * PMCx00B - Add missing unit masks and fix descriptions * PMCx00C - Add missing unit masks * PMCx00D - Add missing unit masks * PMCx025 - Add missing unit masks and fix descriptions Fixes: 45c072f2537a ("perf vendor events amd: Add Zen 5 core events") Signed-off-by: Sandipan Das <sandipan.das@amd.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-04perf test amd ibs: avoid using executable heapOndrej Mosnacek
Making [parts of] the heap executable is dangerous and is blocked by SELinux on Fedora/RHEL even for an unconfined user. Replace the malloc() + mprotect() combo with just mmap(), creating a private anonymous rwx mapping, which only requires the more commonly allowed "execmem" permission under SELinux (things like JIT or regex compilation need it as well). mmap() with MAP_ANONYMOUS will give us a zeroed mapping that begins on a page boundary, so the result is equivalent to the original code even without a memset() or the page-alignment dance. Verified that the test still passes on a machine with an AMD CPU that has the "ibs" CPU flag. Fixes: 35db59fa8ea2 ("perf test amd ibs: Add sample period unit test") Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com> Reviewed-by: Ravi Bangoria <ravi.bangoria@amd.com> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-03perf test: Add Arm CoreSight callchain testLeo Yan
Add a CoreSight shell test for synthesized callchains. The test uses the new callchain workload to generate trace and decodes it with synthesis callchain. It then verifies that the instruction samples show the expected callchain push and pop. Use control FIFOs so tracing starts only around the workload, which keeps the trace data small. The test is limited to with the cs_etm event available and root permission. After: perf test 138 -vvv 138: CoreSight synthesized callchain: ---- start ---- test child forked, pid 35581 Callchain flow matched: l1=4642868 l2=4642880 l3=4642895 l4=4642919 l5=4670494 l6=4670500 l7=4670520 ---- end(0) ---- 138: CoreSight synthesized callchain : Ok Assisted-by: Codex:GPT-5.5 Reviewed-by: James Clark <james.clark@linaro.org> Signed-off-by: Leo Yan <leo.yan@arm.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-03perf cs-etm: Synthesize callchains for instruction samplesLeo Yan
CS ETM already records branches into the thread stack, but instruction samples do not carry synthesized callchains. It misses to support the callchain and no output with the itrace option 'g'. Allocate a callchain buffer per queue and use thread_stack__sample() when synthesizing instruction samples. Advertise PERF_SAMPLE_CALLCHAIN on the synthetic instruction event. Allocate one extra callchain entry than requested, as the first entry is reserved for storing context information. cs_etm__context() is introduced for handling context packet and update the thread info and start kernel address for frontend decoding. After: perf script --itrace=g16l64i1i callchain_test 6543 [002] 1 instructions: ffff800080010c14 vectors+0x414 ([kernel.kallsyms]) aaaad6b60784 do_svc+0x1c (/home/kernel/leoy/test_cs_callchain/callchain_test) aaaad6b60798 print+0xc (/home/kernel/leoy/test_cs_callchain/callchain_test) aaaad6b607b0 foo+0xc (/home/kernel/leoy/test_cs_callchain/callchain_test) aaaad6b607c8 main+0xc (/home/kernel/leoy/test_cs_callchain/callchain_test) ffff9325225c __libc_start_call_main+0x7c (/usr/lib/aarch64-linux-gnu/libc.so.6) ffff9325233c call_init+0x9c (inlined) ffff9325233c __libc_start_main_impl+0x9c (inlined) aaaad6b60670 _start+0x30 (/home/kernel/leoy/test_cs_callchain/callchain_test) ffff800080012290 ret_to_user+0x120 ([kernel.kallsyms]) Signed-off-by: Leo Yan <leo.yan@linaro.org> Reviewed-by: James Clark <james.clark@linaro.org> Signed-off-by: Leo Yan <leo.yan@arm.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-03perf cs-etm: Support call indentationLeo Yan
The perf script callindent is derived from call stack in thread context, CS ETM ignores the requirement for callindent without pushing and poping call stack. Enable thread-stack when either itrace thread-stack support or last branch entries are requested, allocate the branch stack storage accordingly, and feed taken branches to thread_stack__event() whenever thread-stack state is needed. When callindent is requested, pass callstack=true to thread_stack__event() so the common thread-stack code maintains call depth for branch samples. Before: perf script -F +callindent callchain_test 6543 [002] 1 branches: main ffff93252258 __libc_start_call_main+0x78 (/usr/lib/aarch64-linux-gnu/libc.so.6) callchain_test 6543 [002] 1 branches: foo aaaad6b607c4 main+0x8 (/home/kernel/leoy/test_cs_callchain/callchain_test) callchain_test 6543 [002] 1 branches: print aaaad6b607ac foo+0x8 (/home/kernel/leoy/test_cs_callchain/callchain_test) callchain_test 6543 [002] 1 branches: do_svc aaaad6b60794 print+0x8 (/home/kernel/leoy/test_cs_callchain/callchain_test) callchain_test 6543 [002] 1 branches: vectors aaaad6b60780 do_svc+0x18 (/home/kernel/leoy/test_cs_callchain/callchain_test) callchain_test 6543 [002] 1 branches: el0t_64_sync_handler ffff80008001159c el0t_64_sync+0x194 ([kernel.kallsyms]) callchain_test 6543 [002] 1 branches: el0_svc ffff800081829194 el0t_64_sync_handler+0x9c ([kernel.kallsyms]) callchain_test 6543 [002] 1 branches: lockdep_hardirqs_off ffff800081828794 el0_svc+0x24 ([kernel.kallsyms]) callchain_test 6543 [002] 1 branches: __this_cpu_preempt_check ffff80008182b348 lockdep_hardirqs_off+0xf0 ([kernel.kallsyms]) After: callchain_test 6543 [002] 1 branches: main ffff93252258 __libc_start_call_main+0x78 (/usr/lib/aarch64-linux-gnu/libc.so.6) callchain_test 6543 [002] 1 branches: foo aaaad6b607c4 main+0x8 (/home/kernel/leoy/test_cs_callchain/callchain_test) callchain_test 6543 [002] 1 branches: print aaaad6b607ac foo+0x8 (/home/kernel/leoy/test_cs_callchain/callchain_test) callchain_test 6543 [002] 1 branches: do_svc aaaad6b60794 print+0x8 (/home/kernel/leoy/test_cs_callchain/callchain_test) callchain_test 6543 [002] 1 branches: vectors aaaad6b60780 do_svc+0x18 (/home/kernel/leoy/test_cs_callchain/callchain_test) callchain_test 6543 [002] 1 branches: el0t_64_sync_handler ffff80008001159c el0t_64_sync+0x194 ([kernel.kallsyms]) callchain_test 6543 [002] 1 branches: el0_svc ffff800081829194 el0t_64_sync_handler+0x9c ([kernel.kallsyms]) callchain_test 6543 [002] 1 branches: lockdep_hardirqs_off ffff800081828794 el0_svc+0x24 ([kernel.kallsyms]) callchain_test 6543 [002] 1 branches: __this_cpu_preempt_check ffff80008182b348 lockdep_hardirqs_off+0xf0 ([kernel.kallsyms]) Signed-off-by: Leo Yan <leo.yan@linaro.org> Reviewed-by: James Clark <james.clark@linaro.org> Signed-off-by: Leo Yan <leo.yan@arm.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-03perf cs-etm: Flush thread stacks after decoder resetLeo Yan
Perf resets the CoreSight decoder when moving to a new AUX trace buffer, this causes trace discontinunity globally. For callchain synthesis, keeping thread-stack state after decoder reset can leave stale call/return history attached to threads that are decoded later, producing incorrect synthesized callchains. Flush all host thread stacks after a decoder reset. When virtualization is present, flush the guest thread stacks as well. Reviewed-by: James Clark <james.clark@linaro.org> Signed-off-by: Leo Yan <leo.yan@arm.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-03perf cs-etm: Use thread-stack for last branch entriesLeo Yan
CS ETM maintains its own circular array for last branch entries, with local helpers to update, copy and reset the branch stack. This duplicates logic already provided by the common code. Record taken branches with thread_stack__event() and synthesize PERF_SAMPLE_BRANCH_STACK data with thread_stack__br_sample(). This removes the private last_branch_rb buffer and its position tracking. This also makes the branch history state belong to the thread rather than the trace queue. That is a better fit for CoreSight traces where a trace queue can effectively be CPU scoped, while call/return history is per thread. Keep the buffer number updated via thread_stack__set_trace_nr(), which is used when exporting samples to Python scripts. Pass callstack=false for now; synthesized callchains are added by a later patch. The output should remain same, except that be->flags.predicted is no longer set. Since CoreSight trace does not provide branch prediction information, clearing the flag avoids confusion. Reviewed-by: James Clark <james.clark@linaro.org> Signed-off-by: Leo Yan <leo.yan@arm.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-03perf cs-etm: Refactor instruction size handlingLeo Yan
This patch introduces a new function cs_etm__instr_size() to calculate the instruction size based on ISA type and instruction address. Given the trace data can be MB and most likely that will be A64/A32 on a lot of platforms, cs_etm__instr_addr() keeps a single ISA type check for A64/A32 and executes an optimized calculation (addr + offset * 4). Signed-off-by: Leo Yan <leo.yan@linaro.org> Reviewed-by: James Clark <james.clark@linaro.org> Signed-off-by: Leo Yan <leo.yan@arm.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-03perf cs-etm: Decode ETE exception packetsLeo Yan
ETE shares the same packet format as ETMv4, but exception decoding handled ETMv4 packets only. As a result, ETE exception packets were not classified. Recognize the ETE magic for exception number decoding. Reviewed-by: James Clark <james.clark@linaro.org> Signed-off-by: Leo Yan <leo.yan@arm.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-03perf cs-etm: Filter synthesized branch samplesLeo Yan
The itrace 'c' and 'r' options request synthesized branch events for calls and returns only. For perf script the default itrace options are "--itrace=ce", so CS ETM should emit call branches and error events by default. CS ETM currently synthesizes a branch sample for every decoded taken branch whenever branch synthesis is enabled. This produces redundant jump and conditional branch samples. Add a branch filter derived from the itrace calls and returns options. When neither option is set, keep the existing behavior and synthesize all branch samples. When calls or returns are requested, emit only branch samples whose flags match the selected branch type, while preserving trace begin/end markers. Also update test_arm_coresight_disasm.sh and arm-cs-trace-disasm.py to use the --itrace=b option for generating branch samples. Before: perf script -F,+flags callchain_test 6114 [005] 331519.825214: 1 branches: tr strt jmp 0 [unknown] ([unknown]) => ffff8000803a3a68 perf_report_aux_output_id+0x50 ([kernel.kallsyms]) callchain_test 6114 [005] 331519.825214: 1 branches: call ffff8000803a3a74 perf_report_aux_output_id+0x5c ([kernel.kallsyms]) => ffff8000817f4d88 memset+0x0 ([kernel.kallsyms]) callchain_test 6114 [005] 331519.825214: 1 branches: jmp ffff8000817f4d8c memset+0x4 ([kernel.kallsyms]) => ffff8000817f4c00 __pi_memset_generic+0x0 ([kernel.kallsyms]) callchain_test 6114 [005] 331519.825214: 1 branches: jcc ffff8000817f4c1c __pi_memset_generic+0x1c ([kernel.kallsyms]) => ffff8000817f4c44 __pi_memset_generic+0x44 ([kernel.kallsyms]) callchain_test 6114 [005] 331519.825214: 1 branches: jcc ffff8000817f4c4c __pi_memset_generic+0x4c ([kernel.kallsyms]) => ffff8000817f4c5c __pi_memset_generic+0x5c ([kernel.kallsyms]) callchain_test 6114 [005] 331519.825214: 1 branches: jcc ffff8000817f4c5c __pi_memset_generic+0x5c ([kernel.kallsyms]) => ffff8000817f4cf0 __pi_memset_generic+0xf0 ([kernel.kallsyms]) callchain_test 6114 [005] 331519.825214: 1 branches: jcc ffff8000817f4d30 __pi_memset_generic+0x130 ([kernel.kallsyms]) => ffff8000817f4d68 __pi_memset_generic+0x168 ([kernel.kallsyms]) callchain_test 6114 [005] 331519.825214: 1 branches: jcc ffff8000817f4d78 __pi_memset_generic+0x178 ([kernel.kallsyms]) => ffff8000817f4d6c __pi_memset_generic+0x16c ([kernel.kallsyms]) callchain_test 6114 [005] 331519.825214: 1 branches: jcc ffff8000817f4d78 __pi_memset_generic+0x178 ([kernel.kallsyms]) => ffff8000817f4d6c __pi_memset_generic+0x16c ([kernel.kallsyms]) callchain_test 6114 [005] 331519.825214: 1 branches: jcc ffff8000817f4d78 __pi_memset_generic+0x178 ([kernel.kallsyms]) => ffff8000817f4d6c __pi_memset_generic+0x16c ([kernel.kallsyms]) callchain_test 6114 [005] 331519.825214: 1 branches: return ffff8000817f4d84 __pi_memset_generic+0x184 ([kernel.kallsyms]) => ffff8000803a3a78 perf_report_aux_output_id+0x60 ([kernel.kallsyms]) callchain_test 6114 [005] 331519.825214: 1 branches: jcc ffff8000803a3a98 perf_report_aux_output_id+0x80 ([kernel.kallsyms]) => ffff8000803a3b04 perf_report_aux_output_id+0xec ([kernel.kallsyms]) callchain_test 6114 [005] 331519.825214: 1 branches: call ffff8000803a3b1c perf_report_aux_output_id+0x104 ([kernel.kallsyms]) => ffff8000803a38f8 __perf_event_header__init_id+0x0 ([kernel.kallsyms]) After: callchain_test 6114 [005] 331519.825214: 1 branches: tr strt jmp 0 [unknown] ([unknown]) => ffff8000803a3a68 perf_report_aux_output_id+0x50 ([kernel.kallsyms]) callchain_test 6114 [005] 331519.825214: 1 branches: call ffff8000803a3a74 perf_report_aux_output_id+0x5c ([kernel.kallsyms]) => ffff8000817f4d88 memset+0x0 ([kernel.kallsyms]) callchain_test 6114 [005] 331519.825214: 1 branches: call ffff8000803a3b1c perf_report_aux_output_id+0x104 ([kernel.kallsyms]) => ffff8000803a38f8 __perf_event_header__init_id+0x0 ([kernel.kallsyms]) callchain_test 6114 [005] 331519.825214: 1 branches: call ffff8000803a39c0 __perf_event_header__init_id+0xc8 ([kernel.kallsyms]) => ffff800080105258 __task_pid_nr_ns+0x0 ([kernel.kallsyms]) callchain_test 6114 [005] 331519.825214: 1 branches: call ffff80008010528c __task_pid_nr_ns+0x34 ([kernel.kallsyms]) => ffff8000801d5610 __rcu_read_lock+0x0 ([kernel.kallsyms]) callchain_test 6114 [005] 331519.825214: 1 branches: call ffff8000801052b0 __task_pid_nr_ns+0x58 ([kernel.kallsyms]) => ffff800080192078 lock_acquire+0x0 ([kernel.kallsyms]) callchain_test 6114 [005] 331519.825214: 1 branches: call ffff8000801923f4 lock_acquire+0x37c ([kernel.kallsyms]) => ffff8000801d6da0 rcu_is_watching+0x0 ([kernel.kallsyms]) Fixes: b12235b113cf ("perf tools: Add mechanic to synthesise CoreSight trace packets") Signed-off-by: Leo Yan <leo.yan@linaro.org> Reviewed-by: James Clark <james.clark@linaro.org> Signed-off-by: Leo Yan <leo.yan@arm.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-03perf cs-etm: Fix thread leaks on trace queue init failureLeo Yan
cs_etm__init_traceid_queue() allocates the frontend and decode threads, if a later allocation fails, the error path does not drop thread reference that was already acquired. Release both thread pointers with thread__zput() on the error path, so does not leak thread references or leave stale pointers behind. Fixes: 951ccccdc715 ("perf cs-etm: Only track threads instead of PID and TIDs") Reviewed-by: James Clark <james.clark@linaro.org> Signed-off-by: Leo Yan <leo.yan@arm.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-03perf test: Extend perf kvm tests to check default eventNamhyung Kim
It can now pass command line arguments to perf kvm record. Let's pass 'sleep 1' directly and see it doesn't fail. $ sudo perf test -vv kvm 96: perf kvm tests: ---- start ---- test child forked, pid 3686726 Starting qemu-system-x86_64... Testing perf kvm stat Recording kvm events for pid 3686746 (duration 1s)... perf kvm stat test [Success] Testing perf kvm record/report Recording kvm profile for pid 3686746 (duration 1s)... [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.576 MB /tmp/__perf_kvm_test.perf.data.0HgX6 (4009 samples) ] perf kvm record/report test [Success] Testing perf kvm buildid-list perf kvm buildid-list test [Success] Testing perf kvm stat live perf kvm stat live test [Success] Testing perf kvm record default event with command line [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.000 MB /dev/null ] perf kvm record default event [Success] ---- end(0) ---- 96: perf kvm tests : Ok === Test Summary === Passed main tests : 1 Passed subtests : 0 Skipped tests : 0 Failed tests : 0 Tested-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-03perf kvm: Fix a memory leak in the usage stringNamhyung Kim
The first element of the kvm_usage string is allocated dynamically by parse_options_subcommand() if it's NULL. Callers should free it after use. Tested-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-03perf kvm: Do not copy filename stringNamhyung Kim
As it removed STRDUP_FAIL_EXIT(), it no longer calls free() for elements in the copied argv. Thus, the filename should not be allocated as well. In fact, it's a pointer to string literals and should be fine to pass the pointer. Tested-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-03perf kvm: Kill STRDUP_FAIL_EXIT()Namhyung Kim
It's used to pass command line options to a copied argv. But there's no reason to make the copies as it's all used in the same function. It can simply use stack variables. In fact, it fixes a subtle double free issue. As parse_options() can move contents in argv[], some entries may point to the same item. So freeing all items in the argv could trigger a double free. With stack variables, we don't need to allocate and free them. Tested-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-03perf kvm: Check kvm_need_default_arch_event() earlyNamhyung Kim
There's a subtle issue with option parsing in perf record. It calls the function with PARSE_OPT_STOP_AT_NON_OPTION so that it can pass later options to the external command it runs. But perf kvm record passes the default arch events after the argv. So if user calls it with command, then it passes the event to the external command and fails it like below: $ sudo perf kvm --host record sleep 1 sleep: invalid option -- 'e' Try 'sleep --help' for more information. [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.046 MB perf.data.kvm (5 samples) ] We can check if the default options are needed before passing the extra command line to make sure it's passed to perf record. Tested-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-03perf kvm: Factor out kvm_need_default_arch_event()Namhyung Kim
The kvm_add_default_arch_event() has a similar logic in each arch to check if there's an existing command line option for events. Let's check it in the generic code and remove the duplication. Tested-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-03perf symbols: skip livepatch symbols in kcore_copy kallsyms processingJoe Lawrence
Livepatch symbols (.klp.sym.*) carry a [module] tag but resolve to core kernel text addresses. When kcore_copy__process_kallsyms() encounters these symbols, they are treated as module symbols, pulling the first_module_symbol down to a kernel text address. This corrupts the module memory range used to build the kcore PT_LOAD segments. For example, with a kpatch module containing a ".klp.sym.vmlinux.arch_release_task_struct,0" livepatch symbol loaded: kernel symbols ... ffffffffb4a41120 arch_release_task_struct ... ^ ... | aliased by .klp.sym ... | drags first_module_symbol here | (43M gap) | bloated kcore segment | module symbols | ffffffffc047b000 <-- correct first_module_symbol ... ... This causes the module PT_LOAD segment to start at the .klp.sym address and not the real first module address, bloating the kcore copy: Baseline (no livepatch): VirtAddr ffffffffc047b000, 8.5M Bloated (with livepatch): VirtAddr ffffffffb4a41000, 54M Post-fix (with livepatch): VirtAddr ffffffffc047b000, 8.9M Filter livepatch symbols early in kcore_copy__process_kallsyms() before they can affect module boundary tracking. Reported-by: Sashiko <sashiko-bot@kernel.org> Link: https://sashiko.dev/#/patchset/20260624201254.472576-1-joe.lawrence@redhat.com?part=1 Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com> Acked-by: Petr Mladek <pmladek@suse.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-03perf symbols: skip livepatch symbols when loading kallsymsJoe Lawrence
Livepatch modules contain special symbols (prefixed by ".klp.sym.") that act as relocation placeholders. Once resolved, they point to the same addresses as the original kernel symbols they reference. [1] These special symbols confuse the 'vmlinux symtab matches kallsyms' perf test as kallsyms may report multiple symbols sharing a single kernel address. For example: kallsyms (without livepatch) ---------------------------- ffffffff81a41110 T __pfx_arch_release_task_struct > ffffffff81a41120 T arch_release_task_struct ffffffff81a41140 T __pfx_exit_thread ffffffff81a41150 T exit_thread kallsyms (with livepatch loaded) --------------------------------- ffffffff81a41110 T __pfx_arch_release_task_struct > ffffffff81a41120 T arch_release_task_struct ffffffff81a41140 T __pfx_exit_thread ffffffff81a41150 T exit_thread > ffffffff81a41120 w .klp.sym.vmlinux.arch_release_task_struct,0 [kpatch_5_14_0_570_94_1_1_3] When perf loads kallsyms, both symbols are inserted into the symbol table at the same address, corrupting symbol end-address calculations and causing test failures. Filter out symbols prefixed with ".klp.sym." when loading kallsyms, as they alias existing kernel symbols. Link: https://docs.kernel.org/livepatch/module-elf-format.html#livepatch-symbols [1] Reported-and-tested-by: Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com> Acked-by: Petr Mladek <pmladek@suse.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-07-01perf build: Add LDFLAGS to dlfilters .so linkTrevor Allison
Build-time linker flags were not applied when linking dlfilters. Pass LDFLAGS for consistency with the other link rules. Signed-off-by: Trevor Allison <tallison@redhat.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-06-30perf tests: Include error output for skipped tests in JUnit XMLIan Rogers
The JUnit XML output correctly captures the stderr/stdout output of failed tests inside the <failure> element. However, for skipped tests, the output was completely discarded and the XML only received a self-closing <skipped message="reason"/> tag. This expands the <skipped> element to include the test's err_output when available, which is extremely helpful for debugging why a test was skipped (e.g. diagnosing missing prerequisites or unexpected environment states that triggered the skip) directly from CI systems parsing the XML report. Assisted-by: Antigravity:gemini-3.1-pro Signed-off-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-06-30perf tests: Speed up metrics checking shell testsIan Rogers
Optimize the execution of the metric validation and metric listing shell test suites: 1. `stat_metrics_values.sh`: The Python metric validator runs the `perf bench futex hash` workload for each validated metric relationship. Reduce the benchmark runtime limit from `-r 2` (2 seconds) to `-r 1` (1 second). This cuts the workload duration in half while still generating sufficient PMU events to satisfy non-zero threshold metric validations. 2. `stat_all_metrics.sh`: The metric checking test runs `perf stat` sequentially across all 433+ listed metrics. Change the default workload for system-wide runs from `sleep 0.01` to `true`. This avoids the 10ms sleep delay on each sequential metric invocation, saving over 4 seconds of total wall time during full test suite runs. Assisted-by: Antigravity:gemini-3.1-pro Signed-off-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-06-30perf tests: Speed up lock contention analysis shell testIan Rogers
The lock contention analysis test suite (`lock_contention.sh`) performs a series of 13 separate profiling checks to verify various aggregation and filtering parameters of `perf lock contention`. Each of these checks runs the `perf bench sched messaging` messaging benchmark as its workload. By default, `sched messaging` runs 10 groups of 40 processes (400 processes total) generating substantial task scheduling, context switching, and IPC message passing. When traced system-wide for lock events, the tracing overhead (handling millions of lock acquisitions and releases) slows execution down significantly, causing the test suite to take over 80 seconds. Optimize this by introducing a scaled-down messaging benchmark workload: `perf bench sched messaging -g 1 -p`. Running 1 group (40 processes) takes only 0.01 seconds natively (instead of 0.08 seconds), drastically reduces the sheer volume of lock acquire/release trace events, and reduces CPU context switching during tracing while still generating sufficient lock events to fully exercise the BPF/record filters. Assisted-by: Antigravity:gemini-3.1-pro Signed-off-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-06-30perf tests: Speed up off-cpu profiling testsIan Rogers
The off-cpu profiling test suite runs multiple recording commands with a default workload of `sleep 1` to test the off-cpu threshold configurations (specifically, above 999ms and below 1200ms). This adds a mandatory 3.0 seconds of sleep overhead. Optimize this by scaling down the thresholds and workload durations by a factor of 10: - Use `sleep 0.1` as the workload duration. - Change the above-threshold test to use `--off-cpu-thresh 50` and `sleep 0.1`. - Change the below-threshold test to use `--off-cpu-thresh 500` and `sleep 0.1`. - Update the awk period check in the above-threshold test to look for a period greater than 50,000,000 ns (50ms) instead of 999,000,000 ns (999ms). This reduces raw test sleep overhead from 3.0s down to 0.3s, yielding a ~2.7 second speedup for this test. Assisted-by: Antigravity:gemini-3.1-pro Signed-off-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-06-30perf tests: Fix flakiness in branch stack sampling testsIan Rogers
The branch stack sampling test (test 130) runs short iteration-based workloads to verify syscall, kernel, and trap branch stack sampling. Specifically, `test_syscall()` and `test_kernel_branches()` run `perf bench syscall basic` with loop counts of 8000 and 1000, and `test_trap_eret_branches()` runs `traploop` with 1000 iterations. Because these loop limits are extremely small, the total benchmark runtimes last only a few milliseconds (or less). Under high load, virtualization, or coarse sampling conditions, PMU cycle sampling fails to capture enough samples inside the brief benchmark loops. This leads to false negatives where the script output lacks the expected syscall, kernel, or trap branch entries (e.g. "ERROR: Branches missing getppid[^ ]*/SYSCALL/"). Fix this by increasing the workload loop counts to 100,000 across all three test sections. Running 100,000 loops still finishes virtually instantaneously (less than 0.1 seconds), but generates enough iterations to guarantee robust branch stack capture. Fixes: b55878c90ab9 ("perf test: Add test for branch stack sampling") Assisted-by: Antigravity:gemini-3.1-pro Signed-off-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-06-30perf tests: Fix flakiness in BPF counters test on hybrid systemsIan Rogers
The `perf stat --bpf-counters test` fails intermittently on hybrid architectures or systems with dynamic frequency scaling (DVFS). This happens because the test workload (`sqrtloop`) runs for a fixed 1-second duration, and the CPU frequency can scale dynamically between idle and maximum frequency. As the first run runs on a cold CPU and the second run runs on a warmed-up CPU (or vice versa), the number of instructions executed in 1 second differs by up to 2.2x, violating the comparison tolerance. Also, when running as root, BPF tracepoints and scheduling programs trigger frequently. Since standard `perf stat -e instructions` measures both user and kernel space instructions, it counts BPF helper and program execution overheads, whereas the BPF counters themselves do not self- measure. This introduces a large kernel-space instruction count discrepancy between standard and BPF counters. Fix these issues by: 1. Switching the workload to a strictly deterministic, iteration-based workload: `awk 'BEGIN { for (i=0; i<10000000; i++) sum+=i }'`. We pin the workload to a single random allowed CPU using `taskset -c $CPU` via a bash array. 2. Restricting the counted event to user-space only (`instructions:u` or `/u`). 3. Tightening the comparison tolerance from 20% to 15%. These modifications isolate the measurements to user-space instructions of the deterministic loop, which executes a virtually identical number of instructions on both runs (with less than 0.001% variation), eliminating Dynamic Frequency Scaling (DVFS), kernel scheduling noise, and BPF helper self-measurement overheads. Fixes: 2c0cb9f56020 ("perf test: Add a shell test for 'perf stat --bpf-counters' new option") Assisted-by: Antigravity:gemini-3.1-pro Signed-off-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
2026-06-30perf tests: Fix flakiness in trace record and replay testIan Rogers
The `perf trace record and replay` test fails intermittently on slow or virtualized hosts because the default recording workload (`sleep 1`) occasionally completes without scheduling the target `nanosleep` or `clock_nanosleep` system calls inside the recorded sample window, resulting in the error: `Failed: cannot find *nanosleep syscall`. Generalize the `perf_record_with_retry` helper in `tests/shell/lib/perf_record.sh` to support a custom record command prefix via the `PERF_RECORD_CMD` environment variable (defaulting to "perf record"). Update `trace_record_replay.sh` to use this robust retry loop running with `PERF_RECORD_CMD="perf trace record"` and a base workload of `sleep`. The test will automatically retry with scaled sleep durations (from 0.01s up to 2.0s) until the required `nanosleep` event is successfully captured. Fixes: 15bcfb96d0dd ("perf test: Add trace record and replay test") Assisted-by: Antigravity:gemini-3.1-pro Signed-off-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>