Commit Graph

1482244 Commits

Author SHA1 Message Date
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
Tengda Wu
d9700ad94a perf annotate-arm64: Handle load and store instructions
Add ldst_ops to handle load and store instructions in order to parse
the data types and offsets associated with PMU events for memory access
instructions. There are many variants of load and store instructions in
arm64, making it difficult to match all of these instruction names
completely. Therefore, only the instruction prefixes are matched. The
prefix 'ld|st' covers most of the memory access instructions, 'cas|swp'
matches atomic instructions, and 'prf' matches memory prefetch
instructions.

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:26 +02:00
Tengda Wu
699c52c69f perf annotate-arm64: Generalize arm64_mov__parse to support more instructions
As the default parser for arm64 instructions, arm64_mov__parse()
currently only supports parsing instructions with the 'addr <symbol>'
suffix. Other instructions are not supported, causing a lack of
source and target information for most regular instructions.

Generalize arm64_mov__parse to extend its parsing capabilities:
1. Parse 'ops->target.raw' and 'ops->source.raw' by default.
2. Utilize arm64__check_multi_regs() to identify if source and
   target contain multiple registers.
3. Maintain backward compatibility for instructions containing the
   'addr <symbol>' suffix.

Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Tengda Wu <wutengda@huaweicloud.com>
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-21 08:30:21 +02:00
Tengda Wu
705390bdcf perf llvm: Fix arm64 adrp instruction disassembly mismatch with objdump
The operands of 'adrp' instructions parsed by libllvm are currently
represented as raw immediates rather than the "address <symbol+offset>"
format used by objdump. This inconsistency causes arm64_mov__parse()
to fail when parsing these instructions during post-processing.

Example of the mismatch:
  Current: adrp  x18, 8014
  Objdump: adrp  x18, ffff800081f5f000 <this_cpu_vector>

Fix this by manually extracting the target address from the raw adrp
instruction via symbol_lookup_callback(). The address is then converted
to a specific symbol during symbol__disassemble_llvm() and formatted
to match objdump's output, ensuring compatibility with existing
parsers.

Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Tengda Wu <wutengda@huaweicloud.com>
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-21 08:30:17 +02:00
Tengda Wu
268d5c3979 perf capstone: Symbolize address operands to match objdump on arm64
Capstone currently outputs address-bearing instructions with a raw hex
value prefixed by '#', without symbolic resolution. This differs from
objdump output and leads to parse failures in jump__parse() and
arm64_mov__parse() on arm64.

Example of the mismatch:
  Current: b #0xffff8000800114c8
  Objdump: b ffff8000800114c8 <el0t_64_sync+0x108>

  Current: adrp x18, #0xffff800081f5f000
  Objdump: adrp x18, ffff800081f5f000 <this_cpu_vector>

Fix this by extending symbol__disassemble_capstone() to:
- Enable CS_OPT_DETAIL for arm64 to access instruction group info.
- Detect instructions with address operands requiring symbolization
  (jump/call/branch/adr/adrp) via opcode or Capstone group ID.
- Resolve target addresses to symbols via find_symbol_from_addr().
- Format output to match objdump's style (strip '#' prefix, add
  symbol and offset).

Signed-off-by: Tengda Wu <wutengda@huaweicloud.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-21 08:29:47 +02:00
Namhyung Kim
aaca646915 perf annotate-data: Adjust type offset for flex-array
The flex array members are located beyond the original type size.  Also
it needs to adjust the offset in an array to find a corresponding
element using module operation.  Note that we focus on access to type and
field, so array index is not important.

Make sure to find a field name for flex arrays.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-21 08:24:48 +02:00
Namhyung Kim
b4ad992f8f perf annotate-data: Allow out-of-size access for flex-array types
Structs that have a flex array will have accesses beyond its original
size as the array was declared as 0 sized.  For now, it just allow any
offset bigger than the size.  It could be refined later.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-21 08:24:47 +02:00
Namhyung Kim
b827d23469 perf annotate-data: A small cleanup in __add_member_cb()
Check return value of strbuf_init() and die_get_typename() to make sure
if typename of a member gets never NULL.

