Re: BTF loading failing on perf

From: Andrii Nakryiko
Date: Fri Jun 06 2025 - 16:23:22 EST


On Fri, Jun 6, 2025 at 1:05 PM Arnaldo Carvalho de Melo <acme@xxxxxxxxxx> wrote:
>
> On Fri, Jun 06, 2025 at 09:20:57AM -0700, Andrii Nakryiko wrote:
> > On Fri, Jun 6, 2025 at 9:14 AM Leo Yan <leo.yan@xxxxxxx> wrote:
> > > On Fri, Jun 06, 2025 at 12:37:55PM -0300, Arnaldo Carvalho de Melo wrote:
> > > > root@number:~# perf trace -e openat --max-events=1
> > > > libbpf: failed to read kernel BTF from '/sys/kernel/btf/vmlinux': -ENODEV
> > > > libbpf: failed to read kernel BTF from '/sys/kernel/btf/vmlinux': -ENODEV
> > > > 0.000 ( 0.016 ms): ptyxis-agent/4375 openat(dfd: CWD, filename: "/proc/6593/cmdline", flags: RDONLY|CLOEXEC) = 13
> > > > root@number:~#
> > > >
> > > > openat(AT_FDCWD, "/sys/kernel/btf/vmlinux", O_RDONLY) = 258
> > > > mmap(NULL, 6519699, PROT_READ, MAP_PRIVATE, 258, 0) = -1 ENODEV (No such device)
> > > > libbpf: failed to read kernel BTF from '/sys/kernel/btf/vmlinux': -ENODEV
> > >
> > > Have you included the commit below in the kernel side?
> >
> > It doesn't matter, libbpf should silently fallback to non-mmap() way,
>
> Right, it has to work with older kernels, etc.
>
> > and it clearly doesn't.
>
> > We need something like this:
> > +++ b/tools/lib/bpf/btf.c
> > @@ -1384,12 +1384,12 @@ static struct btf *btf_parse_raw_mmap(const
> > char *path, struct btf *base_btf)
> >
> > fd = open(path, O_RDONLY);
> > if (fd < 0)
> > - return libbpf_err_ptr(-errno);
> > + return ERR_PTR(-errno);
> >
> > if (fstat(fd, &st) < 0) {
> > err = -errno;
> > close(fd);
> > - return libbpf_err_ptr(err);
> > + return ERR_PTR(err);
> > }
> >
> > data = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
> > @@ -1397,7 +1397,7 @@ static struct btf *btf_parse_raw_mmap(const char
> > *path, struct btf *base_btf)
> > close(fd);
> >
> > if (data == MAP_FAILED)
> > - return libbpf_err_ptr(err);
> > + return ERR_PTR(err);
> >
> > btf = btf_new(data, st.st_size, base_btf, true);
> > if (IS_ERR(btf))
> >
> > libbpf_err_ptr() should be used for user-facing API functions, they
> > return NULL on error and set errno, so checking for IS_ERR() is wrong
> > here.
>
> And the only user of the above function is:
>
> btf = btf_parse_raw_mmap(sysfs_btf_path, NULL);
> if (IS_ERR(btf))
> btf = btf__parse(sysfs_btf_path, NULL);
>
> That expects ERR_PTR() to then use IS_ERR().
>
> I think this could be automated with something like coccinnele(sp)?
>
> Anyway, I tested the patch above and it seems to fix the issue, so:
>
> Reported-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
> Reviewed-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
> Tested-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
>

Just sent a quick fix to not leave this waiting over the weekend.
Thanks for catching and reporting, Arnaldo!

> - Arnaldo
>
>
> > Lorenz, can you please test and send a proper fix ASAP?
> >
> > >
> > > commit a539e2a6d51d1c12d89eec149ccc72ec561639bc
> > > Author: Lorenz Bauer <lmb@xxxxxxxxxxxxx>
> > > Date: Tue May 20 14:01:17 2025 +0100
> > >
> > > btf: Allow mmap of vmlinux btf
> > >
> > > User space needs access to kernel BTF for many modern features of BPF.
> > > Right now each process needs to read the BTF blob either in pieces or
> > > as a whole. Allow mmaping the sysfs file so that processes can directly
> > > access the memory allocated for it in the kernel.
> > >
> > > remap_pfn_range is used instead of vm_insert_page due to aarch64
> > > compatibility issues.
> > >
> > > Signed-off-by: Lorenz Bauer <lmb@xxxxxxxxxxxxx>
> > > Signed-off-by: Andrii Nakryiko <andrii@xxxxxxxxxx>
> > > Tested-by: Alan Maguire <alan.maguire@xxxxxxxxxx>
> > > Reviewed-by: Shakeel Butt <shakeel.butt@xxxxxxxxx>
> > > Link: https://lore.kernel.org/bpf/20250520-vmlinux-mmap-v5-1-e8c941acc414@xxxxxxxxxxxxx
> > >
> > > Thanks,
> > > Leo