[PATCH v2 0/4] perf script: Bounded and lazy symbol loading

Alireza Haghdoost via B4 Relay posted 4 patches 4 days, 18 hours ago
tools/perf/Documentation/perf-script.txt           |  28 +
tools/perf/arch/powerpc/util/sym-handling.c        |   5 +-
tools/perf/builtin-script.c                        |  44 ++
tools/perf/tests/Build                             |   1 +
tools/perf/tests/builtin-test.c                    |   1 +
tools/perf/tests/shell/script_lazy_load_symbols.sh | 278 ++++++++
.../tests/shell/script_lazy_load_symbols_skip.sh   |  26 +
tools/perf/tests/symbol-bytes.c                    | 340 ++++++++++
tools/perf/tests/tests.h                           |   1 +
tools/perf/util/dso.c                              |  63 +-
tools/perf/util/dso.h                              |  49 ++
tools/perf/util/map.c                              |  30 +-
tools/perf/util/symbol-elf.c                       | 733 ++++++++++++++++++++-
tools/perf/util/symbol-minimal.c                   |  17 +
tools/perf/util/symbol.c                           | 140 +++-
tools/perf/util/symbol.h                           |  24 +-
tools/perf/util/symbol_conf.h                      |   2 +
17 files changed, 1723 insertions(+), 59 deletions(-)
[PATCH v2 0/4] perf script: Bounded and lazy symbol loading
Posted by Alireza Haghdoost via B4 Relay 4 days, 18 hours ago
perf script loads the entire ELF symbol table of every DSO that appears
in a sample, allocating each symbol into an rb-tree held until process
exit. Therefore, a large enough profile turns symbol loading into an
OOM kill.
This is not scalable for profiling a large cgroup with a lot of large
binaries on a production system with limited free memory.

This series adds two independent, opt-in mechanisms and a leading
regression fix they build on:

  [1/4] Fix a broken "#ifdef ELF_C_READ_MMAP" guard so perf actually
        mmaps ELF files instead of malloc'ing section data. This is a
        standalone regression fix that is introduced by 22dd1ac91a77.

  [2/4] --max-symbol-bytes <size>: a byte budget on struct symbol
        allocations (and the lazy index) enforced at the ELF symbol
        loader, degrading to [unknown] with a warning past the cap.
        An unbounded profile doesn't just risk OOM-killing itself. It
        also forces memory pressure on the whole host, pushing the kernel
        to reclaim from co-located latency-sensitive processes. Capping
        it lets the user bound that footprint up front and choose the
        trade-off explicitly.

  [3/4] --lazy-load-symbols: build a compact per-DSO sorted index and
        resolve only the sampled addresses, reading names through the DSO
        data cache at lookup time. On the production fixture, peak RssAnon
        drops from 265 MiB to 39 MiB (6.8x) and wall time from 3.1 s to
        1.85 s (1.7x). Memory optimizations usually cost time; this one
        does not because lazy loading skips a lot of calloc and demangle
        calls.

  [4/4] Shell and unit tests for both options.

Lazy loading handles the common userspace ELF symtab/dynsym path. Eager
loading remains available for dense coverage and for PPC64 .opd and
.gnu_debugdata.

Changes in v2:

- Replace direct pread() name reads with the exact symbol source's DSO data
  cache, preserving split-debuginfo offsets and descriptor reopen behavior.
- Drop the byte-identical-output claim and retain eager loading for PPC64
  .opd and .gnu_debugdata.
- Make the symbol budget atomic and strict, account complete name lengths,
  accept a bare 0 as unlimited, and keep partial zero-sized ranges from
  covering omitted symbols.
- Align lazy lookup with eager duplicate and IFUNC selection, PLT clipping,
  and name-sorted materialization.
- Move option documentation into the feature patches. Add unit and shell
  coverage for cache reopen, truncated names, budget truncation, and skip
  handling.

Link: https://lore.kernel.org/all/20260915-perf-symbol-memory-send-v1-0-1d3360e21f07@uber.com/
---
Alireza Haghdoost (4):
      perf symbols: Fix broken ELF_C_READ_MMAP fallback guard
      perf script: Add --max-symbol-bytes to bound ELF symbol memory
      perf script: Add --lazy-load-symbols for lazy symbol loading
      perf test: Test lazy symbol loading and symbol memory limits

 tools/perf/Documentation/perf-script.txt           |  28 +
 tools/perf/arch/powerpc/util/sym-handling.c        |   5 +-
 tools/perf/builtin-script.c                        |  44 ++
 tools/perf/tests/Build                             |   1 +
 tools/perf/tests/builtin-test.c                    |   1 +
 tools/perf/tests/shell/script_lazy_load_symbols.sh | 278 ++++++++
 .../tests/shell/script_lazy_load_symbols_skip.sh   |  26 +
 tools/perf/tests/symbol-bytes.c                    | 340 ++++++++++
 tools/perf/tests/tests.h                           |   1 +
 tools/perf/util/dso.c                              |  63 +-
 tools/perf/util/dso.h                              |  49 ++
 tools/perf/util/map.c                              |  30 +-
 tools/perf/util/symbol-elf.c                       | 733 ++++++++++++++++++++-
 tools/perf/util/symbol-minimal.c                   |  17 +
 tools/perf/util/symbol.c                           | 140 +++-
 tools/perf/util/symbol.h                           |  24 +-
 tools/perf/util/symbol_conf.h                      |   2 +
 17 files changed, 1723 insertions(+), 59 deletions(-)
---
base-commit: aa18964dd64511305de0711fed912054da6f5d18
change-id: 20260915-perf-symbol-memory-send-e7cfca1ac3d9

Best regards,
--  
Alireza Haghdoost <haghdoost@uber.com>