Also remove the check for typedef by just using die_get_real_type().
It can get rid of member_type variable as well.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-21 08:24:47 +02:00
Namhyung Kim
d673d25d3e perf dwarf-aux: Add die_has_flex_array() helper
The die_has_flex_array() returns true when the given type is a compound
type and contains an array at the end.  To prevent an infinite recursion
add a depth field to the internal function.

Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-21 08:24:47 +02:00
Ian Rogers
63394d0664 perf test: Isolate test suite from user .perfconfig natively
Running 'perf test' should not inherit the user's ~/.perfconfig
environment as customizing core properties (like core.hybrid-merge)
will trivially break stdout matching checks across the shell suite.

Explicitly set PERF_CONFIG to /dev/null inside cmd_test to globally
sandbox the environment for the entire test workflow. Test specific
config, like annotate.objdump, is read before the sandboxing so that
'perf test' still honors it.

Signed-off-by: Ian Rogers <irogers@google.com>
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-18 17:38:50 -03:00
Ian Rogers
06aa9ab061 perf test: Expand tests for --hybrid-merge
Add a "Hybrid event merging" test that checks evlist__can_merge_hybrid()
and evlist__merge_hybrid() directly, covering the events a wildcard
expanded to over two core PMUs, the same over three, and events that
must not be merged.

Add a report_hybrid_merge.sh shell test that records and then reports
with --hybrid-merge, and extend top.sh to cover perf top with it.

Signed-off-by: Ian Rogers <irogers@google.com>
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-18 17:38:26 -03:00
Ian Rogers
5c8edd351d perf config: Add core.hybrid-merge to configure event merging
Provide a core.hybrid-merge configuration option in .perfconfig to allow
enabling hybrid event aggregation by default, avoiding the need to pass
--hybrid-merge explicitly on every invocation.

The config value is a default rather than an explicit request, so with
--hierarchy it is ignored with a warning, while giving both --hierarchy
and --hybrid-merge on the command line remains an error.  For the same
reason it is silently ignored when there are no events to merge, as
would be the case on any machine with a single core PMU, whereas an
explicit --hybrid-merge still warns. Record whether the option came from
the command line in symbol_conf so both can tell the two apart.

'perf stat' has its own merging options for counting, the sampling
core.hybrid-merge deliberately doesn't alter it and its --hybrid-merge
must still be given explicitly.

Signed-off-by: Ian Rogers <irogers@google.com>
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-18 17:37:45 -03:00
Ian Rogers
59eca52494 perf tools: Add TUI hints for --hybrid-merge
Add dynamic TUI hints prompting users to restart with --hybrid-merge
when heterogeneous core PMU events are populated in the sample view.

Signed-off-by: Ian Rogers <irogers@google.com>
Assisted-by: Antigravity:gemini-3.1-pro
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-18 17:37:04 -03:00
Ian Rogers
a25262fb16 perf evlist: Toggle merged_hybrid_group properly in enable/disable
Merging makes the merged event the leader of the events of the other
core PMUs so their histograms can be linked, but the result isn't a real
event group. Each event keeps its own file descriptor and has to be
enabled and disabled in its own right.

__evlist__enable(), __evlist__disable() and evlist__is_enabled() skip
anything that isn't a group leader, and the first two then walk the
group members of the events they do act on. For a merged set that is
backwards: the members are skipped by the leader test, so their file
descriptors are never touched, and the walk over the leader's members
only updates the bookkeeping in evsel->disabled.

Treat an evsel with merged_hybrid_group set as a leader so that it is
enabled and disabled in its own right via its own file descriptors.

'perf top' enables and disables by event name. A merged member carries
the name of its own PMU rather than the name that was asked for, so also
match it against its leader's name, otherwise naming the event toggles
only part of the merged set.

Signed-off-by: Ian Rogers <irogers@google.com>
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-18 17:36:30 -03:00
Ian Rogers
aa2bad59fd perf Documentation: Add tip for hybrid event merging
Add informative text outlining the IPC imbalances associated with
merging cross-hybrid core events like cycles.

