mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
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
> 

      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®