Re: [PATCH bpf-next v2 4/6] libbpf: Resolve typeless ksyms via KALLSYMS_QUERY ioctl
From: David Laight
Date: Wed Oct 28 2026 - 10:07:55 EST
On Tue, 27 Oct 2026 15:07:44 -0700
Samuel Wu <wusamuel@xxxxxxxxxx> wrote:
> On Mon, Oct 26, 2026 at 2:28 AM Jiri Olsa <olsajiri@xxxxxxxxx> wrote:
> >
> > On Thu, Oct 22, 2026 at 05:16:05PM -0700, Samuel Wu wrote:
> >
> > SNIP
> >
> > > +static int bpf_object__query_ksyms(struct bpf_object *obj)
> > > +{
> > > + struct kallsyms_query q;
> > > + struct extern_desc *ext;
> > > + int err = 0;
> > > + int fd;
> > > + int i;
> > > +
> > > + fd = open("/proc/kallsyms", O_RDONLY | O_CLOEXEC);
> > > + if (fd < 0)
> > > + return -errno;
> > > +
> > > + for (i = 0; i < obj->nr_extern; i++) {
> > > + ext = &obj->externs[i];
> > > + if (ext->type != EXT_KSYM || ext->ksym.type_id)
> > > + continue;
> > > +
> > > + q = (struct kallsyms_query){
> > > + .size = sizeof(q),
> > > + .query_flags = KALLSYMS_QUERY_BY_SYMBOL,
> > > + .sym_name_addr = ptr_to_u64(ext->name),
> > > + };
> > > +
> > > + err = -errno;
> > > + if (err == -ENOENT) {
> > > + err = 0;
> > > + continue;
> > > + }
> > > + if (err == -EADDRNOTAVAIL)
> > > + pr_warn("extern (ksym) '%s': resolution is ambiguous\n",
> > > + ext->name);
> > > + break;
> > > + }
> > > + ext->is_set = true;
> > > + ext->ksym.addr = q.sym_addr;
> > > + pr_debug("extern (ksym) '%s': resolved in kernel to 0x%llx\n",
> > > + ext->name, ext->ksym.addr);
> > > + }
> > > + close(fd);
> > > + return err;
> > > +}
> > > +
> > > +static int bpf_object__resolve_typeless_ksyms(struct bpf_object *obj)
> > > {
> > > + int err;
> > > +
> > > + err = bpf_object__query_ksyms(obj);
> >
> > hi,
> > we could also add similar support for libbpf_available_kallsyms_parse and
> > probably in some other places like bpf_get_ksyms.. which makes me think it
> > could be useful to have KALLSYMS_QUERY support for multiple symbols
> >
> > thanks,
> > jirka
> >
>
> Thanks for lookiing over this Jiri!
>
> Using KALLSYMS_QUERY for libbpf_available_kallsyms_parse() would
> theoretically by O(m*log(n)) instead of O(n*log(m)), where m is the
> number of tracefs symbols, and n is lines in kallsyms, with n >> m.
> But AFAICT, libbpf_available_kallsyms_parse() would only be called in
> pre-6.5 kernels, for kernels without commit 83f74441 (ftrace: Show all
> functions with addresses in available_filter_functions_addrs); so this
> ioctl could never be called.
Isn't that code also O(n*log(m)) ?
I've got a patch (I might send it after the merge window) that changes
one of the ftrace functions to look up every symbol by name, not just
when only asked to look up one.
It can also use the 'callback' function to detect duplicates.
That should be massively faster - especially with my ~18 fold improvement
(also waiting for the merge window to end before posting a new
(not much changed) version).
Does look the the code could do with getting the 'symbol name table index'
for the symbol so that it can read the entries sequentially from that
point onwards.
David
>
> And regarding bpf_get_ksyms(), it loads all traceable functions and
> needs the full syms table, so a /proc/kallsyms should fits better.
>
> I did profile a slightly different form of querying multiple symbols
> at once [1], but didn't see much benefit. struct kallsyms_query is
> extensible via size and query_flags, so we can update in the future as
> needed.
>
> [1]: https://lore.kernel.org/all/CAG2KctozPSev+EXSpHitM3JWfjufQaEjsPJHS_1HJ1wSm7sJ1w@xxxxxxxxxxxxxx/
>
> [...]
>