Commit Graph

1482282 Commits

Author SHA1 Message Date
Ian Rogers
d227b45fc1 perf machine: Add session back pointer to fix out of bounds read
thread__e_machine_endian() decides whether a thread is live, and so
whether to read /proc/pid/exe rather than fall back to the perf.data
environment, by recovering the session from the machine:

	session = container_of(machine->machines, struct perf_session,
			       machines);
	is_live = !session->data;

That only holds when the struct machines is the one embedded in a struct
perf_session. It is not the only one. aslr_tool keeps its own in struct
aslr_tool, and hists_cumulate, hists_filter, hists_link, hists_output
and thread-maps-share each put one on the stack. For those the
container_of subtracts offsetof(struct perf_session, machines) from an
address that was never inside a session, and the following load of
session->data reads outside the object, which is what ASan reports.

Replace the derivation with an explicit link. machines__init() takes the
owning session, or NULL when the machines is standalone, and
thread__e_machine_endian() reads it back through machines__session().

A NULL session is treated as live. The tests use synthetic pids that
have no /proc entry, so the read fails there and the e_machine falls
back to EM_HOST as before, rather than being decided by whatever the
out of bounds read happened to return. perf inject registers its
session with the aslr tool once the session exists, before any event is
processed, so that tool keeps reporting file based threads as not live.

Fixes: 70351029b5 ("perf thread: Add support for reading the e_machine type for a thread")
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-25 14:08:40 +02:00
Zhan Xusheng
7e27239d22 perf symbols: Apply the symfs flat layout to the composed filename
--symfs=<dir>,flat documents itself as matching only the base name, so a
debuginfo lookup for /usr/lib/x86_64-linux-gnu/libc.so.6 should land on
<dir>/libc.so.6.debug.  It lands on
<dir>/debug/usr/lib/x86_64-linux-gnu/libc.so.6.debug instead, because the
layout is applied to a fixed prefix and the file name arrives afterwards:

	len = __symbol__join_symfs(filename, size, "/usr/lib/debug");
	snprintf(filename + len, size - len, "%s.debug", dso__long_name(dso));

perf_basename() only ever sees "/usr/lib/debug", so neither layout comes
out of it.

Compose the path as it would appear on the profiled system and join it
once, which puts the layout on the whole name.  That covers
FEDORA_DEBUGINFO, UBUNTU_DEBUGINFO, MIXEDUP_UBUNTU_DEBUGINFO,
OPENEMBEDDED_DEBUGINFO and BUILDID_DEBUGINFO, plus the same composition in
build_id_cache__find_debug().

BUILDID_DEBUGINFO needs one more step: the build id cache splits the first
two characters of the build id off into a directory name, so the basename
of the hierarchy path is only part of the build id.  Name the flat file
after the whole build id.

dso__disassemble_filename() passes a path from perf's own build id cache
rather than one on the profiled system, and every entry there is named
"elf" or "debug".  Use path__join() so the layout does not apply.

With --symfs /s,flat the lookups are now /s/libc.so.6, /s/libc.so.6.debug,
/s/sleep and /s/<build id>.debug.  hierarchy is unchanged.

Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Zhan Xusheng <zhanxusheng@xiaomi.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-25 14:07:01 +02:00
Ethan Nelson-Moore
60d454456f perf tools: Remove unused empty help-unknown-cmd.h header
tools/perf/util/help-unknown-cmd.h has been empty and unused ever since
it was added to the kernel in commit 5feaac248a ("perf tools: Move
help_unknown_cmd() to its own file") to its own file"). Remove it.

Signed-off-by: Ethan Nelson-Moore <enelsonmoore@gmail.com>
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-25 13:05:48 +02:00
Ian Rogers
97e94e5c5a perf test: Fix PMU metric parsing tests for unknown literals
On ARM the #slots literal may or may not be present, it won't be present
on x86. As it is missing it causes the ampereone and ampereonex PMU
metric tests to fail when run say on x86.

Extend the fake_pmu logic so that in these test cases we fake the
unknown literals like #slots as 1.0.

When building with JEVENTS_ARCH=all the ampere metric tests no longer
fail.

Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-25 12:51:49 +02:00
Namhyung Kim
9d86dd191d perf test: Fix record tests on hybrid machines
Currently the leader sampling test looks for "cycles:" string to match
the event and retrieve the value before the event name.  But it won't
work on hybrid systems as the event name is different like below.

  $ perf script | grep -m 10 brstack
      perf 3322152 1873980.978431:     625379 cpu_atom/cycles/:      558200cc40cf brstack_bench+0x31 (/home/namhyung/project/linux/tools/perf/perf)
      perf 3322152 1873980.978431:     625379 cpu_atom/cycles/:      558200cc40cf brstack_bench+0x31 (/home/namhyung/project/linux/tools/perf/perf)
      perf 3322152 1873980.978598:     612177 cpu_atom/cycles/:      558200cc4082 brstack_foo+0x17 (/home/namhyung/project/linux/tools/perf/perf)
      perf 3322152 1873980.978598:     612177 cpu_atom/cycles/:      558200cc4082 brstack_foo+0x17 (/home/namhyung/project/linux/tools/perf/perf)
      perf 3322152 1873980.978762:     591859 cpu_atom/cycles/:      558200cc403d brstack_bar+0x0 (/home/namhyung/project/linux/tools/perf/perf)
      perf 3322152 1873980.978762:     591859 cpu_atom/cycles/:      558200cc403d brstack_bar+0x0 (/home/namhyung/project/linux/tools/perf/perf)
      perf 3322152 1873980.978948:     628505 cpu_atom/cycles/:      558200cc403e brstack_bar+0x1 (/home/namhyung/project/linux/tools/perf/perf)
      perf 3322152 1873980.978948:     628505 cpu_atom/cycles/:      558200cc403e brstack_bar+0x1 (/home/namhyung/project/linux/tools/perf/perf)
      perf 3322152 1873980.979146:     669816 cpu_atom/cycles/:      558200cc40e5 brstack_bench+0x47 (/home/namhyung/project/linux/tools/perf/perf)
      perf 3322152 1873980.979146:     669816 cpu_atom/cycles/:      558200cc40e5 brstack_bench+0x47 (/home/namhyung/project/linux/tools/perf/perf)

