From: Namhyung Kim <namhyung@kernel.org>
To: Matthew Wood <thepacketgeek@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@redhat.com>,
Arnaldo Carvalho de Melo <acme@kernel.org>,
Mark Rutland <mark.rutland@arm.com>,
Alexander Shishkin <alexander.shishkin@linux.intel.com>,
Jiri Olsa <jolsa@kernel.org>, Ian Rogers <irogers@google.com>,
Adrian Hunter <adrian.hunter@intel.com>,
James Clark <james.clark@linaro.org>,
linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org
Subject: Re: [PATCH v3 0/2] perf unwind: Don't load symbols when the caller doesn't need them
Date: Thu, 5 Nov 2026 23:04:32 -0800 [thread overview]
Message-ID: <au18AJ94dUsE5PaQ@google.com> (raw)
In-Reply-To: <20261030193237.1440673-1-thepacketgeek@gmail.com>
Hello,
On Fri, Oct 30, 2026 at 12:32:32PM -0700, Matthew Wood wrote:
> When perf only needs to know which DSOs a callchain passes through (as
> build-id marking does at the end of 'perf record' and in 'perf inject
> -b') it resolves the callchain without symbols. The DWARF unwinders
> ignore that and look up the symbol of every frame anyway, which loads
> and demangles the whole symbol table of each DSO they visit.
>
> On arm64 every frame pointer sample also gets a short DWARF
> unwind to find the leaf function's caller; since v6.17 (commit
> 29be60c93d2d, "perf build-id: Mark DSO in sample callchains") the end of
> 'perf record -a --call-graph fp' loads the symbols of every user binary
> it sampled. On a 128-CPU arm64 host,
>
> perf record -a -e cycles:u --call-graph fp -- sleep 2
>
> never finishes writing perf.data, with over 1GB of heap growth in 5
> seconds.
>
> Skipping the symbol lookup isn't enough because loading the
> symbols also finds two things the unwinders depend on: the DSO's
> build-id, which libdw needs to fall back to the build-id cache, and any
> separate debuginfo file, through dso__symsrc_filename(), which is how
> both unwinders find a .debug_frame there.
>
> 1: add dso__load_symsrc(), which does the same search for debuginfo
> and the build-id as symbol loading, but doesn't read any symbols
> 2: pass the symbols flag down to the unwinders and honour it, using
> dso__load_symsrc() when symbols aren't wanted, which also makes
> the arm64 leaf frame caller unwind skip symbols
Please don't. I've added dso__dbginfo_type() to handle debug files and
that's the correct way to get the file. Probably dso__debuginfo() would
work for you.
I was working on cleaning up this area, but sidetracked by other things.
I hope to find time for it soon but you can go with the above helpers.
Thanks,
Namhyung
>
> Testing compared v7.3-rc7 with this series, on x86 and natively on a
> CentOS Stream 10 arm64 host:
>
> - The 'perf test' dwarf unwind and 'perf inject' DWARF callchain
> conversion tests pass on both, also in a REFCNT_CHECKING build on
> x86. The libdw multi-threaded unwind and addr2line inline unwinding
> tests pass on x86; on the arm64 host the former is skipped and the
> latter fails both with and without this series.
>
> - 'perf inject -b' on an x86 'perf record --call-graph dwarf' profile
> of a Python workload goes from 0.19s and 69MB max RSS to 0.10s and
> 33MB, with the same build-ids injected.
>
> - A test library built with -fno-asynchronous-unwind-tables, so that
> its CFI is only in .debug_frame, then split with 'objcopy
> --only-keep-debug', sits between two other DSOs in the sampled
> stacks. On both architectures, with the debuginfo found either
> through .gnu_debuglink or only in perf's build-id cache, 'perf
> script' output for a --call-graph dwarf profile, and on arm64 for an
> fp profile, is unchanged with both libdw and libunwind, and 'perf
> inject -b' unwinds the same frames and marks the same DSOs. v1,
> which only passed the flag down, lost every frame past the library
> in all but 5 of 4045 samples in 'perf script'.
>
> libunwind's .debug_frame support couldn't be exercised: EL9's x86
> libunwind is built without it, and on arm64 perf's libunwind support
> has been compiled out since v7.2, as libunwind-arm64.c checks
> HAVE_LIBUNWIND_ARM64_SUPPORT while Makefile.config defines
> HAVE_LIBUNWIND_AARCH64_SUPPORT. With that macro defined by hand, and a
> cast for the build error it then hits, arm64 libunwind results are also
> the same with and without this series. That breakage is independent of
> this series.
>
> Not tested: the build-id cache fallback for DSOs in another mount
> namespace when the MMAP2 events don't carry build-ids.
>
> Changes since v2:
> - Instead of a separate debuginfo lookup, reuse dso__load()'s search
> and stop before reading symbols (dso__load_symsrc()) so candidate
> files are checked against the build-id, --symfs, mount namespaces
> and chroots are honoured, and the search is done once per DSO
> - Drop moving dso__read_build_id() out of 'perf inject'
> - Extend the dwarf unwind test to unwind without symbols, check that
> no symbols get loaded, and compare with unwinding with symbols
> - Link:
> https://lore.kernel.org/all/20261017000158.1178269-1-thepacketgeek@gmail.com/
>
> Changes since v1:
> - Complete re-work on approach based on feedback
> - Link: https://lore.kernel.org/linux-perf-users/20261014151326.4142140-1-thepacketgeek@gmail.com/
>
> Matthew Wood (2):
> perf symbol: Add dso__load_symsrc()
> perf unwind: Don't look up symbols when the caller doesn't want them
>
> tools/perf/tests/dwarf-unwind.c | 71 ++++++++++++++++---
> .../util/arm64-frame-pointer-unwind-support.c | 7 +-
> tools/perf/util/dso.h | 11 +++
> tools/perf/util/machine.c | 7 +-
> tools/perf/util/symbol.c | 40 +++++++++--
> tools/perf/util/symbol.h | 1 +
> tools/perf/util/unwind-libdw.c | 17 ++++-
> tools/perf/util/unwind-libdw.h | 1 +
> tools/perf/util/unwind-libunwind.c | 22 ++++--
> tools/perf/util/unwind.c | 7 +-
> tools/perf/util/unwind.h | 11 ++-
> 11 files changed, 164 insertions(+), 31 deletions(-)
>
>
> base-commit: 24a19b953e2a3d0ea5a8c4951a0ab8f32720c907
> --
> 2.53.0-Meta
>
prev parent reply other threads:[~2026-11-06 7:04 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-30 19:32 Matthew Wood
2026-10-30 19:32 ` [PATCH v3 1/2] perf symbol: Add dso__load_symsrc() Matthew Wood
2026-10-30 19:32 ` [PATCH v3 2/2] perf unwind: Don't look up symbols when the caller doesn't want them Matthew Wood
2026-11-06 7:04 ` Namhyung Kim [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=au18AJ94dUsE5PaQ@google.com \
--to=namhyung@kernel.org \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=irogers@google.com \
--cc=james.clark@linaro.org \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=thepacketgeek@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®