Linux Perf Users
 help / color / mirror / Atom feed
From: "Rui Qi" <qirui.001@bytedance.com>
To: <sashiko@lists.linux.dev>
Cc: <linux-perf-users@vger.kernel.org>
Subject: Re: [PATCH v2] perf: Extract is_mapping_symbol() helper for kernel mapping symbol filtering
Date: Thu, 7 May 2026 14:27:06 +0800	[thread overview]
Message-ID: <1022995d-b4d2-4352-9b22-c665174e87e6@bytedance.com> (raw)
In-Reply-To: <20260506104305.2D54DC2BCB8@smtp.kernel.org>

On 5/6/26 6:43 PM, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
> - [High] Asymmetric mapping symbol filtering leads to map/symbol deletion during ksymbol unregistration.
> - [Medium] Incomplete refactoring leaves ELF mapping symbol logic fragile and inconsistent.
> --
> 
> commit f27956b5bf680b8ef41ba119f6dc5cedae4567f5
> Author: Rui Qi <qirui.001@bytedance.com>
> 
> perf: Extract is_mapping_symbol() helper for kernel mapping symbol filtering
> 
> This patch introduces an is_mapping_symbol() inline helper to consolidate
> logic for filtering out ELF mapping symbols across architectures. It also
> adds the helper to machine__process_ksymbol_register() and
> map__process_kallsym_symbol().
> 
>> The perf tool currently has ad-hoc logic to filter out ELF mapping
>> symbols scattered across multiple files and architectures.  ARM,
>> AArch64 and RISC-V each have their own inline checks in
>> dso__load_sym_internal(), and kallsym processing in map__process_kallsym_symbol()
>> has yet another check for ARM module symbols.
>>
>> This is fragile: adding support for a new architecture or adjusting
>> which prefixes are considered mapping symbols requires touching
>> multiple places, and it is easy for the checks to diverge.  It also
>> does not match the kernel's own is_mapping_symbol() logic, which
>> additionally covers x86 local symbols ('.L*' and 'L0*').
> 
> This commit message claims to convert dso__load_sym_internal() to use the
> new helper. However, this patch does not modify dso__load_sym_internal()
> in tools/perf/util/symbol-elf.c at all, leaving the scattered inline checks
> untouched.
> 
> Because x86 local symbols (.L*) were added to the new helper, does this
> omission introduce a new inconsistency where kallsyms parsing will correctly
> filter x86 .L* symbols, but kernel module parsing via ELF (.ko) will not?
> 

I believe this is not a bug. The is_mapping_symbol() helper is
explicitly
documented as kernel-only:



  /*

   * Ignore kernel mapping symbols, matching kernel is_mapping_symbol()
logic.
   * ...

   * Only use this for kernel symbols (kallsyms, ksymbol events).

   */



The dso__load_sym_internal() function handles both kernel and userspace

symbols. Applying is_mapping_symbol() there would incorrectly filter out

userspace .L* and L0* symbols.



However, I noticed that kernel modules could also benefit from filtering
x86 .L* symbols. I've added the following in dso__load_sym_internal() to
handle this case:



  /*

   * For kernel modules, also reject x86 local symbols (.L* and L0*)

   * to match the kernel's is_mapping_symbol() logic and kallsyms

   * parsing behavior.

   */

  if (kmodule && is_mapping_symbol(elf_name))

      continue;



This ensures:



1. Only kernel modules are filtered (kmodule == true)

2. Userspace symbols are not affected

3. The existing is_mapping_symbol() helper is reused


>> diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
>> index e76f8c86e62a6..e0dcf8bfb896e 100644
>> --- a/tools/perf/util/machine.c
>> +++ b/tools/perf/util/machine.c
>> @@ -729,9 +729,15 @@ static int machine__process_ksymbol_register(struct machine *machine,
>>  {
>>  	struct symbol *sym;
>>  	struct dso *dso = NULL;
>> -	struct map *map = maps__find(machine__kernel_maps(machine), event->ksymbol.addr);
>> +	struct map *map;
>>  	int err = 0;
>>  
>> +	/* Ignore mapping symbols in ksymbol events - check early before any state mutation */
>> +	if (is_mapping_symbol(event->ksymbol.name))
>> +		return 0;
> 
> If a PERF_RECORD_KSYMBOL event arrives with the UNREGISTER flag,
> machine__process_ksymbol() routes it to machine__process_ksymbol_unregister().
> 
> Because machine__process_ksymbol_unregister() does not have the same
> is_mapping_symbol() filter, could maps__find() return the enclosing map
> (such as the BPF JIT map or a loaded kernel module's map) that covers the
> mapping symbol's address?
> 
> tools/perf/util/machine.c:machine__process_ksymbol_unregister() {
> ...
> 	map = maps__find(machine__kernel_maps(machine), event->ksymbol.addr);
> 	if (!map)
> 		return 0;
> 
> 	if (!RC_CHK_EQUAL(map, machine->vmlinux_map))
> 		maps__remove(machine__kernel_maps(machine), map);
> ...
> }
> 
> If so, will the unregister path incorrectly call maps__remove() on that
> parent map, prematurely destroying legitimate tracking state and breaking
> symbol resolution for subsequent samples in that memory region?
> 

You are absolutely right. The is_mapping_symbol() check is missing in

machine__process_ksymbol_unregister(). This could indeed cause the
unregister path to incorrectly remove a parent map when a mapping symbol
address falls within an existing map range.



I will fix this by adding the same filter to
machine__process_ksymbol_unregister():



static int machine__process_ksymbol_unregister(struct machine *machine,
union perf_event *event,struct perf_sample *sample __maybe_unused)
{

      struct symbol *sym;

      struct map *map;


      /* Ignore mapping symbols in ksymbol events */
      if (is_mapping_symbol(event->ksymbol.name))
          return 0;

      map = maps__find(machine__kernel_maps(machine), event->ksymbol.addr);
      ...
}


I will send a v3 with these fixes.



Thanks,

Rui Qi

  reply	other threads:[~2026-05-07  6:28 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-06  7:38 [PATCH v2] perf: Extract is_mapping_symbol() helper for kernel mapping symbol filtering Rui Qi
2026-05-06 10:43 ` sashiko-bot
2026-05-07  6:27   ` Rui Qi [this message]
2026-05-07  7:11 ` [PATCH v3] perf: Add " Rui Qi
2026-05-07 15:23   ` Ian Rogers
2026-05-07 20:38   ` sashiko-bot

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=1022995d-b4d2-4352-9b22-c665174e87e6@bytedance.com \
    --to=qirui.001@bytedance.com \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=sashiko@lists.linux.dev \
    /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