But we can control the output format of perf script using -F option.  So
we knows where the period is in the output.  To filter by symbol name,
"ip" and "sym" fields are required as well.

  $ perf script -F period,ip,sym | grep -m 10 brstack
      625379      558200cc40cf brstack_bench
      625379      558200cc40cf brstack_bench
      612177      558200cc4082 brstack_foo
      612177      558200cc4082 brstack_foo
      591859      558200cc403d brstack_bar
      591859      558200cc403d brstack_bar
      628505      558200cc403e brstack_bar
      628505      558200cc403e brstack_bar
      669816      558200cc40e5 brstack_bench
      669816      558200cc40e5 brstack_bench

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Tested-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-25 12:50:28 +02:00
Namhyung Kim
79b617136e perf test: Fix record tests on Intel Broadwell
I noticed it failed for leader sampling tests on Broadwell.  It's
because the period of groups members are a little bit different.  Maybe
there's an hardware issue but anyway it's close enough to treat them as
same.  I printed the value like below.

  $ perf test record
  ...
  prev: 462507, curr: 462506
  prev: 494783, curr: 494782
  prev: 454350, curr: 454349
  prev: 502782, curr: 502781
  prev: 566693, curr: 566692
  prev: 606558, curr: 606557
  prev: 559770, curr: 559769
  prev: 595737, curr: 595736
  prev: 643386, curr: 643385
  prev: 663672, curr: 663671
  prev: 620622, curr: 620621
  prev: 650419, curr: 650418
  Leader sampling [Failed inconsistent cycles count]

Let's update the logic to compare values to allow 1% of errors.

Also I think it should compare only if sees the non-leader samples so
split the check of (($index % 2)).

Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Tested-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-25 12:50:02 +02:00
Namhyung Kim
da5f6a6a32 perf test: Fix errors when deleting data in 'perf record' tests
'perf record' with multithreads would create a data directory instead of
a file.  But the cleanup and retry logic expect a file and try to delete
them with 'rm -f' which would fail.  Add '-r' flag to remove
directories.

  rm: cannot remove '/tmp/__perf_test.perf.data.ZVHTw.old': Is a directory

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Tested-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-25 12:48:04 +02:00
Sandipan Das
1a097d93ca perf jevents: Limit the number of JSON reading workers
The ProcessPoolExecutor is created without max_workers, so
concurrent.futures defaults to one worker per CPU and forks all of them
when the first task is submitted. Each worker costs the parent a few
file descriptors. For systems with high core-count processors like the
AMD EPYC 9996, the pool can easily exhaust RLIMIT_NOFILE as seen below.

  File ".../multiprocessing/popen_fork.py", line 65, in _launch
    child_r, parent_w = os.pipe()
  OSError: [Errno 24] Too many open files

The error is reported, but jevents.py does not exit. The workers that
did start stay blocked waiting for work and are never joined, so the
build eventually hangs. Other targets keep building in the meantime,
leaving the traceback several lines above the point where the build
stalls.

Limit the pool instead of sizing it against the descriptor limit, which
would mean relying on how many descriptors concurrent.futures needs for
each worker. At least for recent AMD EPYC processors, reading the JSON
files does not need many workers to be fast and things typically stop
scaling beyond 32 workers. Hence, a small upper bound keeps the speedup
and stays well inside any usable limit.

Fixes: eaab2eb09d ("perf pmu-events: Parallelize JSON and metric pre-computation in jevents.py")
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Sandipan Das <sandipan.das@amd.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-25 12:41:37 +02:00
Tengda Wu
fe52988684 perf llvm: Fix memory leak of args->fileloc in symbol__disassemble_llvm()
In symbol__disassemble_llvm(), after calling llvm_addr2line(), if the
subsequent disasm_line__new() fails, the code directly jumps to 'err'
without freeing args->fileloc, leading to a memory leak.

Fix this by explicitly calling free(args->fileloc) before jumping to the
error handling path when disasm_line__new() fails.

Fixes: 0488568178 ("perf annotate: LLVM-based disassembler")
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Tengda Wu <wutengda@huaweicloud.com>
Cc: Steinar H. Gunderson <sesse@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-25 11:54:02 +02:00
Jianping Liu
fcf1fccdc9 perf annotate: Fix NULL pointer dereference in loongarch_call__parse
loongarch_call__parse() dereferences the return value of strchr()
without NULL check:

  name = strchr(endptr, '<');
  name++;

When objdump output for a 'bl' (branch-and-link) instruction does not
contain a symbol name delimited by '<' and '>' (e.g., when the call
target has no associated symbol), strchr() returns NULL, and the
subsequent name++ produces a wild pointer (0x1). This leads to a
segmentation fault when strchr() is later called with this invalid
pointer:

  #0  __strchr_lasx () from /lib64/libc.so.6
  #1  loongarch_call__parse () at arch/loongarch/annotate/instructions.c:29
  #2  disasm_line__init_ins () at util/annotate.c:1205
  ...

The objdump line triggering the crash looks like:

  bl              98824   # 0x9000000000641ea0

Note the absence of "<function_name>" after the address.

Rather than aborting parse with -1 (which would clear dl->ins.ops and
lose the is_call attribute, preventing the TUI from drawing branch
arrows and navigating the call), follow the same pattern as the generic
call__parse() in util/disasm.c: when the symbol name is absent, jump to
the address-based symbol lookup so that ops->target.sym can still be
resolved via maps__find_ams() using the already-parsed target address.
This preserves is_call semantics and keeps TUI navigation working.

Reviewed-by: Ming Wang <wangming01@loongson.cn>
Tested-by: WANG Rui <wangrui@loongson.cn>
Signed-off-by: Jianping Liu <frankjpliu@tencent.com>
Acked-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-25 00:55:45 +02:00
James Clark
1bb97afa30 perf build: Follow sourced files when running shellcheck
Shellcheck follows sourced scripts when -a is provided, but only when
that file is also provided on the command line along with the one being
checked. We only ever provide one file at a time to shellcheck, so -a
does nothing.

Improve coverage by following sources using the script's directory as
the base path.

Signed-off-by: James Clark <james.clark@linaro.org>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-25 00:55:45 +02:00
James Clark
a9aa5c5e40 perf test: Remove redundant shellcheck source paths
The minimum required shellcheck version treats paths with leading
variables as starting from the script's current directory, so shellcheck
is able to source all of these files without needing the extra
directives:

  v0.7.2 - 2021-04-19

  Changed
   * SC1090: A leading $x/ or $(x)/ is now treated as ./ when locating files

Remove them to avoid future copy pasting and confusion that they are
required. Because the paths weren't actually followed, they didn't have
to be accurate and accepted any string to silence the warning.

Signed-off-by: James Clark <james.clark@linaro.org>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-25 00:55:45 +02:00
Dapeng Mi
a18bf13d9b perf jevents: Rename OMR offcore_rsp attribute to offmodule_rsp
The kernel renamed the OMR data attribute from offcore_rsp to
offmodule_rsp to avoid confusion and keep the naming consistent.

So update the perf jevents msrmap accordingly.

Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-25 00:55:45 +02:00
James Clark
3b364119a9 perf buildid-list: Fix empty output for AUX data
perf record enables buildid_all for AUX trace because buildid-list does
not decode AUX data to identify hit DSOs. Historically those build IDs
were available in HEADER_BUILD_ID, and buildid-list disabled hit
filtering when HEADER_AUXTRACE was present.

Build IDs are now carried by MMAP2 records by default and the build-ID
header is omitted. perf_session__list_build_ids() forces with_hits when
the header is absent so that it processes the event stream. That also
filters the result to DSOs referenced by ordinary samples. AUX data has
no such samples unless the trace is decoded, so every DSO is dropped and
perf archive reports that no build IDs were found.

