diff mbox series

[RESEND,bpf-next] bpftool: Use sysfs vmlinux when dumping BTF by ID

Message ID 20220428111442.111805-1-larysa.zaremba@intel.com (mailing list archive)
State Superseded
Delegated to: BPF
Headers show
Series [RESEND,bpf-next] bpftool: Use sysfs vmlinux when dumping BTF by ID | expand

Checks

Context Check Description
netdev/tree_selection success Clearly marked for bpf-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/subject_prefix success Link
netdev/cover_letter success Single patches do not need cover letters
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 0 this patch: 0
netdev/cc_maintainers warning 3 maintainers not CCed: john.fastabend@gmail.com kpsingh@kernel.org quentin@isovalent.com
netdev/build_clang success Errors and warnings before: 0 this patch: 0
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 0 this patch: 0
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 56 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-next-VM_Test-1 success Logs for Kernel LATEST on ubuntu-latest + selftests
bpf/vmtest-bpf-next-PR success PR summary
bpf/vmtest-bpf-next-VM_Test-2 success Logs for Kernel LATEST on z15 + selftests

Commit Message

Larysa Zaremba April 28, 2022, 11:14 a.m. UTC
Currently, dumping almost all BTFs specified by id requires
using the -B option to pass the base BTF. For most cases
the vmlinux BTF sysfs path should work.

This patch simplifies dumping by ID usage by attempting to
use vmlinux BTF from sysfs, if the first try of loading BTF by ID
fails with certain conditions.

Signed-off-by: Larysa Zaremba <larysa.zaremba@intel.com>
Reviewed-by: Alexander Lobakin <alexandr.lobakin@intel.com>
---
 tools/bpf/bpftool/btf.c | 35 ++++++++++++++++++++++++++---------
 1 file changed, 26 insertions(+), 9 deletions(-)

Comments

