From: Matthew Wood <thepacketgeek@gmail.com>
To: Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@redhat.com>,
Arnaldo Carvalho de Melo <acme@kernel.org>,
Namhyung Kim <namhyung@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>
Cc: Puranjay Mohan <puranjay@kernel.org>,
Breno Leitao <leitao@debian.org>,
Arnaldo Carvalho de Melo <acme@redhat.com>,
linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH v1] perf machine: Don't unwind the arm64 leaf frame caller without symbols
Date: Wed, 14 Oct 2026 08:13:25 -0700 [thread overview]
Message-ID: <20261014151326.4142140-1-thepacketgeek@gmail.com> (raw)
On arm64, 'perf record --call-graph fp' also samples LR so that
thread__resolve_callchain_sample() can recover the leaf function's
caller, which is missing from the frame pointer chain. It does so via
get_leaf_frame_caller_aarch64(), which runs a DWARF unwind. The
unwinder looks up the symbol of every frame it visits, so the first
lookup in a DSO loads its full symbol table and demangles every symbol
in it.
Commit 02b2705017d2 ("perf callchain: Allow symbols to be optional when
resolving a callchain") added the symbols argument so that callers which
only need maps can avoid loading symbols, and passed it down to every
add_callchain_ip() call. The leaf frame unwind was missed and still runs
for symbols=false, so 'perf inject' on arm64 has been loading symbols it
doesn't need ever since.
Commit 29be60c93d2d ("perf build-id: Mark DSO in sample callchains")
compounded the issue: process_buildids() now walks the callchain of
every sample at the end of 'perf record' to mark DSOs hit. With -a, that
loads and demangles the symbol tables of every user binary sampled on
the system. This can send things into exponential time and memory
(over 1GB of heap growth in 5 seconds), so
perf record -a -e cycles:u --call-graph fp -- sleep 2
never finishes writing perf.data after the workload exits.
Callers that pass symbols=false only want the maps that callchain IPs
fall in, and add_callchain_ip() already honours that by using
thread__find_map() instead of thread__find_symbol(). Skip the leaf
frame unwind for them as well. The leaf frame caller is almost always
in the same DSO as the sampled IP or the next frame in the chain, so
build-id marking loses nothing in practice.
Fixes: 02b2705017d2 ("perf callchain: Allow symbols to be optional when resolving a callchain")
Signed-off-by: Matthew Wood <thepacketgeek@gmail.com>
---
tools/perf/util/machine.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index f86b3b7df742..51597cddd239 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -2989,7 +2989,13 @@ static int thread__resolve_callchain_sample(struct thread *thread,
usr_idx = callchain_param.order == ORDER_CALLEE ? j-2 : j-1;
- if (usr_idx >= 0 && chain->ips[usr_idx] == PERF_CONTEXT_USER) {
+ /*
+ * Finding the leaf frame caller needs a DWARF unwind, and the
+ * unwinder looks up the symbol of every frame it visits. Skip
+ * it when the caller asked for maps only, as for build-id
+ * marking, so that no symbol tables are loaded.
+ */
+ if (symbols && usr_idx >= 0 && chain->ips[usr_idx] == PERF_CONTEXT_USER) {
leaf_frame_caller = get_leaf_frame_caller(sample, thread, usr_idx);
--
2.53.0-Meta
next reply other threads:[~2026-10-14 15:13 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-14 15:13 Matthew Wood [this message]
2026-10-14 15:23 ` [PATCH v1] perf machine: Don't unwind the arm64 leaf frame caller without symbols sashiko-bot
2026-10-14 21:03 ` Ian Rogers
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=20261014151326.4142140-1-thepacketgeek@gmail.com \
--to=thepacketgeek@gmail.com \
--cc=acme@kernel.org \
--cc=acme@redhat.com \
--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=leitao@debian.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=peterz@infradead.org \
--cc=puranjay@kernel.org \
/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