Process the event stream whenever the build-ID header is absent,
allowing MMAP2 build IDs to be read, but do not enable hit filtering for
AUX data, this ensures that all build-IDs are included for AUX data.

Fixes: 6bd89ae7d1 ("perf record: Make sure to update build-ID cache")
Reviewed-by: Ian Rogers <irogers@google.com>
Assisted-by: Codex:GPT-5.6-Sol
Signed-off-by: James Clark <james.clark@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-25 00:55:44 +02:00
Jens Remus
1eb782d60d perf evsel: Improve callchain warning for s390
On s390 the kernel uses s390 back chain instead of frame pointers for
stack tracing of user space since v6.7 commit aa44433ac4 ("s390: add
USER_STACKTRACE support").  This is because frame pointers on s390
cannot be used for stack tracing. [1]

This requires user space to maintain a s390 back chain.  For instance
user space to be built with compiler option '-mbackchain' (instead of
'-fno-omit-frame-pointer' used on other architectures, which should
better not be used on s390 [1]).  Only few distributions and users build
user space with '-mbackchain'.  Therefore '--call-graph fp' may in
practice not produce the expected results.

Commit ca76fb67eb ("perf evlist: Improve default event for s390")
changed the default '-g' option to 'dwarf' on s390 and added a warning
for s390 that wrongly claimed that "Framepointer unwinding lacks kernel
support".  This warning resulted from a misinterpretation of comments
in s390 cpumsf_pmu_event_init().

The restriction in cpumsf_pmu_event_init() applies to callchain sampling
with the s390 CPU Measurement Sampling Facility (CPUMSF) hardware PMU.
CPUMSF events, such as 'cycles', do not support callchain sampling.
This is independent of whether perf uses the 'fp' or 'dwarf' call-graph
mode.  The CPUMSF PMU provides samples collected asynchronously, making
it impossible to associate a callchain to the historic IPs.  Therefore
callchains can only be used with software events on s390.

Remove the incorrect warning.  The kernel supports the 'fp' call-graph
mode on s390 by walking the back chain.  Do not replace it with a
hint to use 'dwarf' when the resulting callchain is incomplete.  Such a
suggestion could imply that 'fp' is inherently inferior.  The same
general limitation exists on other architectures when user space is not
built with frame pointers (i.e. '-fno-omit-frame-pointers').

Instead, warn on s390 when callchain sampling is requested with an event
provided by the CPUMCF or CPUMSF hardware PMUs, because that combination
is not supported.

Update the perf record documentation to state that 'dwarf' is the
default call-graph mode on s390 and that 'fp' uses back chain instead
of frame pointers on s390.

Note that '--call-graph fp' may also be useful for other applications,
such as OpenJDK maintaining a s390 back chain (does not require JVM
option '-XX:+PreserveFramePointer' on s390):

  $ perf record --call-graph fp ... -- \
    java -XX:+UnlockDiagnosticVMOptions -XX:+DumpPerfMapAtExit ...

[1]: s390: Stack tracing using Frame Pointer, Back Chain, and SFrame,
     https://conf.gnu-tools-cauldron.org/opo25/talk/Y3CVHY/

Fixes: ca76fb67eb ("perf evlist: Improve default event for s390")
Reviewed-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
Acked-by: Ian Rogers <irogers@google.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-25 00:55:44 +02:00
Christian Melendez
d6f751c7ad perf stat: Document task-clock/cpu-clock in TIMINGS
task-clock/cpu-clock appear in perf stat's own example output but were
never explained in perf-stat.txt, unlike time elapsed/user/sys.  This
came up unanswered on the list in 2013 and 2015 without docs ever being
added.

Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Christian Melendez <chrismelnu@gmail.com>
Link: https://lore.kernel.org/all/arWi_dY4y15J2rqh@google.com ]
[ Removed the :u modifier from the task-clock example, per Namhyung request ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-25 00:53:56 +02:00
Thomas Falcon
dd0b7ec38d perf c2c: Print memory region data with stdio output
Print memory range data in perf-c2c subcommand. Only available in stdio
mode currently. If memory ranges are not supported or present, print
nothing.

Example output of perf c2c report --stdio:

=================================================
                  Memory Ranges
=================================================
Range 0: [0x0000000000000000-0x00000000bfffffff] Node 0, local region id 0, remote region id 255
Range 1: [0x0000000100000000-0x000000203fffffff] Node 0, local region id 0, remote region id 255
Range 2: [0x0000008000000000-0x0000027fffffffff] Node -2, local region id 1, remote region id 255
Range 3: [0x0000028000000000-0x0000047fffffffff] Node -2, local region id 1, remote region id 255
Range 4: [0x0000048000000000-0x000004ffffffffff] Node -2, local region id 1, remote region id 255

Reviewed-by: Ian Rogers <irogers@google.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Assisted-by: Sashiko:gemini-3.1-pro-preview
Signed-off-by: Thomas Falcon <thomas.falcon@intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-24 19:33:20 +02:00
Dapeng Mi
8eca6fa643 perf tools: Show memory region in perf-script subcommand
Show the memory region in perf-script subcommand. Memory region is found
in the mem_region field of the memory information data source. This
field was included with the introduction of support for the Off-module
Response facility (OMR) [1] in Intel's Diamond Rapids and Nova Lake
Architectures.

An example of perf-script output with the new memory region field is shown
below:

      thread 5/0 ...	|OP LOAD|LVL L3 hit|SNP HitM|TLB L1 or L2 hit|LCK No|BLK  N/A|Region Local-shared-cache              ffffffff9f002aba
      thread 2/0 ...	|OP LOAD|LVL L3 hit|SNP None|TLB L1 or L2 hit|LCK No|BLK  N/A|Region Local-shared-cache              ffffffff9dc54c95
      thread 8/0 ...	|OP LOAD|LVL L3 hit|SNP HitM|TLB L1 or L2 hit|LCK No|BLK  N/A|Region Other-non-shared-cache          ffffffff9dc54db3
      thread 0/0 ...	|OP LOAD|LVL LFB/MAB hit|SNP None|TLB L1 or L2 hit|LCK No|BLK  Addr|Region N/A                       ffffffff9dc54db3
      thread 2/0 ...	|OP LOAD|LVL L0 hit|SNP None|TLB L1 or L2 hit|LCK Yes|BLK  N/A|Region N/A                            ffffffff9f002a8c
      thread 0/0 ...	|OP LOAD|LVL L3 hit|SNP HitM or Fwd|TLB L1 or L2 hit|LCK No|BLK  N/A|Region Local-non-shared-cache   ffffffff9f002aba
      thread 0/0 ...	|OP LOAD|LVL L3 hit|SNP None|TLB L1 or L2 hit|LCK No|BLK  N/A|Region Local-shared-cache          ffffffff9dc54ca7
     thread 30/0 ...	|OP LOAD|LVL LFB/MAB hit|SNP None|TLB L1 or L2 hit|LCK Yes|BLK  N/A|Region N/A                       ffffffff9dcc1ff2
     thread 30/0 ...	|OP LOAD|LVL RAM hit|SNP None|TLB L1 or L2 hit|LCK No|BLK  N/A|Region Mem-0                          ffffffff9dc54c95
     thread 19/0 ...	|OP LOAD|LVL LFB/MAB hit|SNP None|TLB L1 or L2 hit|LCK No|BLK  N/A|Region N/A                        ffffffff9f002cbb
     thread 19/0 ...	|OP LOAD|LVL L3 hit|SNP HitM or Fwd|TLB L1 or L2 hit|LCK No|BLK  N/A|Region Local-non-shared-cache   ffffffff9f002aba

[1]: https://lore.kernel.org/all/20260114011750.350569-1-dapeng1.mi@linux.intel.com/

Reviewed-by: Ian Rogers <irogers@google.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Assisted-by: GitHub-Copilot:claude-opus-4-8
Assisted-by: Sashiko:gemini-3.1-pro-preview
Co-developed-by: Thomas Falcon <thomas.falcon@intel.com>
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Thomas Falcon <thomas.falcon@intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-24 19:29:45 +02:00
Dapeng Mi
41544ef9c9 perf tools: Show memory region in perf-c2c subcommand
Add memory region field to the cacheline list view to help users
identify the memory region to which the cacheline belongs. The memory
region field was included with the introduction of support for the
Off-module Response facility (OMR) [1] in Intel's Diamond Rapids and
Nova Lake architectures.

An example of the new perf c2c output including the memory region
field is shown below:

      0  0xffffffff84eb0040     N/A     0    1205   23.25%      544      544        0     1677     1677
      1  0xffffffff84f03a80     N/A     0       1   18.12%      424      424        0      585      585
[...]
     19  0xffffffff845bc840   Mem-0     0      13    0.30%        7        7        0       31       31
     20  0xff3bbba284520a00     N/A     0      10    0.26%        6        6        0       11       11
     21  0xff3bbbe0bc833500     N/A     0      24    0.26%        6        6        0       30       30

[1]: https://lore.kernel.org/all/20260114011750.350569-1-dapeng1.mi@linux.intel.com/

Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Reviewed-by: Ian Rogers <irogers@google.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Assisted-by: GitHub-Copilot:claude-opus-4-8
Assisted-by: Sashiko:gemini-3.1-pro-preview
Co-developed-by: Thomas Falcon <thomas.falcon@intel.com>
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Thomas Falcon <thomas.falcon@intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-24 19:26:53 +02:00
Thomas Falcon
6cdecad561 perf header: Support memory ranges
Memory ranges were created to track different types of memory, such as
persistent, high bandwidth, or CXL-attached, that may be present on a
system for performance monitoring and resource control purposes.

Memory range data are parsed from the ACPI MRRM table and exposed to
userspace tools via sysfs [1]. Memory range data is read from:

	/sys/firmware/acpi/memory_ranges/rangeX

With the following attributes:

	u64 base;
	u64 length;
	int node;
	u8  local_region_id;
	u8  remote_region_id;

Read memory range data from sysfs if present and save it in the header
of the perf data file under a new feature bit, HEADER_MEMORY_RANGES
(35). Memory range data can be viewed with the --header or --header-only
options of perf-report and perf-script.

Example output:
 # memory ranges (nr 5):
 # range0: [0x0000000000000000-0x00000000bfffffff], node = 0, local_region_id = 0, remote_region_id = 255
 # range1: [0x0000000100000000-0x000000203fffffff], node = 0, local_region_id = 0, remote_region_id = 255
 # range2: [0x0000008000000000-0x0000027fffffffff], node = -2, local_region_id = 1, remote_region_id = 255
 # range3: [0x0000028000000000-0x0000047fffffffff], node = -2, local_region_id = 1, remote_region_id = 255
 # range4: [0x0000048000000000-0x000004ffffffffff], node = -2, local_region_id = 1, remote_region_id = 255

[1]: https://lore.kernel.org/lkml/20250505173819.419271-1-tony.luck@intel.com/

Reviewed-by: Ian Rogers <irogers@google.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Assisted-by: GitHub-Copilot:claude-opus-4-8
Assisted-by: Sashiko:gemini-3.1-pro-preview
Signed-off-by: Thomas Falcon <thomas.falcon@intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-24 19:26:03 +02:00
Dapeng Mi
f6659329a4 perf mem: Add support for printing PERF_MEM_LVLNUM_L0
Add support for printing PERF_MEM_LVLNUM_L0 in perf mem report.

The L0 cache is newly added a small piece of cache which is the closest,
lowest-latency memory cache tied directly to the execution pipeline.

The table "Table 9-4. Data Source Field Encodings for Panther Cove and
Coyote Cove Microarchitectures" in the ISE doc chapter "9.2.1 Panther
Cove and Coyote Cove Microarchitectures Memory Auxiliary Field
Layout"[1] indicates the code "01H" means the "L0 Hit - Minimal latency
core cache hit. This request was satisfied by the L0 data cache."

[1]: https://www.intel.com/content/www/us/en/content-details/922690/intel-architecture-instruction-set-extensions-programming-reference.html

Assisted-by: Sashiko:gemini-3.1-pro-preview
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Reviewed-by: Ian Rogers <irogers@google.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Co-developed-by: Thomas Falcon <thomas.falcon@intel.com>
Signed-off-by: Thomas Falcon <thomas.falcon@intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-24 19:25:34 +02:00
Thomas Falcon
06d5ce78e4 perf mem: Fix size tracking for mem_lvl's in perf_script__meminfo_scnprintf()
When printing memory info in perf script, the entire size of the
buffer is passed to perf_mem__lvl_scnprintf() instead of the remaining
size. Pass the remaining buffer size instead.

This issue was detected by sashiko during an internal code review.

Fixes: fdefc3750e ("perf mem: Print memory operation type")
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Reviewed-by: Ian Rogers <irogers@google.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Cc: Leo Yan <leo.yan@linux.dev>
Assisted-by: Sashiko:gemini-3.1-pro-preview
Signed-off-by: Thomas Falcon <thomas.falcon@intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-24 19:25:01 +02:00
Tiezhu Yang
ed1293302f perf loongarch: Fix discarded const qualifier in _get_field()
When building perf on LoongArch, the following compilation errors occur:

  CC      arch/loongarch/util/header.o
arch/loongarch/util/header.c: In function '_get_field':
arch/loongarch/util/header.c:31:15: error: assignment discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers]
   31 |         line2 = strrchr(line, ' ');
      |               ^
arch/loongarch/util/header.c:36:12: error: assignment discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers]
   36 |         nl = strrchr(line, '\n');
      |            ^