Signed-off-by: Ian Rogers <irogers@google.com>
Assisted-by: Antigravity:gemini-3.1-pro
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-18 17:35:55 -03:00
Ian Rogers
6fa291f805 perf tools: Expose opt-in --hybrid-merge
Add --hybrid-merge to perf report and perf top. It merges the events a
wildcard expanded to across the core PMUs, and their histograms, so
that a symbol which ran on more than one kind of core is reported once
with the total rather than once per PMU.

evlist__merge_hybrid() links the events and evlist__merge_hists_hybrid()
links the histograms. There is nothing to merge on a machine with a
single core PMU, or when the events didn't come from a wildcard, so
warn in that case rather than quietly producing an unmerged report.

Merging collapses the per-PMU entries into one set, which doesn't
combine with the per-level breakdown of --hierarchy, so asking for both
is an error.

Signed-off-by: Ian Rogers <irogers@google.com>
Assisted-by: Antigravity:gemini-3.1-pro
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-18 17:29:34 -03:00
Ian Rogers
bcb89e6320 perf ui hist: Add support for aggregated total_period and merging entries
Add the histogram side of hybrid event merging.

When events are merged the entries of the other events are linked to
the leader's entries as pairs, and a row is then displayed as the sum
over an entry and its pairs. Teach the hpp code to work on that sum:

 - The formatting and sorting routines add up the value of an entry and
   of each of its pairs, so a row shows, and is sorted by, the total
   across the core PMUs rather than the leader's value alone.
 - Percentages are taken against the summed total_period of the merged
   hists. Computing each event's share against its own PMU's total
   would leave the column not adding up to 100%.
   hist_entry__get_percent_limit_merged() does the same for
   --percent-limit, which would otherwise compare against the wrong
   total and filter out the wrong entries.
 - A header and column width are reserved for the "Total" the merged
   value is shown under.

evlist__merge_hists_hybrid() links the hists together and resorts the
result so that it is ordered by the merged total.

hists__link() is run once for every event merged into the leader, so an
entry can be offered as a pair more than once. hist_entry__add_pair()
used list_add_tail() unconditionally, which corrupts the list when the
entry is already on one. Return early if the entry is already paired
with this one, and use list_move_tail() so that an entry linked
elsewhere is moved rather than added a second time.

Merging is never combined with --hierarchy, which the merge_entries
tests rely on.

Signed-off-by: Ian Rogers <irogers@google.com>
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-18 17:28:52 -03:00
Ian Rogers
ce7948448d perf evlist: Implement evlist__can_merge_hybrid using first_wildcard_match
Add logic to dynamically identify mergeable events spawned from the
same wildcard alias via first_wildcard_match. first_wildcard_match is
populated when events are parsed, in `perf report` the events come
from a file and so the first_wildcard_match is computed by matching
event names.

evlist__can_merge_hybrid only tests whether merging is possible and
doesn't modify the evlist, so that it may be used as a predicate, for
example, to decide whether to display a hint. The linking of all the
matching events is done by evlist__merge_hybrid.

is_pmu_core_len identifies core PMUs using the hybrid topology of the
perf.data file. Should the file lack the topology, the PMUs of this
machine are scanned but only when the file was recorded on the same
architecture, as PMU names like "cpu_core" are architecture specific.

Signed-off-by: Ian Rogers <irogers@google.com>
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-18 17:26:41 -03:00
Ian Rogers
3d8fb5a4a1 perf libbfd: Report success when an address is found
libbfd__addr2line() only reports success when the caller asked for a file
name. addr2inlines() passes a NULL file as it just wants the inline_node
populating, so libbfd__addr2line() returns 0 for it unless
bfd_find_inliner_info() happened to find an inline frame.

addr2line() in srcline.c treats 0 as a failure and tries the next
addr2line implementation, which appends its own frames to the
inline_node libbfd already appended to.

