All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexei Starovoitov <alexei.starovoitov@gmail.com>
To: davem@davemloft.net
Cc: daniel@iogearbox.net, andrii@kernel.org,
	john.fastabend@gmail.com, bpf@vger.kernel.org,
	kernel-team@fb.com
Subject: [PATCH v4 bpf-next 09/22] libbpf: Support for fd_idx
Date: Fri,  7 May 2021 20:48:24 -0700	[thread overview]
Message-ID: <20210508034837.64585-10-alexei.starovoitov@gmail.com> (raw)
In-Reply-To: <20210508034837.64585-1-alexei.starovoitov@gmail.com>

From: Alexei Starovoitov <ast@kernel.org>

Add support for FD_IDX and make libbpf prefer that approach to loading programs
to make testing and bisection easy.
The next patch will fine tune libbpf behavior to use FEAT_FD_IDX only when
generating loader program.

Signed-off-by: Alexei Starovoitov <ast@kernel.org>
---
 tools/lib/bpf/bpf.c             |  1 +
 tools/lib/bpf/libbpf.c          | 73 +++++++++++++++++++++++++++++----
 tools/lib/bpf/libbpf_internal.h |  1 +
 3 files changed, 68 insertions(+), 7 deletions(-)

diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index bba48ff4c5c0..b96a3aba6fcc 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -252,6 +252,7 @@ int libbpf__bpf_prog_load(const struct bpf_prog_load_params *load_attr)
 
 	attr.prog_btf_fd = load_attr->prog_btf_fd;
 	attr.prog_flags = load_attr->prog_flags;
+	attr.fd_array = ptr_to_u64(load_attr->fd_array);
 
 	attr.func_info_rec_size = load_attr->func_info_rec_size;
 	attr.func_info_cnt = load_attr->func_info_cnt;
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 491349a31a06..0b9270403a77 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -175,6 +175,8 @@ enum kern_feature_id {
 	FEAT_MODULE_BTF,
 	/* BTF_KIND_FLOAT support */
 	FEAT_BTF_FLOAT,
+	/* Kernel support for FD_IDX */
+	FEAT_FD_IDX,
 	__FEAT_CNT,
 };
 
@@ -288,6 +290,7 @@ struct bpf_program {
 	__u32 line_info_rec_size;
 	__u32 line_info_cnt;
 	__u32 prog_flags;
+	int *fd_array;
 };
 
 struct bpf_struct_ops {
@@ -4238,6 +4241,29 @@ static int probe_module_btf(void)
 	return !err;
 }
 
