bpf.vger.kernel.org archive mirror
 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, lmb@cloudflare.com,
	mcroce@microsoft.com, bpf@vger.kernel.org, kernel-team@fb.com
Subject: [PATCH RFC bpf-next 05/10] libbpf: Use CO-RE in the kernel in light skeleton.
Date: Fri, 17 Sep 2021 14:57:16 -0700	[thread overview]
Message-ID: <20210917215721.43491-6-alexei.starovoitov@gmail.com> (raw)
In-Reply-To: <20210917215721.43491-1-alexei.starovoitov@gmail.com>

From: Alexei Starovoitov <ast@kernel.org>

Signed-off-by: Alexei Starovoitov <ast@kernel.org>
---
 tools/lib/bpf/bpf_gen_internal.h | 12 ++++++++
 tools/lib/bpf/gen_loader.c       | 47 ++++++++++++++++++++++++++++++++
 tools/lib/bpf/libbpf.c           | 27 +++++++++++++++---
 3 files changed, 82 insertions(+), 4 deletions(-)

diff --git a/tools/lib/bpf/bpf_gen_internal.h b/tools/lib/bpf/bpf_gen_internal.h
index 615400391e57..1b27faf71080 100644
--- a/tools/lib/bpf/bpf_gen_internal.h
+++ b/tools/lib/bpf/bpf_gen_internal.h
@@ -9,6 +9,13 @@ struct ksym_relo_desc {
 	int insn_idx;
 };
 
+struct core_relo_desc {
+	__u32   insn_idx;
+	__u32   type_id;
+	__u32   access_str_off;
+	__u32	kind;
+};
+
 struct bpf_gen {
 	struct gen_loader_opts *opts;
 	void *data_start;
@@ -22,6 +29,8 @@ struct bpf_gen {
 	int error;
 	struct ksym_relo_desc *relos;
 	int relo_cnt;
+	struct core_relo_desc *core_relos;
+	int core_relo_cnt;
 	char attach_target[128];
 	int attach_kind;
 };
@@ -37,5 +46,8 @@ void bpf_gen__map_update_elem(struct bpf_gen *gen, int map_idx, void *value, __u
 void bpf_gen__map_freeze(struct bpf_gen *gen, int map_idx);
 void bpf_gen__record_attach_target(struct bpf_gen *gen, const char *name, enum bpf_attach_type type);
 void bpf_gen__record_extern(struct bpf_gen *gen, const char *name, int kind, int insn_idx);
+struct bpf_core_relo;
+void bpf_gen__record_relo_core(struct bpf_gen *gen, const struct bpf_core_relo *core_relo,
+			       int insn_idx);
 
 #endif
diff --git a/tools/lib/bpf/gen_loader.c b/tools/lib/bpf/gen_loader.c
index 8df718a6b142..fe2415ab53f6 100644
--- a/tools/lib/bpf/gen_loader.c
+++ b/tools/lib/bpf/gen_loader.c
@@ -524,6 +524,23 @@ void bpf_gen__record_extern(struct bpf_gen *gen, const char *name, int kind,
 	gen->relo_cnt++;
 }
 
+void bpf_gen__record_relo_core(struct bpf_gen *gen, const struct bpf_core_relo *core_relo,
+			       int insn_idx)
+{
+	struct core_relo_desc *relo;
+
+	relo = libbpf_reallocarray(gen->core_relos, gen->core_relo_cnt + 1, sizeof(*relo));
+	if (!relo) {
+		gen->error = -ENOMEM;
+		return;
+	}
+	gen->core_relos = relo;
+	relo += gen->core_relo_cnt;
+	memcpy(relo, core_relo, sizeof(*relo));
+	relo->insn_idx = insn_idx;
+	gen->core_relo_cnt++;
+}
+
 static void emit_relo(struct bpf_gen *gen, struct ksym_relo_desc *relo, int insns)
 {
 	int name, insn, len = strlen(relo->name) + 1;
@@ -554,12 +571,37 @@ static void emit_relo(struct bpf_gen *gen, struct ksym_relo_desc *relo, int insn
 	}
 }
 
+static void emit_core_relo(struct bpf_gen *gen, struct core_relo_desc *relo, int insns)
+{
+	int relo_off, insn, len = sizeof(*relo) - 4;
+
+	pr_debug("gen: relo_core: local_btf_id %d kind %d at %d\n",
+		 relo->type_id, relo->kind, relo->insn_idx);
+	relo_off = add_data(gen, &relo->type_id, len);
+
+	emit(gen, BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_10, stack_off(btf_fd)));
+	emit2(gen, BPF_LD_IMM64_RAW_FULL(BPF_REG_2, BPF_PSEUDO_MAP_IDX_VALUE,
+					 0, 0, 0, relo_off));
+	emit(gen, BPF_MOV64_IMM(BPF_REG_3, len));
+	insn = insns + sizeof(struct bpf_insn) * relo->insn_idx;
+	emit2(gen, BPF_LD_IMM64_RAW_FULL(BPF_REG_4, BPF_PSEUDO_MAP_IDX_VALUE,
+					 0, 0, 0, insn));
+	emit(gen, BPF_MOV64_IMM(BPF_REG_5, 0));
+	emit(gen, BPF_EMIT_CALL(BPF_FUNC_core_apply_relo));
+	emit(gen, BPF_MOV64_REG(BPF_REG_7, BPF_REG_0));
+	debug_ret(gen, "core_apply_relo(btf_id=%d,kind=%d,insn=%d)",
+		  relo->type_id, relo->kind, relo->insn_idx);
+	emit_check_err(gen);
+}
+
 static void emit_relos(struct bpf_gen *gen, int insns)
 {
 	int i;
 
 	for (i = 0; i < gen->relo_cnt; i++)
 		emit_relo(gen, gen->relos + i, insns);
+	for (i = 0; i < gen->core_relo_cnt; i++)
+		emit_core_relo(gen, gen->core_relos + i, insns);
 }
 
 static void cleanup_relos(struct bpf_gen *gen, int insns)
@@ -580,6 +622,11 @@ static void cleanup_relos(struct bpf_gen *gen, int insns)
 		gen->relo_cnt = 0;
 		gen->relos = NULL;
 	}