cc1: all warnings being treated as errors

Declare 'line2' and 'nl' as const char * to ensure type safety. In modern
glibc versions, strrchr() returns a 'const char *' if the input string is
const.

This is similar to commit 7378b6656a ("perf riscv: Fix discarded const
qualifier in _get_field()").

Fixes: 492ac37fa3 ("perf kvm: Add kvm-stat for loongarch64")
Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
Acked-by: Huacai Chen <chenhuacai@loongson.cn>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Bibo Mao <maobibo@loongson.cn>
Cc: Huacai Chen <chenhuacai@kernel.org>
Cc: stable@vger.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-24 19:22:25 +02:00
Stian Halseth
d8fd56321d perf unwind-libdw: Fix reading the stack of a 32-bit task
memory_read() hands libdw 8 bytes whatever the sampled task's ABI. For a
32-bit task libdw keeps the low 32 bits (__libdwfl_frame_reg_set()), so
on a big-endian machine each word read from the stack or a DSO is the
one at addr + 4, and unwinding stops at the first frame restored from
the stack. On sparc the 8-byte load from a stack address that is only
4-byte aligned even traps, and perf dies with SIGBUS. Read 4 bytes for a
PERF_SAMPLE_REGS_ABI_32 sample.

A recording of the other byte order has each sample swapped in 8-byte
units when it is read (perf_event__all64_swap()), which leaves the
4-byte words of a 32-bit stack dump reversed and paired up wrongly.
Undo the swap of the unit holding the word and swap the word itself, as
__evsel__parse_sample() does for PERF_SAMPLE_CPU.

Suggested-by: Ian Rogers <irogers@google.com>
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Stian Halseth <stian@itx.no>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-24 19:22:06 +02:00
Ian Rogers
edd8a9fe2e perf evsel: Report an allocation failure as ENOMEM when setting filters
evsel__set_filter() and evsel__append_filter() return -1 when the strdup()
or asprintf() that builds the new filter string fails, and
evlist__set_tp_filter() and evlist__append_tp_filter() do the same when
handed the NULL that asprintf__tp_filter_pids() returns for the same
reason. In every case the only thing that can have gone wrong is an
allocation.

Callers all test the result with "< 0" or for being non-zero, so -1 has
been as good as any other error so far, but it is not an errno and so
cannot be printed as one. A caller that does, such as

	str_error_r(-err, errbuf, sizeof(errbuf))

turns it into EPERM and reports a failure to allocate as "Operation not
permitted", which is no help to anyone trying to work out what happened.

Return -ENOMEM instead, which is what these failures are.

Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-22 15:00:48 +02:00
Ian Rogers
1865b4164b perf trace: Free the whole evsel_trace in evsel__put_and_free_priv
Every evsel->priv in builtin-trace.c is a struct evsel_trace, allocated
by evsel_trace__new(). It holds a syscall_arg_fmt array in its fmt
member, which evsel__syscall_arg_fmt() allocates on demand for the
syscalls:sys_{enter,exit}_SYSCALL tracepoints and for every other
tracepoint that gets its arguments pretty printed.

evsel__put_and_free_priv() only did zfree(&evsel->priv), releasing the
evsel_trace itself and leaking that array. Use evsel_trace__delete(),
which frees fmt first, exactly as the out_delete path of
evsel__syscall_arg_fmt() already does.

The current callers are all error paths that run before fmt can have
been allocated, so nothing leaks in practice today, but the helper is
the obvious thing to reach for whenever an evsel is discarded and it
should be safe for that.

Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-22 15:00:23 +02:00
Ian Rogers
1b9822a297 perf trace: Include the headers declaring pid_t, strcmp and assert
trace_augment.h uses pid_t in the augmented_syscalls__set_filter_pids()
prototype and in the !HAVE_BPF_SKEL stub. bpf_trace_augment.c calls
strcmp() in augmented_syscalls__find_by_title() and assert() in
augmented_syscalls__create_bpf_output(), but neither pulls in the header
that declares what it uses. Both happen to build today only because
something else in the include chain drags <sys/types.h>, <string.h> and
<assert.h> in first, which is not guaranteed and does not hold on libcs
such as musl that keep the POSIX namespaces strictly separated.

Include <sys/types.h>, <string.h> and <assert.h> explicitly.

Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-22 14:59:58 +02:00
Arnaldo Carvalho de Melo
9db4e9d6cc perf annotate-data: Show the sample count in the data-type browser
The data-type browser has a samples view, selected with -n (or with
annotate.show_nr_samples), in which browser__write_overhead() prints a
local nr_samples variable that is initialized to zero and never
updated, so every member is listed as having no samples while the
period and percent columns for the same entry are filled in.

Print the histogram entry's own count instead.

This predates the load/store counter split, so fix it ahead of that
patch: the split then only has to adapt a line that is already correct,
and this fix can be picked on its own.

Fixes: d001c7a7f4 ("perf annotate-data: Add hist_entry__annotate_data_tui()")
Acked-by: Namhyung Kim <namhyung@kernel.org>
Assisted-by: LLM
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-22 14:52:08 +02:00
Dapeng Mi
4cc2f9c885 perf util: Explicitly include required headers
Sashiko complains "the perf tool can be compiled with musl libc, which
enforces strict POSIX namespace separation and does not implicitly
include headers. Relying on implicit header inclusion can cause build
failures under musl."

Include the required headers explicitly to avoid such failures.

Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-22 14:50:54 +02:00
Dapeng Mi
67b2c43c0c perf aslr: Add missing SIMD handling in aslr_tool__process_sample()
Currently the SIMD register sampling is supported, but the corresponding
handling is missed in aslr_tool__process_sample(). This can break parsing
of the sample record.

Add the missing SIMD register handling in aslr_tool__process_sample().

Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-22 14:50:04 +02:00
Ian Rogers
551fbfaa06 perf test: Add build tests for clang and libbfd demangling
Three build configurations broke recently without the build test suite
noticing, as none of them were covered:

  - "CC=clang" on its own. CXX is only set to clang++ by "make LLVM=1",
    so CXX stays as g++ and used to be passed clang's flags.
  - "CC=clang BUILD_NONDISTRO=1", where libbfd.c failed clang's
    -Wthread-safety analysis.
  - "BUILD_NONDISTRO=1 NO_DEMANGLE=1", the only combination that
    compiles the libbfd demangling in symbol.c, which referred to
    identifiers nothing declared.

Add the three. The clang ones need clang installed, and the libbfd ones
reuse the existing binutils check.

Testing that perf was built isn't enough for the first one. Feature
tests are allowed to fail, so a broken C++ compiler command line doesn't
fail the build, it silently turns off every feature needing a C++
compiler and the build still produces a working perf. Check that libLLVM
is still built in, which is the C++ dependent feature perf can report
on, so the test fails instead of quietly producing a perf with less in
it than the default build has.

Only make that check when libLLVM can be built in the first place. The
llvm-perf feature test compiles and links against the llvm-devel/llvm-dev
headers and libraries and needs version 13 or newer, so the presence of
llvm-config on its own says nothing. Probe the same way the feature test
does and fall back to only testing that perf was built when the probe
fails, rather than turning a machine without the LLVM development files
into a spurious failure.

For the same reason the clang tests must not reuse a feature dump made
with the default compiler, so exclude them from REUSE_FEATURES_DUMP.

Signed-off-by: Ian Rogers <irogers@google.com>
Assisted-by: Antigravity:gemini-3.1-pro
Acked-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-22 14:46:31 +02:00
Ian Rogers
a5cac2df8b perf build: Remove leftovers of removed build options
NO_LIBDW_DWARF_UNWIND, NO_SYSCALL_TABLE and the embedded clang/LLVM
support were all removed, but each removal left the matching entry in
the build test suite behind:

  run += make_no_libdw_dwarf_unwind
  run += make_no_syscall_tbl
  run += make_with_clangllvm

None of these have a make_* variable defining what to build, so $($@)
expands to nothing and each one silently repeats the plain "make_pure"
build. The suite therefore spends six builds, as every test is also run
with O=, appearing to cover options that no longer exist.

Remove them, along with the NO_LIBDW_DWARF_UNWIND comment that is still
in Makefile.perf.

Fixes: 2e9191573a ("perf build: Remove NO_LIBDW_DWARF_UNWIND option")
Fixes: 3cc550f5bb ("perf tools: Remove dependency on libaudit")
Fixes: 56b11a2126 ("perf bpf: Remove support for embedding clang for compiling BPF events (-e foo.c)")
Signed-off-by: Ian Rogers <irogers@google.com>
Assisted-by: Antigravity:gemini-3.1-pro
Acked-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-22 14:46:02 +02:00
Ian Rogers
4f4387a07f perf build: Check the version of the compiler that is used
The flex and bison flags are adjusted for clang older than 13.0.0, which
doesn't grok -Wno-unused-but-set-variable. The test is reached because
CC_NO_CLANG says CC is clang, but the version comes from $(CLANG), which
defaults to plain "clang" and needn't be the compiler in use:

  $ make CC=clang-19 CLANG=clang-12
  version from $(CLANG) -> 12.0.0, flag stripped
  version from $(CC)    -> 19.1.7, flag kept

Dropping the flag lets the warnings it suppresses in the generated flex
and bison code through, and those are errors under -Werror.

Ask $(CC) instead, as that is what compiles the code.

Fixes: 878460e8d0 ("perf build: Remove -Wno-unused-but-set-variable from the flex flags when building with clang < 13.0.0")
Signed-off-by: Ian Rogers <irogers@google.com>
Assisted-by: Antigravity:gemini-3.1-pro
Acked-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-22 14:45:48 +02:00
Ian Rogers
bd874cd835 perf build: Use the given CC rather than clang in clang builds
The clang block is entered when CC_NO_CLANG has determined that CC is
clang, but it then ignores CC and hard codes $(CLANG), which defaults to
plain "clang". Building with a versioned compiler silently switches
compiler:

  $ make CC=clang-19		# actually builds with "clang"

Worse, the target triple is probed with $(CLANG) too, so on a machine
that only has versioned binaries installed the probe produces nothing
and the build stops:

  $ make CC=clang-19
  *** Specify CROSS_COMPILE or add CLANG_TARGET_FLAGS for x86_64

Use $(CC) in both places. Within the block CC is known to be clang, and
for "make LLVM=1" CC is already $(CLANG), so nothing changes there.

$(CLANG) is left as it is for BPF skeletons, as bpf_skel.mak builds
those with "$(CLANG) --target=bpf" whatever CC happens to be.

Fixes: 4772e66cb4 ("perf build: Support build with clang")
Signed-off-by: Ian Rogers <irogers@google.com>
Assisted-by: Antigravity:gemini-3.1-pro
Acked-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-22 14:45:33 +02:00
Ian Rogers
c8592f8da8 perf build: Only pass clang flags to CXX when CXX is clang
Building with "make CC=clang" appends clang's --target= and
-fintegrated-as to CXX, but CXX is only set to clang++ by "make LLVM=1".
With just CC=clang, CXX is still g++ and every C++ feature test dies:

  g++: error: unrecognized command-line option '--target=...'
  g++: error: unrecognized command-line option '-fintegrated-as'

The failures are silent, as feature tests are allowed to fail, so the
build quietly loses libllvm and C++ demangling support:

  $ make CC=clang && grep LIBLLVM .config-detected
  (nothing, whereas a gcc build reports CONFIG_LIBLLVM=y)

The block is entered when CC_NO_CLANG says CC is clang, which says
nothing about CXX. Probe CXX the same way tools/scripts/Makefile.include
probes CC, and only add the flags when CXX really is clang++.

Mixing a clang-built C with a g++-built C++ is fine here, the C++ code
is linked with -lstdc++ already.

Fixes: 4772e66cb4 ("perf build: Support build with clang")
Signed-off-by: Ian Rogers <irogers@google.com>
Assisted-by: Antigravity:gemini-3.1-pro
Acked-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-22 14:45:16 +02:00
Ian Rogers
cd1f5f952a perf pmu: Include the headers that are used
pmu.c uses errno, free() and the str*() functions but declares none of
them directly. <string.h> arrives by way of <linux/string.h>, and
<errno.h> and <stdlib.h> come from whatever the other headers happen to
drag in, which is fragile and breaks on C libraries that don't nest
their headers the same way.

Include the three directly.

<ctype.h> is deliberately not added. The isdigit(), tolower() and
toupper() used here are the macros from <linux/ctype.h>, which is
included on purpose and documents that it doesn't handle EOF the way the
standard C library does, so pulling in <ctype.h> would change which
implementation is used.

size_t is left alone too, as <stdio.h> is already included directly and
declares it.

No functional change.

Signed-off-by: Ian Rogers <irogers@google.com>
Assisted-by: Antigravity:gemini-3.1-pro
Acked-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-22 14:45:12 +02:00
Ian Rogers
f963226016 perf libbfd: Include the headers that are used
libbfd.c uses errno, PATH_MAX, strdup(), strlen(), strcmp(), memcpy()
and pthread_once() but relies on other headers to drag in <errno.h>,
<limits.h>, <string.h> and <pthread.h>. The BPF disassembly code needs
<inttypes.h> for PRIx64 and <stdint.h> for uintptr_t for the same
reason.

Include them directly and group the includes so that the system ones
come before perf's own.

No functional change.

Signed-off-by: Ian Rogers <irogers@google.com>
Assisted-by: Antigravity:gemini-3.1-pro
Acked-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-22 14:45:02 +02:00
Ian Rogers
ecbc5aac7d perf symbol: Fix the build when demangling with libbfd
cxx_demangle_sym() calls bfd_demangle() with the DMGL_PARAMS and
DMGL_ANSI flags, but nothing declares them. The
"#define PACKAGE 'perf'", "#include <bfd.h>" and the DMGL_ definitions
were left behind in symbol-elf.c when the demangling code moved to
symbol.c, and libiberty's demangle.h that defines the flags isn't
installed by every binutils package. The cplus_demangle() variant is
missing a declaration for the same reason.

The code is only built when the C++ ABI's __cxa_demangle() is
unavailable, so most builds never compile it:

  $ make BUILD_NONDISTRO=1 NO_DEMANGLE=1
  util/symbol.c:2714: error: 'DMGL_PARAMS' undeclared
  util/symbol.c:2714: error: 'DMGL_ANSI' undeclared
  util/symbol.c:2716: error: implicit declaration of 'bfd_demangle'

Move the libbfd demangling into libbfd.c, which already includes bfd.h,
and declare in symbol.c the libiberty interfaces the cplus_demangle()
variant needs.

Fixes: 4d9b5146f0 ("perf symbol: Move demangling code out of symbol-elf.c")
Signed-off-by: Ian Rogers <irogers@google.com>
Assisted-by: Antigravity:gemini-3.1-pro
Acked-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-22 14:44:33 +02:00
Ian Rogers
c4c4334350 perf libbfd: Fix the clang -Wthread-safety build failure
perf_bfd_lock() and perf_bfd_unlock() are the callbacks given to
bfd_thread_init(), so by design they acquire and release the lock on
libbfd's behalf and the lock state differs between entry and exit.
clang's thread safety analysis, which perf builds with as an error,
flags both:

  util/libbfd.c:56:1: error: mutex 'bfd_mutex' is still held at the end of function [-Werror,-Wthread-safety-analysis]
  util/libbfd.c:60:2: error: releasing mutex 'bfd_mutex' that was not held [-Werror,-Wthread-safety-analysis]

Mark both functions NO_THREAD_SAFETY_ANALYSIS so that libbfd.c compiles
with "make CC=clang BUILD_NONDISTRO=1".

Fixes: b72b8132d8 ("perf libbfd: Ensure libbfd is initialized prior to use")
Signed-off-by: Ian Rogers <irogers@google.com>
Assisted-by: Antigravity:gemini-3.1-pro
Acked-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-22 14:44:13 +02:00
Chen Pei
0b26b346a8 perf riscv: Add perf_regs_load and enable the dwarf unwind test
riscv has no arch level perf test: tests/builtin-test.c only picks up
arch_tests[] for x86, arm64 and powerpc64, tests/Build only builds the
generic dwarf unwind test driver for x86, arm, arm64 and powerpc, and
arch/riscv/tests/ did not exist. "Test dwarf unwind" was therefore never
registered on riscv, even though DWARF is the only reliable way to walk a
riscv user stack -- the arch callchain code walks frame pointers only --
and both unwinders already support riscv, elfutils libdw generically and
libunwind through util/libunwind-arch/libunwind-riscv.c.

Add perf_regs_load() and the arch unwind sample helper modelled on the
arm64 ones, and wire riscv into the two gates. The x1..x31 slots of enum
perf_event_riscv_regs match the hardware registers one to one, and
PERF_REG_RISCV_PC is filled with ra so that unwinding starts at the
caller.

Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Chen Pei <cp0613@linux.alibaba.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-22 14:42:08 +02:00
Chen Pei
1622c9ae39 perf test: Fix a leaked map reference in the arch dwarf unwind tests
maps__find() has returned a reference to the map it finds since
commit 42fd623b58 ("perf maps: Get map before returning in
maps__find"), which updated arch/x86/tests/dwarf-unwind.c but missed
the arm, arm64 and powerpc copies. Release the map after reading its
end, as x86 does. All other callers of maps__find() already release
what they get.

Fixes: 42fd623b58 ("perf maps: Get map before returning in maps__find")
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Chen Pei <cp0613@linux.alibaba.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-22 14:42:02 +02:00
Hui Su
cf3d239189 perf synthetic-events: Fix schedstat event lifetime handling
perf_event__synthesize_schedstat() has two event lifetime issues.

After a successful iteration, event is freed but retains its value. If
the next iteration starts with an unrecognized schedstat record type,
neither synthesizer assigns a new value. The stale pointer then passes
the NULL check, may be passed to process(), and is freed again.

In addition, when user_requested_cpus filters out a synthesized event,
the continue path skips free(event), leaking the event.

Make event local to each loop iteration so it always starts as NULL.
Also avoid the filter continue and unconditionally free each synthesized
event at the end of the iteration.

Fixes: c3030995f2 ("perf sched stats: Add record and rawdump support")
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Hui Su <sh_def@163.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-22 14:41:56 +02:00
Hui Su
d023b2110d perf evsel: Restrict incremental open error unwind
evsel__open_cpu(), evsel__tool_pmu_open() and
evsel__hwmon_pmu_open() support opening a subrange of a CPU map, bounded
by [start_cpu_map_idx, end_cpu_map_idx).

Their error paths, however, unwind using "while (--idx >= 0)" all the way
back to CPU index 0 regardless of start_cpu_map_idx. If lower CPU indices
were opened by an earlier invocation, a later incremental open failure
therefore closes those existing file descriptors and overwrites their
slots with -1.

Before this fix, running the new incremental open test demonstrates this
corruption:

  $ perf test -v "Tool PMU"
   12: Tool PMU:
   12.1: Tool PMU                                                      : Ok
   12.2: Tool PMU leader                                               : Ok
   12.3: Incremental open error unwind boundary:
     FAILED: CPU 0 FD overwritten: FD(evsel, 0, 0)=-1, expected 4
  FAILED!

Stop the unwind at start_cpu_map_idx so that only file descriptors
opened by the current invocation are rolled back.

After this fix:

  $ perf test -v "Tool PMU"
   12: Tool PMU:
   12.1: Tool PMU                                                      : Ok
   12.2: Tool PMU leader                                               : Ok
   12.3: Incremental open error unwind boundary                        : Ok

Fixes: 4804e01116 ("perf stat: Use affinity for opening events")
Fixes: 240505b2d0 ("perf tool_pmu: Factor tool events into their own PMU")
Fixes: 53cc0b351e ("perf hwmon_pmu: Add a tool PMU exposing events from hwmon in sysfs")
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Hui Su <sh_def@163.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-22 14:41:49 +02:00
Tengda Wu
1c12f13c07 perf arm-spe: Set default synthesized event period to 1
When using --itrace=M for data type profiling on arm64, the 'Percent'
values in perf annotate output are all zero:

Annotate type: 'struct mmu_gather_batch' in [kernel.kallsyms] (15 samples):
============================================================================
 Percent     offset       size  field
    0.00          0       0x10  struct mmu_gather_batch  {
    0.00          0        0x8      struct mmu_gather_batch*    next;
    0.00        0x8        0x4      unsigned int        nr;
    0.00        0xc        0x4      unsigned int        max;
    0.00       0x10          0      struct encoded_page*[]      encoded_pages;
                                };

However, adding the -n option (show-nr-samples) reveals non-zero sample counts:

Annotate type: 'struct mmu_gather_batch' in [kernel.kallsyms] (15 samples):
============================================================================
 Samples     offset       size  field
      15          0       0x10  struct mmu_gather_batch  {
      13          0        0x8      struct mmu_gather_batch*    next;
       2        0x8        0x4      unsigned int        nr;
       0        0xc        0x4      unsigned int        max;
       0       0x10          0      struct encoded_page*[]      encoded_pages;
                                };

The root cause is that when --itrace is used with non-i/y options
(e.g., --itrace=M), the period remains zero after parsing. During
subsequent propagation, the final percentage calculation results
in zero:

   arm_spe_prep_sample()
      sample->period = spe->synth_opts.period;

   __hists__add_entry()
      he.stat.period = sample->period;

   annotated_data_type__update_samples()
      h->period += period;
      h->addr[offset].period += period;

   print_annotated_data_value()
      double percent = h->period ? (100.0 * period / h->period) : 0;

Fix this by defaulting the period to 1 in the ARM SPE auxtrace info
processing path if it is not explicitly specified. This ensures that
downstream tool components can correctly accumulate periods and compute
event percentages for all synthesized SPE events.

With this fix applied, the result is as follows:

Annotate type: 'struct mmu_gather_batch' in [kernel.kallsyms] (15 samples):
============================================================================
 Percent     offset       size  field
  100.00          0       0x10  struct mmu_gather_batch  {
   86.67          0        0x8      struct mmu_gather_batch*    next;
   13.33        0x8        0x4      unsigned int        nr;
    0.00        0xc        0x4      unsigned int        max;
    0.00       0x10          0      struct encoded_page*[]      encoded_pages;
                                };

Reviewed-by: Ian Rogers <irogers@google.com>
Acked-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-09-21 08:42:22 +02:00
Tengda Wu
035efae7df perf annotate: Default to --itrace=i1i for data type profiling
ARM SPE-based sampling can synthesize multiple events on a single
instruction, as shown below. This would affect data type profiling
statistics:

  Available samples
  0 arm_spe_0/ts_enable=1,pa_enable=1,load_filter=1,store_filter=1,min_latency=30/
  0 dummy:u
  84K l1d-miss
  95K l1d-access
  77K llc-miss
  58K llc-access
  9K tlb-miss
  108K tlb-access
  0 branch
  13K remote-access
  108K memory
  108K instructions

While 'perf report' provides an interactive menu for users to select a
specific event to prevent duplicate counting, 'perf annotate' lacks such
a mechanism. Consequently, it counts all instructions across these
overlapping events, which inflates the profile and distorts the data
type statistics.

Although using the '--itrace' option can work around this issue (e.g.:
perf annotate --data-type --stdio --itrace=i1i), it is inconvenient for
users to specify this explicitly every time.

To address this, introduce itrace_synth_opts.default_single_event_per_ip.
Set this field to true when data type profiling is enabled and the user
has not explicitly specified an itrace option. In itrace_synth_opts__set_default(),
use this flag to default to synthesizing at most one event per IP (equivalent
to --itrace=i1i) to prevent duplicate sample counts.

Reviewed-by: Ian Rogers <irogers@google.com>
Reviewed-by: Adrian Hunter <adrian.hunter@intel.com>
Acked-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-09-21 08:41:55 +02:00
Tengda Wu
20aca19350 perf annotate-arm64: Implement extract_op_location() callback
Implement the extract_op_location() callback for the arm64 architecture
to handle its specific assembly syntax and addressing modes.

The extractor handles:
1. Immediate operands (e.g., '#0x10' or '#0xc600, lsl #16').
2. Memory references with diverse addressing modes:
   - Signed offset: [base{, #imm|reg}]
   - Pre-index: [base, #imm]!
   - Post-index: [base], #imm|reg
3. Multi-register operands and primary/secondary register extraction.
4. Register extension specifiers (e.g., uxtw, sxtx) and shift amounts
   for shifted/extended operands.

With this callback in place, 'perf annotate' can now resolve memory
locations and register types on arm64, marking the initial enablement
of data type profiling for this architecture.

Commiter notes:

Added a cast to overcome a compiler error about setting a non cost char
* var to strchr(), the var is not modified.

  util/annotate-arch/annotate-arm64.c: In function ‘extract_op_location_arm64’:
  util/annotate-arch/annotate-arm64.c:385:19: error: assignment discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers]
    385 |                 p = strchr(s, ']');
        |                   ^
  cc1: all warnings being treated as errors

Reviewed-by: Ian Rogers <irogers@google.com>
Acked-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-09-21 08:38:58 +02:00
Tengda Wu
0ba32f84fc perf annotate: Adapt arch__dwarf_regnum() for arm64
Currently, arch__dwarf_regnum() assumes that all architectures use a
register prefix character (e.g., '%' for x86) defined by
arch->objdump.register_char, and uses it to match register names in
objdump output. However, this assumption does not hold for arm64,
where assembly syntax uses bare register names like 'x0', 'w1'
without any prefix.

As a result, arm64 builds may fail to correctly recognize register
names from objdump disassembly, leading to incomplete or incorrect
annotation output.

To address this:

- Make the register prefix check optional, allowing architectures
  without a prefix character to be parsed correctly.

- Extend the delimiter set in strpbrk() to include the closing square
  bracket ']'. In arm64 assembly, memory operands often use bracketed
  syntax such as '[x1, #16]' or '[x2]'. Adding ']' ensures clean
  extraction of register names like 'x2' without trailing characters.

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-09-21 08:30:55 +02:00
Tengda Wu
4c42173d98 perf dwarf-regs: Adapt get_dwarf_regnum() for arm64
The current arm64 DWARF register lookup relies on 'aarch64_regstr_tbl',
a static string table. While this works for kprobe-tracer where register
names start with '%', it is insufficient for parsing register numbers
directly from raw instructions (e.g., extracting '6' from 'x6' or 'w6')
during annotation.

Since get_dwarf_regnum() is currently used only by 'perf annotate' and
does not affect kprobe-tracer, replace the limited table-based lookup
with a programmatic implementation in __get_dwarf_regnum_arm64(). This
allows resolving arm64 register names (x0-x30, w0-w30, sp, etc.) directly
into their corresponding DWARF register numbers.

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-09-21 08:30:50 +02:00
Tengda Wu
487e428bb3 perf annotate: Introduce extract_op_location callback for arch-specific parsing
Assembly syntax for operands varies significantly across different
architectures, which prevents the operand location (op_loc) parsing
logic in annotate_get_insn_location() from being directly reused.

To simplify the core logic and improve maintainability, move the
operand parsing inside the for_each_insn_op_loc loop into arch-specific
extract_op_location callbacks. This refactoring is intended to be a
cleanup with no functional changes.

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-09-21 08:30:45 +02:00
Tengda Wu
988b4e4698 perf annotate: Normalize arch__dwarf_regnum() error return values
arch__dwarf_regnum() returns inconsistent error values: early path
returns -1 while the main lookup returns -ENOENT/-EINVAL from
get_dwarf_regnum(). Callers only check for -1, so genuine failures
can slip through.

Normalize all failures to -1 to match the callers' expectation.

Suggested-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-09-21 08:30:38 +02:00