From: Andrii Nakryiko <andrii@kernel.org>
To: <bpf@vger.kernel.org>, <ast@kernel.org>, <daniel@iogearbox.net>,
<martin.lau@kernel.org>
Cc: <andrii@kernel.org>, <kernel-team@meta.com>,
Jiri Olsa <jolsa@kernel.org>
Subject: [PATCH v2 bpf-next 6/9] libbpf: move exception callbacks assignment logic into relocation step
Date: Tue, 2 Jan 2024 11:00:52 -0800 [thread overview]
Message-ID: <20240102190055.1602698-7-andrii@kernel.org> (raw)
In-Reply-To: <20240102190055.1602698-1-andrii@kernel.org>
Move the logic of finding and assigning exception callback indices from
BTF sanitization step to program relocations step, which seems more
logical and will unblock moving BTF loading to after relocation step.
Exception callbacks discovery and assignment has no dependency on BTF
being loaded into the kernel, it only uses BTF information. It does need
to happen before subprogram relocations happen, though. Which is why the
split.
No functional changes.
Acked-by: Jiri Olsa <jolsa@kernel.org>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
---
tools/lib/bpf/libbpf.c | 165 +++++++++++++++++++++--------------------
1 file changed, 85 insertions(+), 80 deletions(-)
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index e0085aef17d7..d44aea1cc428 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -3172,86 +3172,6 @@ static int bpf_object_sanitize_and_load_btf(struct bpf_object *obj)
}
}
- if (!kernel_supports(obj, FEAT_BTF_DECL_TAG))
- goto skip_exception_cb;
- for (i = 0; i < obj->nr_programs; i++) {
- struct bpf_program *prog = &obj->programs[i];
- int j, k, n;
-
- if (prog_is_subprog(obj, prog))
- continue;
- n = btf__type_cnt(obj->btf);
- for (j = 1; j < n; j++) {
- const char *str = "exception_callback:", *name;
- size_t len = strlen(str);
- struct btf_type *t;
-
- t = btf_type_by_id(obj->btf, j);
- if (!btf_is_decl_tag(t) || btf_decl_tag(t)->component_idx != -1)
- continue;
-
- name = btf__str_by_offset(obj->btf, t->name_off);
- if (strncmp(name, str, len))
- continue;
-
- t = btf_type_by_id(obj->btf, t->type);
- if (!btf_is_func(t) || btf_func_linkage(t) != BTF_FUNC_GLOBAL) {
- pr_warn("prog '%s': exception_callback:<value> decl tag not applied to the main program\n",
- prog->name);
- return -EINVAL;
- }
- if (strcmp(prog->name, btf__str_by_offset(obj->btf, t->name_off)))
- continue;
- /* Multiple callbacks are specified for the same prog,
- * the verifier will eventually return an error for this
- * case, hence simply skip appending a subprog.
- */
- if (prog->exception_cb_idx >= 0) {
- prog->exception_cb_idx = -1;
- break;
- }
-
- name += len;
- if (str_is_empty(name)) {
- pr_warn("prog '%s': exception_callback:<value> decl tag contains empty value\n",
- prog->name);
- return -EINVAL;
- }
-
- for (k = 0; k < obj->nr_programs; k++) {
- struct bpf_program *subprog = &obj->programs[k];
-
- if (!prog_is_subprog(obj, subprog))
- continue;
- if (strcmp(name, subprog->name))
- continue;
- /* Enforce non-hidden, as from verifier point of
- * view it expects global functions, whereas the
- * mark_btf_static fixes up linkage as static.
- */
- if (!subprog->sym_global || subprog->mark_btf_static) {
- pr_warn("prog '%s': exception callback %s must be a global non-hidden function\n",
- prog->name, subprog->name);
- return -EINVAL;
- }
- /* Let's see if we already saw a static exception callback with the same name */
- if (prog->exception_cb_idx >= 0) {
- pr_warn("prog '%s': multiple subprogs with same name as exception callback '%s'\n",
- prog->name, subprog->name);
- return -EINVAL;
- }
- prog->exception_cb_idx = k;
- break;
- }
-
- if (prog->exception_cb_idx >= 0)
- continue;
- pr_warn("prog '%s': cannot find exception callback '%s'\n", prog->name, name);
- return -ENOENT;
- }
- }
-skip_exception_cb:
-
sanitize = btf_needs_sanitization(obj);
if (sanitize) {
const void *raw_data;
@@ -6628,6 +6548,88 @@ static void bpf_object_sort_relos(struct bpf_object *obj)
}
}
+static int bpf_prog_assign_exc_cb(struct bpf_object *obj, struct bpf_program *prog)
+{
+ const char *str = "exception_callback:";
+ size_t pfx_len = strlen(str);
+ int i, j, n;
+
+ if (!obj->btf || !kernel_supports(obj, FEAT_BTF_DECL_TAG))
+ return 0;
+
+ n = btf__type_cnt(obj->btf);
+ for (i = 1; i < n; i++) {
+ const char *name;
+ struct btf_type *t;
+
+ t = btf_type_by_id(obj->btf, i);
+ if (!btf_is_decl_tag(t) || btf_decl_tag(t)->component_idx != -1)
+ continue;
+
+ name = btf__str_by_offset(obj->btf, t->name_off);
+ if (strncmp(name, str, pfx_len) != 0)
+ continue;
+
+ t = btf_type_by_id(obj->btf, t->type);
+ if (!btf_is_func(t) || btf_func_linkage(t) != BTF_FUNC_GLOBAL) {
+ pr_warn("prog '%s': exception_callback:<value> decl tag not applied to the main program\n",
+ prog->name);
+ return -EINVAL;
+ }
+ if (strcmp(prog->name, btf__str_by_offset(obj->btf, t->name_off)) != 0)
+ continue;
+ /* Multiple callbacks are specified for the same prog,
+ * the verifier will eventually return an error for this
+ * case, hence simply skip appending a subprog.
+ */
+ if (prog->exception_cb_idx >= 0) {
+ prog->exception_cb_idx = -1;
+ break;
+ }
+
+ name += pfx_len;
+ if (str_is_empty(name)) {
+ pr_warn("prog '%s': exception_callback:<value> decl tag contains empty value\n",
+ prog->name);
+ return -EINVAL;
+ }
+
+ for (j = 0; j < obj->nr_programs; j++) {
+ struct bpf_program *subprog = &obj->programs[j];
+
+ if (!prog_is_subprog(obj, subprog))
+ continue;
+ if (strcmp(name, subprog->name) != 0)
+ continue;
+ /* Enforce non-hidden, as from verifier point of
+ * view it expects global functions, whereas the
+ * mark_btf_static fixes up linkage as static.
+ */
+ if (!subprog->sym_global || subprog->mark_btf_static) {
+ pr_warn("prog '%s': exception callback %s must be a global non-hidden function\n",
+ prog->name, subprog->name);
+ return -EINVAL;
+ }
+ /* Let's see if we already saw a static exception callback with the same name */
+ if (prog->exception_cb_idx >= 0) {
+ pr_warn("prog '%s': multiple subprogs with same name as exception callback '%s'\n",
+ prog->name, subprog->name);
+ return -EINVAL;
+ }
+ prog->exception_cb_idx = j;
+ break;
+ }
+
+ if (prog->exception_cb_idx >= 0)
+ continue;
+
+ pr_warn("prog '%s': cannot find exception callback '%s'\n", prog->name, name);
+ return -ENOENT;
+ }
+
+ return 0;
+}
+
static int
bpf_object_relocate(struct bpf_object *obj, const char *targ_btf_path)
{
@@ -6688,6 +6690,9 @@ bpf_object_relocate(struct bpf_object *obj, const char *targ_btf_path)
return err;
}
+ err = bpf_prog_assign_exc_cb(obj, prog);
+ if (err)
+ return err;
/* Now, also append exception callback if it has not been done already. */
if (prog->exception_cb_idx >= 0) {
struct bpf_program *subprog = &obj->programs[prog->exception_cb_idx];
--
2.34.1
next prev parent reply other threads:[~2024-01-02 19:01 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-01-02 19:00 [PATCH v2 bpf-next 0/9] Libbpf-side __arg_ctx fallback support Andrii Nakryiko
2024-01-02 19:00 ` [PATCH v2 bpf-next 1/9] libbpf: name internal functions consistently Andrii Nakryiko
2024-01-03 23:12 ` Alexei Starovoitov
2024-01-03 23:17 ` Eduard Zingerman
2024-01-04 0:30 ` Andrii Nakryiko
2024-01-02 19:00 ` [PATCH v2 bpf-next 2/9] libbpf: make uniform use of btf__fd() accessor inside libbpf Andrii Nakryiko
2024-01-02 19:00 ` [PATCH v2 bpf-next 3/9] libbpf: use explicit map reuse flag to skip map creation steps Andrii Nakryiko
2024-01-02 19:00 ` [PATCH v2 bpf-next 4/9] libbpf: don't rely on map->fd as an indicator of map being created Andrii Nakryiko
2024-01-02 19:00 ` [PATCH v2 bpf-next 5/9] libbpf: use stable map placeholder FDs Andrii Nakryiko
2024-01-03 20:57 ` Eduard Zingerman
2024-01-03 22:46 ` Andrii Nakryiko
2024-01-02 19:00 ` Andrii Nakryiko [this message]
2024-01-02 19:00 ` [PATCH v2 bpf-next 7/9] libbpf: move BTF loading step after relocation step Andrii Nakryiko
2024-01-02 19:00 ` [PATCH v2 bpf-next 8/9] libbpf: implement __arg_ctx fallback logic Andrii Nakryiko
2024-01-03 20:57 ` Eduard Zingerman
2024-01-03 23:10 ` Andrii Nakryiko
2024-01-03 23:43 ` Eduard Zingerman
2024-01-03 23:59 ` Andrii Nakryiko
2024-01-04 0:09 ` Eduard Zingerman
2024-01-04 0:27 ` Andrii Nakryiko
2024-01-02 19:00 ` [PATCH v2 bpf-next 9/9] selftests/bpf: add arg:ctx cases to test_global_funcs tests Andrii Nakryiko
2024-01-03 20:57 ` Eduard Zingerman
2024-01-03 23:17 ` Andrii Nakryiko
2024-01-03 23:51 ` Eduard Zingerman
2024-01-04 0:26 ` Andrii Nakryiko
2024-01-04 0:28 ` Eduard Zingerman
2024-01-02 19:57 ` [PATCH v2 bpf-next 0/9] Libbpf-side __arg_ctx fallback support Andrii Nakryiko
2024-01-03 20:57 ` Eduard Zingerman
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=20240102190055.1602698-7-andrii@kernel.org \
--to=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=jolsa@kernel.org \
--cc=kernel-team@meta.com \
--cc=martin.lau@kernel.org \
/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