+	if (gen->core_relo_cnt) {
+		free(gen->core_relos);
+		gen->core_relo_cnt = 0;
+		gen->core_relos = NULL;
+	}
 }
 
 void bpf_gen__prog_load(struct bpf_gen *gen,
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index bc023b6a6d87..ed2c4f6661fe 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -5175,10 +5175,17 @@ static int bpf_core_apply_relo(struct bpf_program *prog,
 		return -EINVAL;
 
 	if (prog->obj->gen_loader) {
-		pr_warn("// TODO core_relo: prog %td insn[%d] %s kind %d\n",
+		const char *spec_str = btf__name_by_offset(local_btf, relo->access_str_off);
+
+		/* Adjust relo_core's insn_idx since final subprog offset in
+		 * the main prog is known.
+		 */
+		insn_idx += prog->sub_insn_off;
+		pr_debug("record_relo_core: prog %td insn[%d] %s %s %s final insn_idx %d\n",
 			prog - prog->obj->programs, relo->insn_off / 8,
-			local_name, relo->kind);
-		return -ENOTSUP;
+			btf_kind_str(local_type), local_name, spec_str, insn_idx);
+		bpf_gen__record_relo_core(prog->obj->gen_loader, relo, insn_idx);
+		return 0;
 	}
 
 	if (relo->kind != BPF_CORE_TYPE_ID_LOCAL &&
@@ -5813,7 +5820,7 @@ bpf_object__relocate(struct bpf_object *obj, const char *targ_btf_path)
 	size_t i, j;
 	int err;
 
-	if (obj->btf_ext) {
+	if (obj->btf_ext && !obj->gen_loader) {
 		err = bpf_object__relocate_core(obj, targ_btf_path);
 		if (err) {
 			pr_warn("failed to perform CO-RE relocations: %d\n",
@@ -5863,6 +5870,18 @@ bpf_object__relocate(struct bpf_object *obj, const char *targ_btf_path)
 			return err;
 		}
 	}
+
+	/* Let gen_loader record CO-RE relocations after subprogs were appended
+	 * to make sure that insn_idx is calculated as the offset in main progs.
+	 */
+	if (obj->btf_ext && obj->gen_loader) {
+		err = bpf_object__relocate_core(obj, targ_btf_path);
+		if (err) {
+			pr_warn("failed to perform CO-RE relocations: %d\n",
+				err);
+			return err;
+		}
+	}
 	/* Process data relos for main programs */
 	for (i = 0; i < obj->nr_programs; i++) {
 		prog = &obj->programs[i];
-- 
2.30.2


  parent reply	other threads:[~2021-09-17 21:57 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-17 21:57 [PATCH RFC bpf-next 00/10] bpf: CO-RE support in the kernel Alexei Starovoitov
2021-09-17 21:57 ` [PATCH RFC bpf-next 01/10] bpf: Prepare relo_core.c for kernel duty Alexei Starovoitov
2021-09-21 21:25   ` Andrii Nakryiko
2021-09-28 14:45   ` Matteo Croce
2021-09-28 16:37     ` Alexei Starovoitov
2021-09-28 17:11       ` Matteo Croce
2021-09-28 20:34         ` Alexei Starovoitov
2021-09-29 12:32           ` Matteo Croce
2021-09-29 17:38             ` Matteo Croce
2021-09-29 23:00               ` Alexei Starovoitov
2021-09-29 23:49                 ` Matteo Croce
2021-10-22  0:48                   ` Matteo Croce
2021-10-22  0:51                     ` Alexei Starovoitov
2021-09-17 21:57 ` [PATCH RFC bpf-next 02/10] bpf: Define enum bpf_core_relo_kind as uapi Alexei Starovoitov
2021-09-21 21:27   ` Andrii Nakryiko
2021-09-17 21:57 ` [PATCH RFC bpf-next 03/10] bpf: Add proto of bpf_core_apply_relo() Alexei Starovoitov
2021-09-23 11:21   ` Lorenz Bauer
2021-09-23 18:48     ` Andrii Nakryiko
2021-09-17 21:57 ` [PATCH RFC bpf-next 04/10] bpf: Add bpf_core_add_cands() and wire it into bpf_core_apply_relo_insn() Alexei Starovoitov
2021-09-21 21:34   ` Andrii Nakryiko
2021-09-27 18:04   ` Matteo Croce
2021-09-17 21:57 ` Alexei Starovoitov [this message]
2021-09-17 21:57 ` [PATCH RFC bpf-next 06/10] libbpf: Make gen_loader data aligned Alexei Starovoitov
2021-09-17 21:57 ` [PATCH RFC bpf-next 07/10] libbpf: Support init of inner maps in light skeleton Alexei Starovoitov
2021-09-17 21:57 ` [PATCH RFC bpf-next 08/10] selftests/bpf: Convert kfunc test with CO-RE to lskel Alexei Starovoitov
2021-09-17 21:57 ` [PATCH RFC bpf-next 09/10] selftests/bpf: Improve inner_map test coverage Alexei Starovoitov
2021-09-17 21:57 ` [PATCH RFC bpf-next 10/10] selftests/bpf: Convert map_ptr_kern test to use light skeleton Alexei Starovoitov
2021-09-23 11:33 ` [PATCH RFC bpf-next 00/10] bpf: CO-RE support in the kernel Lorenz Bauer
2021-09-23 18:52   ` Andrii Nakryiko
2021-09-24 23:13   ` Alexei Starovoitov
2021-09-27 16:12     ` Lorenz Bauer
2021-09-27 16:50       ` Alexei Starovoitov
2021-09-28  8:30         ` Lorenz Bauer
2021-09-28 16:35           ` Alexei Starovoitov

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=20210917215721.43491-6-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 \
    --cc=lmb@cloudflare.com \
    --cc=mcroce@microsoft.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 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).