bpf.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH bpf-next v2] bpftool: Use sysfs vmlinux when dumping BTF by ID
@ 2022-05-05 13:05 Larysa Zaremba
  2022-05-10  0:24 ` Andrii Nakryiko
  0 siblings, 1 reply; 2+ messages in thread
From: Larysa Zaremba @ 2022-05-05 13:05 UTC (permalink / raw)
  To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko
  Cc: netdev, bpf, linux-kernel, Martin KaFai Lau, Song Liu,
	Yonghong Song, John Fastabend, KP Singh, Quentin Monnet,
	Maciej Fijalkowski, Larysa Zaremba, Alexander Lobakin

Currently, dumping almost all BTFs specified by id requires
using the -B option to pass the base BTF. For kernel module
BTFs 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 and the ID corresponds to a kernel
module BTF.

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

diff --git a/tools/bpf/bpftool/btf.c b/tools/bpf/bpftool/btf.c
index a2c665beda87..070e0c1595d7 100644
--- a/tools/bpf/bpftool/btf.c
+++ b/tools/bpf/bpftool/btf.c
@@ -459,6 +459,56 @@ 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 struct btf *btf_try_load_with_vmlinux(__u32 btf_id, struct btf **base)
+{
+	struct bpf_btf_info btf_info = {};
+	unsigned int len;
+	int btf_fd;
+	int err;
+
+	btf_fd = bpf_btf_get_fd_by_id(btf_id);
+	if (btf_fd < 0) {
+		p_err("can't get BTF object by id (%u): %s",
+		      btf_id, strerror(errno));
+		return ERR_PTR(btf_fd);
+	}
+
+	len = sizeof(btf_info);
+	err = bpf_obj_get_info_by_fd(btf_fd, &btf_info, &len);
+	close(btf_fd);
+
+	if (err) {
+		p_err("can't get BTF (ID %u) object info: %s",
+		      btf_id, strerror(errno));
+		return ERR_PTR(err);
+	}
+
+	if (!btf_info.kernel_btf) {
+		p_err("BTF with ID %u is not a kernel module BTF, cannot use vmlinux as base",
+		      btf_id);
+		return ERR_PTR(-EINVAL);
+	}
+
+	*base = get_vmlinux_btf_from_sysfs();
+	return btf__load_from_kernel_by_id_split(btf_id, *base);
+}
+
 static int do_dump(int argc, char **argv)
 {
 	struct btf *btf = NULL, *base = NULL;
@@ -536,18 +586,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 +636,12 @@ 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) {
+			p_info("Warning: valid base BTF was not specified with -B option, falling back on standard base BTF (sysfs vmlinux)");
+			btf = btf_try_load_with_vmlinux(btf_id, &base);
+			err = libbpf_get_error(btf);
+		}
+
 		if (err) {
 			p_err("get btf by id (%u): %s", btf_id, strerror(err));
 			goto done;
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH bpf-next v2] bpftool: Use sysfs vmlinux when dumping BTF by ID
  2022-05-05 13:05 [PATCH bpf-next v2] bpftool: Use sysfs vmlinux when dumping BTF by ID Larysa Zaremba
@ 2022-05-10  0:24 ` Andrii Nakryiko
  0 siblings, 0 replies; 2+ messages in thread
From: Andrii Nakryiko @ 2022-05-10  0:24 UTC (permalink / raw)
  To: Larysa Zaremba
  Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko, Networking,
	bpf, open list, Martin KaFai Lau, Song Liu, Yonghong Song,
	John Fastabend, KP Singh, Quentin Monnet, Maciej Fijalkowski,
	Alexander Lobakin

On Thu, May 5, 2022 at 6:17 AM Larysa Zaremba <larysa.zaremba@intel.com> wrote:
>
> Currently, dumping almost all BTFs specified by id requires
> using the -B option to pass the base BTF. For kernel module
> BTFs 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 and the ID corresponds to a kernel
> module BTF.

It feels sloppy to first try without base BTF and then fallback to
base BTF. When specified ID of BTF object, let's just get its struct
bpf_btf_info with bpf_obj_get_info_by_fd() and then check that
kernel_btf is set and name isn't "vmlinux". This will mean it's kernel
module, so load base BTF from /sys/kernel/btf/vmlinux. If that fails,
there is no way that kernel module BTF will be successfully loaded, so
there is no point in trying.

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

[...]

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-05-10  0:24 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-05 13:05 [PATCH bpf-next v2] bpftool: Use sysfs vmlinux when dumping BTF by ID Larysa Zaremba
2022-05-10  0:24 ` Andrii Nakryiko

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).