mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Namhyung Kim <namhyung@kernel.org>
To: Ian Rogers <irogers@google.com>
Cc: Michal Pluta <michalpl2003@gmail.com>,
	acme@kernel.org, Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@redhat.com>,
	Mark Rutland <mark.rutland@arm.com>,
	Alexander Shishkin <alexander.shishkin@linux.intel.com>,
	Jiri Olsa <jolsa@kernel.org>,
	Adrian Hunter <adrian.hunter@intel.com>,
	James Clark <james.clark@linaro.org>,
	linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH 3/5] perf symbol: Grow the Rust demangle buffer geometrically
Date: Tue, 6 Oct 2026 13:06:21 -0700	[thread overview]
Message-ID: <asVUvfhz4wG5CnZC@google.com> (raw)
In-Reply-To: <CAP-5=fVe=VxnxypQYNt1h-s+3=Me8D_fpBL3LD1Eeb1cGvUc3g@mail.gmail.com>

On Mon, Sep 28, 2026 at 02:43:21PM -0700, Ian Rogers wrote:
> On Sun, Sep 27, 2026 at 6:02 PM Michal Pluta <michalpl2003@gmail.com> wrote:
> >
> > When a demangled Rust name doesn't fit in the provided buffer,
> > dso__demangle_sym() adds 32 bytes to it and formats the name again from
> > the start.  The number of attempts grows with the length of the output,
> > so the total work is quadratic.  Names with deeply nested generic types
> > need many attempts, leading to noticeable slowdowns in larger programs.
> >
> > Double the buffer instead, reaching the maximum buffer limit exactly
> > rather than stopping 32 bytes early.  The demangled names are
> > unchanged.
> >
> > Add a test for a symbol whose expansion exceeds the bound.
> >
> > Signed-off-by: Michal Pluta <michalpl2003@gmail.com>
> > ---
> >  tools/perf/tests/demangle-rust-v0-test.c | 12 ++++++++++++
> >  tools/perf/util/symbol.c                 | 10 ++++++++--
> >  2 files changed, 20 insertions(+), 2 deletions(-)
> >
> > diff --git a/tools/perf/tests/demangle-rust-v0-test.c b/tools/perf/tests/demangle-rust-v0-test.c
> > index ee4ddb61174b..d1e0636d73bc 100644
> > --- a/tools/perf/tests/demangle-rust-v0-test.c
> > +++ b/tools/perf/tests/demangle-rust-v0-test.c
> > @@ -69,6 +69,18 @@ static int test__demangle_rust(struct test_suite *test __maybe_unused, int subte
> >                 free(buf);
> >         }
> >
> > +       /*
> > +        * A symbol with more lifetimes bound than fit in the largest buffer
> > +        * must fail to demangle rather than give a truncated name.
> > +        */
> > +       buf = dso__demangle_sym(/*dso=*/NULL, /*kmodule=*/0, "_RINvC1a1fFGZZZZZZ_EuE");
> > +       if (buf) {
> > +               pr_debug("FAILED: symbol larger than the buffer limit demangled to %zu bytes\n",
> > +                        strlen(buf));
> > +               ret = TEST_FAIL;
> > +               free(buf);
> > +       }
> > +
> >         return ret;
> >  }
> >
> > diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
> > index 3cb42805a82f..1a52bc2980a0 100644
> > --- a/tools/perf/util/symbol.c
> > +++ b/tools/perf/util/symbol.c
> > @@ -2737,29 +2737,35 @@ char *cxx_demangle_sym(const char *str __maybe_unused, bool params __maybe_unuse
> >  }
> >  #endif /* !HAVE_CXA_DEMANGLE_SUPPORT */
> >
> > +/* Buffer limit for a demangled Rust symbol name. */
> > +#define RUST_DEMANGLE_MAX_LEN (1024 * 1024)
> > +
> >  char *dso__demangle_sym(struct dso *dso, int kmodule, const char *elf_name)
> >  {
> >         struct demangle rust_demangle = {
> >                 .style = DemangleStyleUnknown,
> >         };
> >         char *demangled = NULL;
> > +       size_t buf_len;
> 
> It seems changing the scope of this variable is unnecessary.
> 
> >
> >         /*
> >          * We need to figure out if the object was created from C++ sources
> >          * DWARF DW_compile_unit has this, but we don't always have access
> >          * to it...
> >          */
> >         if (!want_demangle((dso && dso__kernel(dso)) || kmodule))
> >                 return demangled;
> >
> >         rust_demangle_demangle(elf_name, &rust_demangle);
> >         if (rust_demangle_is_known(&rust_demangle)) {
> >                 /* A rust mangled name. */
> >                 if (rust_demangle.mangled_len == 0)
> >                         return demangled;
> >
> > -               for (size_t buf_len = roundup_pow_of_two(rust_demangle.mangled_len * 2);
> > -                    buf_len < 1024 * 1024; buf_len += 32) {
> > +               for (buf_len = min_t(size_t, roundup_pow_of_two(rust_demangle.mangled_len * 2),
> > +                                    RUST_DEMANGLE_MAX_LEN);
> > +                    buf_len <= RUST_DEMANGLE_MAX_LEN;
> > +                    buf_len *= 2) {
> 
> Thanks for digging into this problem and exploring a fix! Previously,
> we guessed the demangled length was twice the mangled length, then
> added 32 bytes for each retry. These were numbers I pulled out of thin
> air, so I'm glad you've found them to be wrong :-). Could we estimate
> the initial demangled size better? Could you get data from Bevy and
> Typst? I'm a little concerned that a demangled symbol of say just over
> 2KB might require 4KB with this change, instead of 2KB + 32bytes.

I guess it's hard to predict a good initial size as backrefs can make
long strings easily.  If we really care about the memory usage, how
about calling realloc() for the actual length at the end?

Thanks,
Namhyung


  reply	other threads:[~2026-10-06 20:06 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-28  1:02 [PATCH 0/5] perf symbol: Speed up demangling of long Rust symbols Michal Pluta
2026-09-28  1:02 ` [PATCH 1/5] perf test demangle: Fail when demangling fails Michal Pluta
2026-09-28 21:31   ` Ian Rogers
2026-09-28  1:02 ` [PATCH 2/5] perf symbol: Don't return an unterminated Rust demangle buffer Michal Pluta
2026-09-28 21:33   ` Ian Rogers
2026-09-30 17:10     ` Arnaldo Carvalho de Melo
2026-09-28  1:02 ` [PATCH 3/5] perf symbol: Grow the Rust demangle buffer geometrically Michal Pluta
2026-09-28 21:43   ` Ian Rogers
2026-10-06 20:06     ` Namhyung Kim [this message]
2026-09-28  1:02 ` [PATCH 4/5] perf symbol: Shrink the demangled Rust buffer to fit Michal Pluta
2026-10-06 20:07   ` Namhyung Kim
2026-09-28  1:02 ` [PATCH 5/5] perf symbol: Move Rust demangling into its own function Michal Pluta
2026-10-06 20:10 ` [PATCH 0/5] perf symbol: Speed up demangling of long Rust symbols Namhyung Kim

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=asVUvfhz4wG5CnZC@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=michalpl2003@gmail.com \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.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

all inboxes | Powered by JetHome®