+static int probe_kern_fd_idx(void)
+{
+	struct bpf_load_program_attr attr;
+	struct bpf_insn insns[] = {
+		BPF_LD_IMM64_RAW(BPF_REG_0, BPF_PSEUDO_MAP_IDX, 0),
+		BPF_EXIT_INSN(),
+	};
+	int err;
+
+	memset(&attr, 0, sizeof(attr));
+	attr.prog_type = BPF_PROG_TYPE_SOCKET_FILTER;
+	attr.insns = insns;
+	attr.insns_cnt = ARRAY_SIZE(insns);
+	attr.license = "GPL";
+
+	err = bpf_load_program_xattr(&attr, NULL, 0);
+	if (err >= 0) {
+		close(err);
+		return 0;
+	}
+	return errno == EPROTO;
+}
+
 enum kern_feature_result {
 	FEAT_UNKNOWN = 0,
 	FEAT_SUPPORTED = 1,
@@ -4288,6 +4314,9 @@ static struct kern_feature_desc {
 	[FEAT_BTF_FLOAT] = {
 		"BTF_KIND_FLOAT support", probe_kern_btf_float,
 	},
+	[FEAT_FD_IDX] = {
+		"prog_load with fd_idx", probe_kern_fd_idx,
+	},
 };
 
 static bool kernel_supports(enum kern_feature_id feat_id)
@@ -6368,19 +6397,34 @@ bpf_object__relocate_data(struct bpf_object *obj, struct bpf_program *prog)
 
 		switch (relo->type) {
 		case RELO_LD64:
-			insn[0].src_reg = BPF_PSEUDO_MAP_FD;
-			insn[0].imm = obj->maps[relo->map_idx].fd;
+			if (kernel_supports(FEAT_FD_IDX)) {
+				insn[0].src_reg = BPF_PSEUDO_MAP_IDX;
+				insn[0].imm = relo->map_idx;
+			} else {
+				insn[0].src_reg = BPF_PSEUDO_MAP_FD;
+				insn[0].imm = obj->maps[relo->map_idx].fd;
+			}
 			break;
 		case RELO_DATA:
-			insn[0].src_reg = BPF_PSEUDO_MAP_VALUE;
 			insn[1].imm = insn[0].imm + relo->sym_off;
-			insn[0].imm = obj->maps[relo->map_idx].fd;
+			if (kernel_supports(FEAT_FD_IDX)) {
+				insn[0].src_reg = BPF_PSEUDO_MAP_IDX_VALUE;
+				insn[0].imm = relo->map_idx;
+			} else {
+				insn[0].src_reg = BPF_PSEUDO_MAP_VALUE;
+				insn[0].imm = obj->maps[relo->map_idx].fd;
+			}
 			break;
 		case RELO_EXTERN_VAR:
 			ext = &obj->externs[relo->sym_off];
 			if (ext->type == EXT_KCFG) {
-				insn[0].src_reg = BPF_PSEUDO_MAP_VALUE;
-				insn[0].imm = obj->maps[obj->kconfig_map_idx].fd;
+				if (kernel_supports(FEAT_FD_IDX)) {
+					insn[0].src_reg = BPF_PSEUDO_MAP_IDX_VALUE;
+					insn[0].imm = obj->kconfig_map_idx;
+				} else {
+					insn[0].src_reg = BPF_PSEUDO_MAP_VALUE;
+					insn[0].imm = obj->maps[obj->kconfig_map_idx].fd;
+				}
 				insn[1].imm = ext->kcfg.data_off;
 			} else /* EXT_KSYM */ {
 				if (ext->ksym.type_id) { /* typed ksyms */
@@ -7106,6 +7150,7 @@ load_program(struct bpf_program *prog, struct bpf_insn *insns, int insns_cnt,
 	load_attr.attach_btf_id = prog->attach_btf_id;
 	load_attr.kern_version = kern_version;
 	load_attr.prog_ifindex = prog->prog_ifindex;
+	load_attr.fd_array = prog->fd_array;
 
 	/* specify func_info/line_info only if kernel supports them */
 	btf_fd = bpf_object__btf_fd(prog->obj);
@@ -7296,6 +7341,7 @@ static int
 bpf_object__load_progs(struct bpf_object *obj, int log_level)
 {
 	struct bpf_program *prog;
+	int *fd_array = NULL;
 	size_t i;
 	int err;
 
@@ -7306,6 +7352,14 @@ bpf_object__load_progs(struct bpf_object *obj, int log_level)
 			return err;
 	}
 
+	if (kernel_supports(FEAT_FD_IDX) && obj->nr_maps) {
+		fd_array = malloc(sizeof(int) * obj->nr_maps);
+		if (!fd_array)
+			return -ENOMEM;
+		for (i = 0; i < obj->nr_maps; i++)
+			fd_array[i] = obj->maps[i].fd;
+	}
+
 	for (i = 0; i < obj->nr_programs; i++) {
 		prog = &obj->programs[i];
 		if (prog_is_subprog(obj, prog))
@@ -7315,10 +7369,15 @@ bpf_object__load_progs(struct bpf_object *obj, int log_level)
 			continue;
 		}
 		prog->log_level |= log_level;
+		prog->fd_array = fd_array;
 		err = bpf_program__load(prog, obj->license, obj->kern_version);
-		if (err)
+		prog->fd_array = NULL;
+		if (err) {
+			free(fd_array);
 			return err;
+		}
 	}
+	free(fd_array);
 	return 0;
 }
 
diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_internal.h
index ee426226928f..2d4f4a995f35 100644
--- a/tools/lib/bpf/libbpf_internal.h
+++ b/tools/lib/bpf/libbpf_internal.h
@@ -249,6 +249,7 @@ struct bpf_prog_load_params {
 	__u32 log_level;
 	char *log_buf;
 	size_t log_buf_sz;
+	int *fd_array;
 };
 
 int libbpf__bpf_prog_load(const struct bpf_prog_load_params *load_attr);
-- 
2.30.2


  parent reply	other threads:[~2021-05-08  3:49 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-08  3:48 [PATCH v4 bpf-next 00/22] bpf: syscall program, FD array, loader program, light skeleton Alexei Starovoitov
2021-05-08  3:48 ` [PATCH v4 bpf-next 01/22] bpf: Introduce bpf_sys_bpf() helper and program type Alexei Starovoitov
2021-05-08  3:48 ` [PATCH v4 bpf-next 02/22] bpf: Introduce bpfptr_t user/kernel pointer Alexei Starovoitov
2021-05-11 22:23   ` Andrii Nakryiko
2021-05-08  3:48 ` [PATCH v4 bpf-next 03/22] bpf: Prepare bpf syscall to be used from kernel and user space Alexei Starovoitov
2021-05-11 22:31   ` Andrii Nakryiko
2021-05-08  3:48 ` [PATCH v4 bpf-next 04/22] libbpf: Support for syscall program type Alexei Starovoitov
2021-05-08  3:48 ` [PATCH v4 bpf-next 05/22] selftests/bpf: Test " Alexei Starovoitov
2021-05-11 22:36   ` Andrii Nakryiko
2021-05-11 22:44     ` Andrii Nakryiko
2021-05-08  3:48 ` [PATCH v4 bpf-next 06/22] bpf: Make btf_load command to be bpfptr_t compatible Alexei Starovoitov
2021-05-11 22:41   ` Andrii Nakryiko
2021-05-08  3:48 ` [PATCH v4 bpf-next 07/22] selftests/bpf: Test for btf_load command Alexei Starovoitov
2021-05-11 22:45   ` Andrii Nakryiko
2021-05-12  4:04     ` Alexei Starovoitov
2021-05-12 18:00       ` Andrii Nakryiko
2021-05-08  3:48 ` [PATCH v4 bpf-next 08/22] bpf: Introduce fd_idx Alexei Starovoitov
2021-05-11 22:47   ` Andrii Nakryiko
2021-05-08  3:48 ` Alexei Starovoitov [this message]
2021-05-11 22:57   ` [PATCH v4 bpf-next 09/22] libbpf: Support for fd_idx Andrii Nakryiko
2021-05-08  3:48 ` [PATCH v4 bpf-next 10/22] bpf: Add bpf_btf_find_by_name_kind() helper Alexei Starovoitov
2021-05-11 23:02   ` Andrii Nakryiko
2021-05-08  3:48 ` [PATCH v4 bpf-next 11/22] bpf: Add bpf_sys_close() helper Alexei Starovoitov
2021-05-08  3:48 ` [PATCH v4 bpf-next 12/22] libbpf: Change the order of data and text relocations Alexei Starovoitov
2021-05-11 23:06   ` Andrii Nakryiko
2021-05-08  3:48 ` [PATCH v4 bpf-next 13/22] libbpf: Add bpf_object pointer to kernel_supports() Alexei Starovoitov
2021-05-08  3:48 ` [PATCH v4 bpf-next 14/22] libbpf: Generate loader program out of BPF ELF file Alexei Starovoitov
2021-05-11 23:22   ` Andrii Nakryiko
2021-05-08  3:48 ` [PATCH v4 bpf-next 15/22] libbpf: Use fd_array only with gen_loader Alexei Starovoitov
2021-05-11 23:24   ` Andrii Nakryiko
2021-05-12  4:17     ` Alexei Starovoitov
2021-05-12 18:11       ` Andrii Nakryiko
2021-05-08  3:48 ` [PATCH v4 bpf-next 16/22] libbpf: Cleanup temp FDs when intermediate sys_bpf fails Alexei Starovoitov
2021-05-11 23:34   ` Andrii Nakryiko
2021-05-12  4:33     ` Alexei Starovoitov
2021-05-08  3:48 ` [PATCH v4 bpf-next 17/22] libbpf: Introduce bpf_map__get_initial_value() Alexei Starovoitov
2021-05-11 23:39   ` Andrii Nakryiko
2021-05-08  3:48 ` [PATCH v4 bpf-next 18/22] bpftool: Use syscall/loader program in "prog load" and "gen skeleton" command Alexei Starovoitov
2021-05-12  4:17   ` Andrii Nakryiko
2021-05-12 18:43     ` Alexei Starovoitov
2021-05-12 18:55       ` Andrii Nakryiko
2021-05-08  3:48 ` [PATCH v4 bpf-next 19/22] selftests/bpf: Convert few tests to light skeleton Alexei Starovoitov
2021-05-12  4:19   ` Andrii Nakryiko
2021-05-08  3:48 ` [PATCH v4 bpf-next 20/22] selftests/bpf: Convert atomics test " Alexei Starovoitov
2021-05-12  4:21   ` Andrii Nakryiko
2021-05-08  3:48 ` [PATCH v4 bpf-next 21/22] selftests/bpf: Convert test printk to use rodata Alexei Starovoitov
2021-05-12  4:23   ` Andrii Nakryiko
2021-05-08  3:48 ` [PATCH v4 bpf-next 22/22] selftests/bpf: Convert test trace_printk to lskel Alexei Starovoitov
2021-05-12  4:24   ` Andrii Nakryiko

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=20210508034837.64585-10-alexei.starovoitov@gmail.com \
    --to=alexei.starovoitov@gmail.com \
    --cc=andrii@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=john.fastabend@gmail.com \
    --cc=kernel-team@fb.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.