Daniel Borkmann April 28, 2022, 3:17 p.m. UTC | #1
On 4/28/22 1:14 PM, Larysa Zaremba wrote:
> Currently, dumping almost all BTFs specified by id requires
> using the -B option to pass the base BTF. For most cases
> the vmlinux BTF sysfs path should work.
> 
> This patch simplifies dumping by ID usage by attempting to
> use vmlinux BTF from sysfs, if the first try of loading BTF by ID
> fails with certain conditions.
> 
> Signed-off-by: Larysa Zaremba <larysa.zaremba@intel.com>
> Reviewed-by: Alexander Lobakin <alexandr.lobakin@intel.com>
> ---
>   tools/bpf/bpftool/btf.c | 35 ++++++++++++++++++++++++++---------
>   1 file changed, 26 insertions(+), 9 deletions(-)
> 
> diff --git a/tools/bpf/bpftool/btf.c b/tools/bpf/bpftool/btf.c
> index a2c665beda87..557f65e2de5c 100644
> --- a/tools/bpf/bpftool/btf.c
> +++ b/tools/bpf/bpftool/btf.c
> @@ -459,6 +459,22 @@ static int dump_btf_c(const struct btf *btf,
>   	return err;
>   }
>   
> +static const char sysfs_vmlinux[] = "/sys/kernel/btf/vmlinux";
> +
> +static struct btf *get_vmlinux_btf_from_sysfs(void)
> +{
> +	struct btf *base;
> +
> +	base = btf__parse(sysfs_vmlinux, NULL);
> +	if (libbpf_get_error(base)) {
> +		p_err("failed to parse vmlinux BTF at '%s': %ld\n",
> +		      sysfs_vmlinux, libbpf_get_error(base));
> +		base = NULL;
> +	}

Could we reuse libbpf's btf__load_vmlinux_btf() which probes well-known
locations?

> +	return base;
> +}
> +
>   static int do_dump(int argc, char **argv)
>   {
>   	struct btf *btf = NULL, *base = NULL;
> @@ -536,18 +552,11 @@ static int do_dump(int argc, char **argv)
>   		NEXT_ARG();
>   	} else if (is_prefix(src, "file")) {
>   		const char sysfs_prefix[] = "/sys/kernel/btf/";
> -		const char sysfs_vmlinux[] = "/sys/kernel/btf/vmlinux";
>   
>   		if (!base_btf &&
>   		    strncmp(*argv, sysfs_prefix, sizeof(sysfs_prefix) - 1) == 0 &&
> -		    strcmp(*argv, sysfs_vmlinux) != 0) {
> -			base = btf__parse(sysfs_vmlinux, NULL);
> -			if (libbpf_get_error(base)) {
> -				p_err("failed to parse vmlinux BTF at '%s': %ld\n",
> -				      sysfs_vmlinux, libbpf_get_error(base));
> -				base = NULL;
> -			}
> -		}
> +		    strcmp(*argv, sysfs_vmlinux))
> +			base = get_vmlinux_btf_from_sysfs();
>   
>   		btf = btf__parse_split(*argv, base ?: base_btf);
>   		err = libbpf_get_error(btf);
> @@ -593,6 +602,14 @@ static int do_dump(int argc, char **argv)
>   	if (!btf) {
>   		btf = btf__load_from_kernel_by_id_split(btf_id, base_btf);
>   		err = libbpf_get_error(btf);
> +		if (err == -EINVAL && !base_btf) {
> +			btf__free(base);
> +			base = get_vmlinux_btf_from_sysfs();
> +			p_info("Warning: valid base BTF was not specified with -B option, falling back on standard base BTF (sysfs vmlinux)");
> +			btf = btf__load_from_kernel_by_id_split(btf_id, base);
> +			err = libbpf_get_error(btf);
> +		}
> +
>   		if (err) {
>   			p_err("get btf by id (%u): %s", btf_id, strerror(err));
>   			goto done;
>
Andrii Nakryiko April 29, 2022, 5 a.m. UTC | #2
On Thu, Apr 28, 2022 at 8:17 AM Daniel Borkmann <daniel@iogearbox.net> wrote:
>
> On 4/28/22 1:14 PM, Larysa Zaremba wrote:
> > Currently, dumping almost all BTFs specified by id requires
> > using the -B option to pass the base BTF. For most cases
> > the vmlinux BTF sysfs path should work.
> >
> > This patch simplifies dumping by ID usage by attempting to
> > use vmlinux BTF from sysfs, if the first try of loading BTF by ID
> > fails with certain conditions.
> >
> > Signed-off-by: Larysa Zaremba <larysa.zaremba@intel.com>
> > Reviewed-by: Alexander Lobakin <alexandr.lobakin@intel.com>
> > ---
> >   tools/bpf/bpftool/btf.c | 35 ++++++++++++++++++++++++++---------
> >   1 file changed, 26 insertions(+), 9 deletions(-)
> >
> > diff --git a/tools/bpf/bpftool/btf.c b/tools/bpf/bpftool/btf.c
> > index a2c665beda87..557f65e2de5c 100644
> > --- a/tools/bpf/bpftool/btf.c
> > +++ b/tools/bpf/bpftool/btf.c
> > @@ -459,6 +459,22 @@ static int dump_btf_c(const struct btf *btf,
> >       return err;
> >   }
> >
> > +static const char sysfs_vmlinux[] = "/sys/kernel/btf/vmlinux";
> > +
> > +static struct btf *get_vmlinux_btf_from_sysfs(void)
> > +{
> > +     struct btf *base;
> > +
> > +     base = btf__parse(sysfs_vmlinux, NULL);
> > +     if (libbpf_get_error(base)) {
> > +             p_err("failed to parse vmlinux BTF at '%s': %ld\n",
> > +                   sysfs_vmlinux, libbpf_get_error(base));
> > +             base = NULL;
> > +     }
>
> Could we reuse libbpf's btf__load_vmlinux_btf() which probes well-known
> locations?

Systems that don't have /sys/kernel/btf/vmlinux exposed definitely
don't support base BTF, so there is no point in trying to find vmlinux
BTF anywhere else (which is only necessary for old kernels). So I
think it should be fine as is, except we shouldn't guess when base BTF
is needed, it should always be for kernel module BTFs only.

>
> > +     return base;
> > +}
> > +
> >   static int do_dump(int argc, char **argv)
> >   {
> >       struct btf *btf = NULL, *base = NULL;
> > @@ -536,18 +552,11 @@ static int do_dump(int argc, char **argv)
> >               NEXT_ARG();
> >       } else if (is_prefix(src, "file")) {
> >               const char sysfs_prefix[] = "/sys/kernel/btf/";
> > -             const char sysfs_vmlinux[] = "/sys/kernel/btf/vmlinux";
> >
> >               if (!base_btf &&
> >                   strncmp(*argv, sysfs_prefix, sizeof(sysfs_prefix) - 1) == 0 &&
> > -                 strcmp(*argv, sysfs_vmlinux) != 0) {
> > -                     base = btf__parse(sysfs_vmlinux, NULL);
> > -                     if (libbpf_get_error(base)) {
> > -                             p_err("failed to parse vmlinux BTF at '%s': %ld\n",
> > -                                   sysfs_vmlinux, libbpf_get_error(base));
> > -                             base = NULL;
> > -                     }
> > -             }
> > +                 strcmp(*argv, sysfs_vmlinux))
> > +                     base = get_vmlinux_btf_from_sysfs();
> >
> >               btf = btf__parse_split(*argv, base ?: base_btf);
> >               err = libbpf_get_error(btf);
> > @@ -593,6 +602,14 @@ static int do_dump(int argc, char **argv)
> >       if (!btf) {
> >               btf = btf__load_from_kernel_by_id_split(btf_id, base_btf);
> >               err = libbpf_get_error(btf);
> > +             if (err == -EINVAL && !base_btf) {
> > +                     btf__free(base);
> > +                     base = get_vmlinux_btf_from_sysfs();
> > +                     p_info("Warning: valid base BTF was not specified with -B option, falling back on standard base BTF (sysfs vmlinux)");
> > +                     btf = btf__load_from_kernel_by_id_split(btf_id, base);
> > +                     err = libbpf_get_error(btf);
> > +             }
> > +
> >               if (err) {
> >                       p_err("get btf by id (%u): %s", btf_id, strerror(err));
> >                       goto done;
> >
>
diff mbox series

Patch

diff --git a/tools/bpf/bpftool/btf.c b/tools/bpf/bpftool/btf.c
index a2c665beda87..557f65e2de5c 100644
--- a/tools/bpf/bpftool/btf.c
+++ b/tools/bpf/bpftool/btf.c
@@ -459,6 +459,22 @@  static int dump_btf_c(const struct btf *btf,
 	return err;
 }
 
+static const char sysfs_vmlinux[] = "/sys/kernel/btf/vmlinux";
+
+static struct btf *get_vmlinux_btf_from_sysfs(void)
+{
+	struct btf *base;
+
+	base = btf__parse(sysfs_vmlinux, NULL);
+	if (libbpf_get_error(base)) {
+		p_err("failed to parse vmlinux BTF at '%s': %ld\n",
+		      sysfs_vmlinux, libbpf_get_error(base));
+		base = NULL;
+	}
+
+	return base;
+}
+
 static int do_dump(int argc, char **argv)
 {
 	struct btf *btf = NULL, *base = NULL;
@@ -536,18 +552,11 @@  static int do_dump(int argc, char **argv)
 		NEXT_ARG();
 	} else if (is_prefix(src, "file")) {
 		const char sysfs_prefix[] = "/sys/kernel/btf/";
-		const char sysfs_vmlinux[] = "/sys/kernel/btf/vmlinux";
 
 		if (!base_btf &&
 		    strncmp(*argv, sysfs_prefix, sizeof(sysfs_prefix) - 1) == 0 &&
-		    strcmp(*argv, sysfs_vmlinux) != 0) {
-			base = btf__parse(sysfs_vmlinux, NULL);
-			if (libbpf_get_error(base)) {
-				p_err("failed to parse vmlinux BTF at '%s': %ld\n",
-				      sysfs_vmlinux, libbpf_get_error(base));
-				base = NULL;
-			}
-		}
+		    strcmp(*argv, sysfs_vmlinux))
+			base = get_vmlinux_btf_from_sysfs();
 
 		btf = btf__parse_split(*argv, base ?: base_btf);
 		err = libbpf_get_error(btf);
@@ -593,6 +602,14 @@  static int do_dump(int argc, char **argv)
 	if (!btf) {
 		btf = btf__load_from_kernel_by_id_split(btf_id, base_btf);
 		err = libbpf_get_error(btf);
+		if (err == -EINVAL && !base_btf) {
+			btf__free(base);
+			base = get_vmlinux_btf_from_sysfs();
+			p_info("Warning: valid base BTF was not specified with -B option, falling back on standard base BTF (sysfs vmlinux)");
+			btf = btf__load_from_kernel_by_id_split(btf_id, base);
+			err = libbpf_get_error(btf);
+		}
+
 		if (err) {
 			p_err("get btf by id (%u): %s", btf_id, strerror(err));
 			goto done;