linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Yonghong Song <yonghong.song@linux.dev>
To: Menglong Dong <menglong8.dong@gmail.com>,
	ast@kernel.org, daniel@iogearbox.net
Cc: john.fastabend@gmail.com, andrii@kernel.org,
	martin.lau@linux.dev, eddyz87@gmail.com, song@kernel.org,
	kpsingh@kernel.org, sdf@fomichev.me, haoluo@google.com,
	jolsa@kernel.org, bpf@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	Menglong Dong <dongml2@chinatelecom.cn>
Subject: Re: [PATCH bpf-next v3] bpf: make the attach target more accurate
Date: Thu, 10 Jul 2025 20:46:18 -0700	[thread overview]
Message-ID: <ffcbe060-a15d-44d7-bf5e-090e74726c31@linux.dev> (raw)
In-Reply-To: <2f8c792e-9675-4385-b1cb-10266c72bd45@linux.dev>



On 7/10/25 8:10 PM, Yonghong Song wrote:
>
>
> On 7/10/25 12:08 AM, Menglong Dong wrote:
>> For now, we lookup the address of the attach target in
>> bpf_check_attach_target() with find_kallsyms_symbol_value or
>> kallsyms_lookup_name, which is not accurate in some cases.
>>
>> For example, we want to attach to the target "t_next", but there are
>> multiple symbols with the name "t_next" exist in the kallsyms, which 
>> makes
>> the attach target ambiguous, and the attach should fail.
>>
>> Introduce the function bpf_lookup_attach_addr() to do the address 
>> lookup,
>> which will return -EADDRNOTAVAIL when the symbol is not unique.
>>
>> We can do the testing with following shell:
>>
>> for s in $(cat /proc/kallsyms | awk '{print $3}' | sort | uniq -d)
>> do
>>    if grep -q "^$s\$" 
>> /sys/kernel/debug/tracing/available_filter_functions
>>    then
>>      bpftrace -e "fentry:$s {printf(\"1\");}" -v
>>    fi
>> done
>>
>> The script will find all the duplicated symbols in /proc/kallsyms, which
>> is also in /sys/kernel/debug/tracing/available_filter_functions, and
>> attach them with bpftrace.
>>
>> After this patch, all the attaching fail with the error:
>>
>> The address of function xxx cannot be found
>> or
>> No BTF found for xxx
>>
>> Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
>
> Maybe we should prevent vmlinux BTF generation for such symbols
> which are static and have more than one instances? This can
> be done in pahole and downstream libbpf/kernel do not
> need to do anything. This can avoid libbpf/kernel runtime overhead
> since bpf_lookup_attach_addr() could be expensive as it needs
> to go through ALL symbols, even for unique symbols.

There is a multi-link effort:
   https://lore.kernel.org/bpf/20250703121521.1874196-1-dongml2@chinatelecom.cn/
which tries to do similar thing for multi-kprobe. For example, for fentry,
multi-link may pass an array of btf_id's to the kernel. For such cases,
this patch may cause significant performance overhead.