Every frame that isn't inlined is then reported twice, which happens by
default when perf is built with libbfd but without libdw as the fallback
order is then libbfd followed by the addr2line command:

  $ perf record --call-graph dwarf -- perf test -w inlineloop 1
  $ perf script --fields +srcline
  ...
	    56051a994f8e parent+0x2e (perf)
    inlineloop.c:32
	    56051a99503a inlineloop+0x8a (perf)
    inlineloop.c:47
	    56051a99503a inlineloop+0x8a (perf)
    inlineloop.c:47
	    56051a95841a cmd_test+0xb7a (perf)
    ??:0
	    56051a95841a cmd_test+0xb7a (perf)
    ??:0
  ...

Report success whenever the address is found, like libdw__addr2line()
does, and clear the frames appended so far when appending fails so that a
following implementation starts from an empty node.

Fixes: 257046a367 ("perf srcline: Fallback between addr2line implementations")
Signed-off-by: Ian Rogers <irogers@google.com>
Assisted-by: Antigravity:gemini-3.1-pro
Cc: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-18 17:24:49 -03:00
Ian Rogers
f651c02755 perf dso: Separate libbfd and cmd addr2line caches to fix confusion
When a dso executes addr2line via libbfd it instantiates an a2l_data
pointer. If the DSO later executes via the command-line fallback due
to an inlined bug, the a2l pointer is unconditionally populated with a
child_process process wrapper.

If libbfd is queried again, the offline reader attempts to cast struct
a2l_data into child_process, coercing random arbitrary instruction
addresses and causing silent aborts. This cleanly splits the caches.

Fixes: 257046a367 ("perf srcline: Fallback between addr2line implementations")
Signed-off-by: Ian Rogers <irogers@google.com>
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-18 17:23:59 -03:00
Ian Rogers
bf96e296d5 perf libdw: Fix Dwfl discovery with split files
dso__libdw_dwfl() opens the Dwfl with dso__long_name(), the file the
samples came from. When the debug information lives in a separate file,
symbol loading finds it and records it as the dso's symsrc filename, but
the Dwfl still refers to the original file, so libdw has no DWARF to
resolve addresses against.

Open the Dwfl with the symsrc filename when one is known and fall back
to the long name when it isn't.

The symsrc file is found while symbols are loaded, which can happen
after the Dwfl has been created and cached, so drop the cached Dwfl and
the addr2line cache built from it when the symsrc filename is set.  That
teardown can run while another thread is using the cache, so take the
dso lock across both the teardown and the Dwfl accessors, and re-read
dso__symsrc_filename() under the dso lock in libbfd__addr2line() and
cmd__addr2line() to prevent a TOCTOU race with cache invalidation.

Fixes: b7a2b011e9 ("perf powerpc: Unify the skip-callchain-idx libdw with that for addr2line")
Signed-off-by: Ian Rogers <irogers@google.com>
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-18 17:23:16 -03:00
Zide Chen
0824af00a8 perf topdown: Don't require config1==0 for a slots event
arch_is_topdown_slots() requires config1 == 0, so it misidentified
"cpu/slots,metrics_clear=1/" as not being the slots event, and an
additional slots event gets inserted, which fails event scheduling
since the group now needs two fixed counter 3.

  $ perf stat -e "{cpu/slots,metrics_clear=1/,cpu/topdown-retiring/}" -- sleep 1
  WARNING: events were regrouped to match PMUs
       <not counted>      slots
     <not supported>      cpu/slots,metrics_clear=1/
       <not counted>      cpu/topdown-retiring/

Drop the config1 == 0 check from arch_is_topdown_slots(). This is
safe: config1 has no bearing on the event's identifying config value
(TOPDOWN_SLOTS, 0x0400).

The attr.type == PERF_TYPE_RAW check is what actually matters: only the
core PMU is registered with PERF_TYPE_RAW, and on x86, 0x400 is
guaranteed to be slots event on core CPU.

arch_is_topdown_metrics() keeps its own config1 == 0 check, since
genuine metrics events have no "metrics_clear" and config1 remains 0.

Add a test verifying that an explicit "slots,metrics_clear=1" event in
a group does not trigger an extra slots event injection.

