Commit Graph

19576 Commits

Author SHA1 Message Date
Linus Torvalds
dd384658c7 perf tools changes for v7.4
- 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.
 
 Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQR2GiIUctdOfX2qHhGyPKLppCJ+JwUCauUL4QAKCRCyPKLppCJ+
 JzsyAQCNjqGOBYEUaDbQAbK1/1h9D9QER9s+4aU3Np2zT9XSPAD/RkY12uxT3YAO
 NcQlaj0On+I46SkgyGzGrV9mOvDZJwo=
 =b9um
 -----END PGP SIGNATURE-----

Merge tag 'perf-tools-for-v7.4-1-2026-10-30' of 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
  ...
2026-10-30 21:54:38 -07:00
lvyating
4626d370ae perf machine: Fix NULL deref in thread__resolve_callchain_sample()
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: 29be60c93d ("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>
2026-10-27 17:45:34 -03:00
Lalit Maganti
aa0fec5853 perf pmu-events: Fix jevents.py type annotations for mypy 2.x
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: b3e9c396d0 ("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>
2026-10-27 17:40:37 -03:00
Florian Fainelli
022b0ac5d3 perf parse-events: Include errno.h before kernel headers
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: 6b9c0261b3 ("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>
2026-10-27 17:40:37 -03:00
Florian Fainelli
e0e4470aa5 perf print_insn: Include sys/types.h for ssize_t
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: 218c200f67 ("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>
2026-10-27 17:40:37 -03:00
James Clark
fe7b73c293 perf tests mmap-basic: Fix user rdpmc detection logic
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>
2026-10-27 17:40:24 -03:00
James Clark
e793b6a4be perf tests mmap-basic: Only test userspace reading on supported platforms
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 588d22b404 ("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>
2026-10-27 17:03:20 -03:00
Paul Moses
022c64992a perf mmap: Use the head selected by read_init
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: 8872481bd0 ("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>
2026-10-27 17:00:15 -03:00
Ian Rogers
98892841bd perf hist: Do not delete cumulative caller entries before stat_acc decays
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>
2026-10-27 16:59:44 -03:00
Ian Rogers
2fb45894e8 perf debug: Avoid calling eprintf() in pr_debugN() when verbose < n
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>
2026-10-27 16:59:18 -03:00
Ian Rogers
62d7cdc8d5 perf libdw: Optimize fallback logic for missing DWARF
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: bf96e296d5 ("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>
2026-10-27 16:57:56 -03:00
Linus Torvalds
c0e8d30137 Modules changes for 7.4-rc1
- 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.
 
 The changes to several #include lists have been reported to cause trivial
 conflicts in linux-next with the drm, drm-xe, and usb trees.
 -----BEGIN PGP SIGNATURE-----
 
 iQFkBAABCABOFiEEIduBR9MnFA82q/jtumpXJwqY6poFAmrWJvAbFIAAAAAABAAO
 bWFudTIsMi41KzEuMTIsMiwyFBxwZXRyLnBhdmx1QHN1c2UuY29tAAoJELpqVycK
 mOqalOYH/RpwszqX+OuRhf3G9IDokSZFZyiAJLZan3H7jZNb9VBVLYmTTRYF/UE4
 uXKeGAUXZOaUdhVjQi/1LqX3NbDO1NfUCM9sbk3EPal0L6ILbcmkBecXu9JXHxvB
 6sfEAdTMdAn28613wcnbjmdGfEkgHuDZqZeld4dIAtZ+GvLzFz0D+o0zkigCnT4I
 faKU9GLIHJe2Cn5FB40b1+M+IGY9t6bl2+WxVc1rd9oSZXfr8ptE7NPllhiOmOhD
 /aMVpeSlXzo8DYxIhvtZGwDh5NrJglPFdFRXYuHUDLxkWCCFtXRt//LtWv3EpKqp
 dgQUH5QAO5E/+OuycHFLaXOUiKVS0P4=
 =bCLk
 -----END PGP SIGNATURE-----

Merge tag 'modules-7.4-rc1' of 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()
2026-10-23 09:32:44 -10:00
Arnaldo Carvalho de Melo
95074c8492 tools headers: Sync UAPI sound/asound.h with the kernel sources
To pick up the changes in:

  91415225fb ("ALSA: uapi: Drop __bitwise and __force prefix")
  86cac980c9 ("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>
2026-10-23 09:09:01 -03:00
Arnaldo Carvalho de Melo
dd10ecd9ec tools headers: Sync UAPI linux/mount.h with the kernel sources
To pick up the changes in:

  73b40395c7 ("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>
2026-10-23 09:09:01 -03:00
Arnaldo Carvalho de Melo
46e856da1b tools headers: Sync UAPI linux/fs.h with the kernel sources
To pick up the changes in:

  21a62663d4 ("fs: fix typos in comments")
  3389648819 ("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>
2026-10-23 09:09:01 -03:00
Arnaldo Carvalho de Melo
4915cbe47e tools headers: Sync UAPI linux/fcntl.h with the kernel sources
To pick up the changes in:

  cdf930a009 ("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-23 09:09:01 -03:00
Arnaldo Carvalho de Melo
bbe94bbbed tools headers: Sync linux/socket.h with the kernel sources
To pick up the changes in:

  be3a5e06b9 ("net: add SO_PASSPIDFD_THREAD to get a thread-specific SCM_PIDFD")
  5bd369c055 ("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-22 17:17:20 -03:00
Arnaldo Carvalho de Melo
24eae148cf perf tools: Add script and make target to sync the header copies with the kernel
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:
    7cb8198761 ("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:
    cc17e386f8 ("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:
    be3a5e06b9 ("net: add SO_PASSPIDFD_THREAD to get a thread-specific SCM_PIDFD")
    5bd369c055 ("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-22 17:17:20 -03:00
Francesco Nigro
3dabc8ad8a perf test: Add test for events re-armed with PERF_EVENT_IOC_REFRESH
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 18dbcbfabf ("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-22 17:17:20 -03:00
Tengda Wu
645d694dd0 perf annotate-arm64: Support 'mrs' instruction to track 'current' pointer
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-22 17:17:02 -03:00
Tengda Wu
b61eb0fd4e perf annotate-arm64: Support per-cpu variable access tracking
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-22 17:17:01 -03:00
Tengda Wu
76a411f90b perf annotate-arm64: Support 'adrp' instruction to track global variables
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-22 17:17:01 -03:00
Tengda Wu
143ad11b37 perf annotate-arm64: Support 'add' instruction tracking
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-22 17:17:01 -03:00
Tengda Wu
cf66ee3a5d perf annotate-arm64: Support 'mov' instruction tracking
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-22 17:17:01 -03:00
Tengda Wu
861ecd5c6c perf annotate-arm64: Support stack variable tracking
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-22 17:17:01 -03:00
Tengda Wu
aa2cd2e19c perf annotate-x86: Delete stale stack state on store of untracked register
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-22 17:17:01 -03:00
Tengda Wu
f6455a6e20 perf annotate-data: Track imm_value for stack variables
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-22 17:17:01 -03:00
Tengda Wu
4043104984 perf annotate-data: Expand type_state_reg imm_value to u64
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-22 17:17:01 -03:00
Tengda Wu
f9b51a42dd perf annotate-arm64: Support store instruction tracking
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-22 17:17:01 -03:00
Tengda Wu
3edfbb8bc0 perf annotate-arm64: Support load instruction tracking
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-22 17:17:01 -03:00
Tengda Wu
7c132a86ec perf annotate-arm64: Track return type after call instructions
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-22 17:17:01 -03:00
Tengda Wu
68cedb761d perf annotate-data: Add arch_get_reg_offset helper
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-22 17:17:01 -03:00
Tengda Wu
059f12f8cd perf annotate-arm64: Enable instruction tracking support
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-22 17:17:01 -03:00
Tengda Wu
edc11f5794 perf annotate-data: Extract invalidate_reg_state() as a common helper
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-22 17:17:01 -03:00
Changbin Du
6bfe62df93 perf bench: Add atomic operations benchmark
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-21 19:25:29 -03:00
Ian Rogers
c58d1598e7 perf lock contention: Filter events before creating lock_stat
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: b4a7eff93c ("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-21 19:25:29 -03:00
James Clark
746cd5440b perf cs-etm: Respect --no-itrace option
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-21 16:14:59 -03:00
Leo Yan
e4c26138ec perf cs-etm: Synthesize missing HW_ID mappings for raw trace
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-21 16:14:59 -03:00
James Clark
18eaa04d94 perf cs-etm: Free partially created queues
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-21 16:14:59 -03:00
James Clark
31627cfb63 perf cs-etm: Don't add global v0 HW_IDs to unformatted queues
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: 19c3e4db38 ("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-21 16:14:59 -03:00
Namhyung Kim
7d0fe18bc9 perf c2c: Fix memory leaks on output fields
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: c75540e316 ("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-21 16:14:59 -03:00
Ian Rogers
aa68bfb7b0 perf test: Avoid stack trace noise in verbose=1 failure snippets
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-19 09:25:42 -03:00
James Clark
dd1c6ac2f7 perf treport: Fix profile builder type narrowing in progress callback
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: b379b70b7b ("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-19 09:25:01 -03:00
James Clark
5927da0078 perf timechart: Fix task row type narrowing in goto_task()
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: e7a72d6919 ("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-19 09:24:59 -03:00
Arnaldo Carvalho de Melo
1c90f0a3c8 perf kvm: Cast tv_usec to long to fix build on MIPS 32-bits
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-17 16:39:29 -03:00
Arnaldo Carvalho de Melo
ba2a0285a6 perf test: Take turns using the perf mlock budget in the mmaping tests
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-17 10:30:20 -03:00
Arnaldo Carvalho de Melo
4456c404c6 perf mutex: Add a robust, process-shared mutex initializer
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-17 10:30:20 -03:00
Arnaldo Carvalho de Melo
1938d59c05 perf tests: Mark the shell tests not mapping perf ring buffers
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-17 10:30:20 -03:00
Arnaldo Carvalho de Melo
b3abf1281a perf tests: Mark the C tests mapping perf ring buffers
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-17 10:30:19 -03:00
Arnaldo Carvalho de Melo
d068b2363a perf tests: Introduce a 'needs_mlock' suite flag
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>
2026-10-17 10:30:19 -03:00