>
>
>> ---
>> v3:
>> - reject all the duplicated symbols
>> v2:
>> - Lookup both vmlinux and modules symbols when mod is NULL, just like
>>    kallsyms_lookup_name().
>>
>>    If the btf is not a modules, shouldn't we lookup on the vmlinux only?
>>    I'm not sure if we should keep the same logic with
>>    kallsyms_lookup_name().
>>
>> - Return the kernel symbol that don't have ftrace location if the 
>> symbols
>>    with ftrace location are not available
>> ---
>>   kernel/bpf/verifier.c | 71 ++++++++++++++++++++++++++++++++++++++++---
>>   1 file changed, 66 insertions(+), 5 deletions(-)
>>
>> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
>> index 53007182b46b..bf4951154605 100644
>> --- a/kernel/bpf/verifier.c
>> +++ b/kernel/bpf/verifier.c
>> @@ -23476,6 +23476,67 @@ static int 
>> check_non_sleepable_error_inject(u32 btf_id)
>>       return btf_id_set_contains(&btf_non_sleepable_error_inject, 
>> btf_id);
>>   }
>>   +struct symbol_lookup_ctx {
>> +    const char *name;
>> +    unsigned long addr;
>> +};
>> +
>> +static int symbol_callback(void *data, unsigned long addr)
>> +{
>> +    struct symbol_lookup_ctx *ctx = data;
>> +
>> +    if (ctx->addr)
>> +        return -EADDRNOTAVAIL;
>> +    ctx->addr = addr;
>> +
>> +    return 0;
>> +}
>> +
>> +static int symbol_mod_callback(void *data, const char *name, 
>> unsigned long addr)
>> +{
>> +    if (strcmp(((struct symbol_lookup_ctx *)data)->name, name) != 0)
>> +        return 0;
>> +
>> +    return symbol_callback(data, addr);
>> +}
>> +
>> +/**
>> + * bpf_lookup_attach_addr: Lookup address for a symbol
>> + *
>> + * @mod: kernel module to lookup the symbol, NULL means to lookup 
>> both vmlinux
>> + * and modules symbols
>> + * @sym: the symbol to resolve
>> + * @addr: pointer to store the result
>> + *
>> + * Lookup the address of the symbol @sym. If multiple symbols with 
>> the name
>> + * @sym exist, -EADDRNOTAVAIL will be returned.
>> + *
>> + * Returns: 0 on success, -errno otherwise.
>> + */
>> +static int bpf_lookup_attach_addr(const struct module *mod, const 
>> char *sym,
>> +                  unsigned long *addr)
>> +{
>> +    struct symbol_lookup_ctx ctx = { .addr = 0, .name = sym };
>> +    const char *mod_name = NULL;
>> +    int err = 0;
>> +
>> +#ifdef CONFIG_MODULES
>> +    mod_name = mod ? mod->name : NULL;
>> +#endif
>> +    if (!mod_name)
>> +        err = kallsyms_on_each_match_symbol(symbol_callback, sym, 
>> &ctx);
>> +
>> +    if (!err && !ctx.addr)
>> +        err = module_kallsyms_on_each_symbol(mod_name, 
>> symbol_mod_callback,
>> +                             &ctx);
>> +
>> +    if (!ctx.addr)
>> +        err = -ENOENT;
>> +    *addr = err ? 0 : ctx.addr;
>> +
>> +    return err;
>> +}
>> +
>>   int bpf_check_attach_target(struct bpf_verifier_log *log,
>>                   const struct bpf_prog *prog,
>>                   const struct bpf_prog *tgt_prog,
>> @@ -23729,18 +23790,18 @@ int bpf_check_attach_target(struct 
>> bpf_verifier_log *log,
>>               if (btf_is_module(btf)) {
>>                   mod = btf_try_get_module(btf);
>>                   if (mod)
>> -                    addr = find_kallsyms_symbol_value(mod, tname);
>> +                    ret = bpf_lookup_attach_addr(mod, tname, &addr);
>>                   else
>> -                    addr = 0;
>> +                    ret = -ENOENT;
>>               } else {
>> -                addr = kallsyms_lookup_name(tname);
>> +                ret = bpf_lookup_attach_addr(NULL, tname, &addr);
>>               }
>> -            if (!addr) {
>> +            if (ret) {
>>                   module_put(mod);
>>                   bpf_log(log,
>>                       "The address of function %s cannot be found\n",
>>                       tname);
>> -                return -ENOENT;
>> +                return ret;
>>               }
>>           }
>
>


  reply	other threads:[~2025-07-11  3:46 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-07-10  7:08 [PATCH bpf-next v3] bpf: make the attach target more accurate Menglong Dong
2025-07-10 23:24 ` Andrii Nakryiko
2025-07-11  1:27   ` Menglong Dong
2025-07-11  3:10 ` Yonghong Song
2025-07-11  3:46   ` Yonghong Song [this message]
2025-07-11  5:51     ` Menglong Dong
2025-07-11  6:37       ` Menglong Dong
2025-07-11 11:23       ` Jiri Olsa
2025-07-11 12:01         ` Menglong Dong
2025-07-14 19:52 ` Alexei Starovoitov
2025-07-14 21:50   ` Menglong Dong
2025-07-14 22:29     ` Alexei Starovoitov
2025-07-14 23:32       ` Menglong Dong

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=ffcbe060-a15d-44d7-bf5e-090e74726c31@linux.dev \
    --to=yonghong.song@linux.dev \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=dongml2@chinatelecom.cn \
    --cc=eddyz87@gmail.com \
    --cc=haoluo@google.com \
    --cc=john.fastabend@gmail.com \
    --cc=jolsa@kernel.org \
    --cc=kpsingh@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=martin.lau@linux.dev \
    --cc=menglong8.dong@gmail.com \
    --cc=sdf@fomichev.me \
    --cc=song@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;
as well as URLs for NNTP newsgroup(s).