Fixes: 5b546de9cc ("perf topdown: Use attribute to see an event is a topdown metic or slots")
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Zide Chen <zide.chen@intel.com>
Cc: Namhyung Kim <namhyung@kernel.org>
[ Add missing stdio.h and string.h as noticed by Sashiko ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-18 17:18:25 -03:00
Chun-Tse Shao
86a2781167 perf evsel: Find process with busy PMUs for EBUSY
It parses fdinfo with PMU type, comparing with the event which failed to
open, and report the processes causing EBUSY error.

Testing cycles and intel_pt//

  $ ./perf stat -e cycles &
  [1] 55569
  $ ./perf stat -e intel_pt// &
  [2] 55683
  $ ./perf stat -e intel_pt//
  Error:
  The PMU intel_pt counters are busy and in use by another process.
  Possible processes:
  55683 ./perf stat -e intel_pt//

Only perf with intel_pt was reported.

Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Chun-Tse Shao <ctshao@google.com>
Assisted-by: Gemini:gemini-3.1-pro-preview
[ Added a few missing includes as per Sashiko's review ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-17 12:27:34 -03:00
liujing
63c2df4cfb perf bench messaging: Fix the formatting issue when printing.
The unsigned int type should use the %u format specifier when
printing with printf or related functions.

Signed-off-by: liujing <liujing@cmss.chinamobile.com>
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-17 12:27:34 -03:00
Ian Rogers
3cbb16ccd7 perf record: Fix unhandled POLLHUP on non_perf_event descriptors
When processing POLLHUP on a non_perf_event control descriptor,
evlist__finalize_ctlfd() is invoked to finalize the setup, correctly
setting the core evlist's poll array file descriptor to -1. However,
this finalized teardown state is never propagated back to the
individual thread's local replica of the pollfd array.

Consequently, on the next iteration of the main recording loop,
record__update_evlist_pollfd_from_thread() performs a strict
equivalence check between the core evlist's array and the thread's
localized poll array, detecting that the fd values no longer match.
This causes an immediate -EINVAL abort and a premature teardown.

Fix the underlying logic within
record__update_evlist_pollfd_from_thread() to sustainably propagate
the finalized teardown statuses (-1) originating from the core evlist
back to the thread's localized poll structure. This correctly
maintains synchronization and entirely prevents the unhandled
index mismatch crashes.

Additionally, add a unit test that explicitly validates that
fdarray__filter() preserves its invariants regarding
fdarray_flag__nonfilterable items to guard against regressions.

Fixes: fb4751e79c ("perf record: Fix teardown hang on system-wide multi-threaded sessions")
Signed-off-by: Ian Rogers <irogers@google.com>
Assisted-by: Gemini:gemini-3.1-pro
Cc: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-17 12:27:34 -03:00
Arnaldo Carvalho de Melo
29f320d221 perf test: Skip data_type_profiling when the PMU cannot record memory events
The test's only guard matches "failed: no PMU supports the memory
events", but a PMU that has memory events and refuses them per-thread,
such as AMD IBS on kernels without the swfilt filter, falls through:
the script runs under 'set -e' and the bare 'perf mem record' aborts it
through the EXIT trap, reporting a signal that never happened and
turning "this PMU cannot record these events" into a test failure.

Skip when a trivial per-thread 'perf mem record' fails, and put the
record and annotate calls in the condition of an 'if', where 'set -e'
leaves them alone, so the remaining cases report their own failures
instead of the first one aborting the run.

Fixes: f60a5c2296 ("perf tests: Test annotate with data type profiling and rust")
Acked-by: Namhyung Kim <namhyung@kernel.org>
Assisted-by: LLM
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-17 12:22:07 -03:00
Namhyung Kim
91b0782fc9 perf annotate-data: Convert type histogram to hashmap
The type histogram maintains sample counts and periods per offset.  Use
a hashmap instead of an array to reduce the memory overhead.

No functional changes intended.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Reviewed-by: Tengda Wu <wutengda@huaweicloud.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-14 15:58:37 -03:00
Dapeng Mi
193e66b9e2 perf tests: Add SIMD registers sampling test
Validate that SIMD registers (XMM/YMM/ZMM/OPMASK on x86) can be sampled
correctly with hardware support.

Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-14 15:35:30 -03:00
Dapeng Mi
7db989086a perf tests: Add x86 eGPRs/SSP registers sampling test
Validate that eGPRs (extended general purpose registers) and SSP
(shadow stack pointer) registers can be sampled correctly on x86
platforms.

Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-14 15:35:18 -03:00
Dapeng Mi
1f2177e9e0 perf dwarf-regs: Add SIMD/eGPRs support for x86 DWARF registers
Enhance the x86-specific DWARF register handling by adding support for
SIMD and eGPRs registers.

This update is based on the "DWARF Register Number Mapping" table from
the "System V Application Binary Interface AMD64 Architecture Processor
Supplement" (version 1.0).

Modifications include:
- Updating the x86_64_regidx_table[] array to incorporate SIMD and eGPRs
  registers.
- Enhancing the __get_dwarf_regnum_for_perf_regnum_x86_64() function to
  retrieve the DWARF register index for eGPRs.

Since currently libdw doesn't support SIMD and APX eGPRs registers yet,
still keep the original return value for get_libdw_frame_nregs() helper.

Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-14 15:35:05 -03:00
Dapeng Mi
01ee8c1435 perf regs: Enable dumping of SIMD registers
Support dumping of SIMD registers with the new PERF_SAMPLE_REGS_ABI_SIMD
ABI.

Currently, the XMM, YMM, ZMM, OPMASK, eGPRs, and SSP registers on x86
platforms are supported with the PERF_SAMPLE_REGS_ABI_SIMD ABI.

An example of the raw format output is displayed below.

Example:

 $perf record -e cycles:p -Iax,bx,r8,r16,r31,ssp,xmm,ymm,zmm,opmask ./test
 $perf report -D
 ... ...
 3342715685845 0x3afe8 [0xbc8]: PERF_RECORD_SAMPLE(IP, 0x1):
 27776/27776: 0xffffffff91d7c18f period: 10000 addr: 0
 ... intr regs: mask 0x18001010003 ABI 64-bit SIMD
 .... AX    0xffffed102de1a606
 .... BX    0xffffed102de1a606
 .... R8    0x0000000000000001
 .... R16   0x0000000000000000
 .... R31   0x0000000000000000
 .... SSP   0x0000000000000000
 ... SIMD ABI nr_vectors 32 vector_qwords 8 nr_pred 8 pred_qwords 1
 .... ZMM[0][0] 0x616c2f656d6f682f
 .... ZMM[0][1] 0x696c2f7265737562
 .... ZMM[0][2] 0x0000000000000000
 .... ZMM[0][3] 0x0000000000000000
 .... ZMM[0][4] 0x0000000000000000
 .... ZMM[0][5] 0x0000000000000000
 .... ZMM[0][6] 0x0000000000000000
 .... ZMM[0][7] 0x0000000000000000
 .... ZMM[1][0] 0x702f636578656269
 .... ZMM[1][1] 0x65726f632d667265
 .... ZMM[1][2] 0x0000000000000000
 .... ZMM[1][3] 0x0000000000000000
 .... ZMM[1][4] 0x0000000000000000
 .... ZMM[1][5] 0x0000000000000000
 .... ZMM[1][6] 0x0000000000000000
 .... ZMM[1][7] 0x0000000000000000
 ... ...
 .... ZMM[31][0] 0x0000000000000000
 .... ZMM[31][1] 0x0000000000000000
 .... ZMM[31][2] 0x0000000000000000
 .... ZMM[31][3] 0x0000000000000000
 .... ZMM[31][4] 0x0000000000000000
 .... ZMM[31][5] 0x0000000000000000
 .... ZMM[31][6] 0x0000000000000000
 .... ZMM[31][7] 0x0000000000000000
 .... OPMASK[0] 0x0000000000100221
 .... OPMASK[1] 0x0000000000000020
 .... OPMASK[2] 0x000000007fffffff
 .... OPMASK[3] 0x0000000000000000
 .... OPMASK[4] 0x0000000000000000
 .... OPMASK[5] 0x0000000000000000
 .... OPMASK[6] 0x0000000000000000
 .... OPMASK[7] 0x0000000000000000
 ... ...

Co-developed-by: Kan Liang <kan.liang@linux.intel.com>
Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-14 15:34:43 -03:00
Dapeng Mi
6e9c063d8f perf regs: Support x86 SIMD registers sampling
Add support for the newly introduced SIMD register sampling format by
adding the following 5 functions:

uint64_t perf_intr_simd_reg_class_mask(uint16_t e_machine, bool pred);
uint64_t perf_user_simd_reg_class_mask(uint16_t e_machine, bool pred);
uint64_t perf_intr_simd_reg_class_bitmap_qwords(uint16_t e_machine, int reg_c,
						uint16_t *qwords, bool pred);
uint64_t perf_user_simd_reg_class_bitmap_qwords(uint16_t e_machine, int reg_c,
						uint16_t *qwords, bool pred);
const char *perf_simd_reg_class_name(uint16_t e_machine, int id, bool pred);

The perf_{intr|user}_simd_reg_class_mask() functions retrieve the bitmap
of kernel supported SIMD/PRED register classes on current platform for
intr-regs and user-regs sampling, such as OPMASK/XMM/YMM/ZMM on
x86 platforms.

The perf_{intr|user}_simd_reg_class_bitmap_qwords() functions retrieve
the bitmap and qwords length of a certain class of SIMD/PRED register
on current platform for intr-regs and user-regs sampling. For example,
for the XMM registers on x86 platforms, the returned bitmap is 0xffff
(XMM0 ~ XMM15) and the qwords length is 2 (128 bits for each XMM
register).

The perf_simd_reg_class_name() function gets the register class name for
a certain register class index.

Additionally, the function __parse_regs() is enhanced to support parsing
these newly introduced SIMD/PRED registers. Currently, each class of
register can only be sampled collectively; sampling a specific SIMD
register is not supported. For example, all XMM registers are sampled
together rather than sampling only XMM0.

When multiple overlapping register types, such as XMM and YMM, are
sampled simultaneously, only the superset (YMM registers) is sampled.

With this patch, all supported sampling registers on x86 platforms are
displayed as follows.

 $perf record --intr-regs=?
 available registers: AX BX CX DX SI DI BP SP IP FLAGS CS SS R8 R9 R10
 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28
 R29 R30 R31 SSP XMM0-15 YMM0-15 ZMM0-31 OPMASK0-7

 $perf record --user-regs=?
 available registers: AX BX CX DX SI DI BP SP IP FLAGS CS SS R8 R9 R10
 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28
 R29 R30 R31 SSP XMM0-15 YMM0-15 ZMM0-31 OPMASK0-7

Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-14 15:34:05 -03:00
Dapeng Mi
adc6aa9a28 perf regs: Support x86 eGPRs/SSP sampling
Add support for sampling x86 extended GP registers (R16-R31) and the
shadow stack pointer (SSP) register.

The original XMM registers space in sample_regs_user/sample_regs_intr is
reclaimed to represent the eGPRs and SSP when SIMD registers sampling is
supported with the new SIMD sampling fields in the perf_event_attr
structure. This necessitates a way to distinguish which register layout
is used for the sample_regs_user/sample_regs_intr bitmap.

To address this, a new "abi" argument is added to the helpers
perf_intr_reg_mask(), perf_user_reg_mask(), and perf_reg_name(). When
"abi & PERF_SAMPLE_REGS_ABI_SIMD" is true, it indicates the eGPRs and SSP
layout is represented; otherwise, the legacy XMM registers are
represented.

Please note that PERF_SAMPLE_REGS_ABI_SIMD is set by default on platforms
that support SIMD register sampling, even when no eGPR or SSP register is
requested (for example, -Iax). As a result, sample_regs_intr and
sample_regs_usr always use the new GPR layout on platforms with SIMD
register sampling support.

The patch only supports eGPRs and SSP sampling, the complete SIMD
registers sampling would be supported in the next patch.

Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-14 15:33:33 -03:00
Dapeng Mi
eb89aef367 perf headers: Sync perf_event.h/perf_regs.h with the kernel headers
Sync the UAPI header changes of supporting SIMD/eGPRs/SSP sampling into
corresponding tools UAPI headers.

Additionally, support the new introduced perf_event_attr fields in the
perf_event_attr__fprintf and perf_event__attr_swap() helpers, and add
sanity check for the new introduced __reserved_4 field in
perf_attr_check().

Co-developed-by: Kan Liang <kan.liang@linux.intel.com>
Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-14 15:32:52 -03:00
Dapeng Mi
7846bf499d tools headers: Sync x86 headers with kernel sources
Sync newly introduced ARCH_PEBS_VECR_xxx macros from kernel.

Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-14 15:32:42 -03:00
Dapeng Mi
2b7e273af0 perf util: Add missed fields in _attr__fprintf() and __attr_swap()
Some new introduced perf_event_attr fields, like config3 and config4,
are forgotten to add into perf_event_attr__fprintf() and
perf_event__attr_swap() helpers. Add these missed fields into these 2
helpers.

The aux_action is an exception. aux_action aliases bitfields
(e.g. aux_start_paused) in a union. Bitfields and plain u32 fields
follow different endian rules, so both views cannot be swapped
correctly at the same time. Leave aux_action unswapped until the ABI
is represented in a byte-order-safe form.

Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-14 15:32:26 -03:00
Dapeng Mi
3792e2922d perf dwarf-regs: Fix DWARF register index bounds check
Tighten bounds validation in __get_dwarf_regnum_for_perf_regnum_xxx()
helpers by changing perf_regnum > ARRAY_SIZE() to
perf_regnum >= ARRAY_SIZE().

This fixes an off-by-one condition where perf_regnum == ARRAY_SIZE()
could pass validation and cause out-of-bounds access for
dwarf_xxx_regnums[].

Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-14 15:31:50 -03:00
Ian Rogers
5a8e536e5f perf jevents: Add mesh bandwidth saturation for CWF, EMR, GRR, SNR, SPR, SRF
Extend the mesh bandwidth saturation's list of events to include events
from clearwaterforest, emeraldrapids, grandridge, graniterapids,
sapphirerapids and sierraforest. This makes the lpm_mem_sat metric
available for those CPU models.

Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-13 21:43:20 -03:00
Qerogram
1f06510349 perf list: Avoid repeated strlen() when escaping JSON strings
The %S conversion in fix_escape_fprintf() calls strlen(s) in the loop
condition while escaping each character. GCC 14.2.0 retains this call
inside the loop in a normal DEBUG=0 (-O3) perf build, repeatedly
scanning the whole string.

Test the current character for NUL instead. This processes the same
bytes without rescanning the string. Escaping and buffer growth are
unchanged.

Full-command wall-clock measurements on an Apple M5 Pro host running an
aarch64 Linux container with GCC 14.2.0 and glibc 2.41 gave these
medians:

  perf list --json metrics       Before (ms)  After (ms)
  Default catalog                    0.5969      0.5855
  PERF_CPUID=0x00000000410fd830        0.7818      0.7033

Each workload used 50 randomized before/after pairs. Each sample
averages the time per invocation across five fresh processes, with
stdout sent to /dev/null and no single-CPU pinning. PERF_CPUID selects
the shipped V3 catalog on the same host; these are not measurements on
V3 hardware. The measurements include process startup and do not
establish a gain on other machines or perf commands.

These observations come from one short run. Relinking also changes code
layout: .text grows from 2,013,172 to 2,017,236 bytes in this build. The
timings do not isolate scan removal from the changed layout.

The existing list shell test passes for both binaries. Source-extracted
functions linked to perf's strbuf implementation pass 906 equivalence
cases with ASan and UBSan. Full-command outputs are byte-identical.

Codex assisted with identifying the redundant scan, preparing the change,
and running the comparisons.

Assisted-by: LLM
Signed-off-by: Qerogram <qerogram@naver.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2026-09-13 18:44:37 -03:00