[PATCH bpf-next 04/13] bpf: move bpf_get_btf_vmlinux() to btf.c

From: Jay Wang

Date: Sat Oct 31 2026 - 09:12:46 EST


From: Ihor Solodrai <ihor.solodrai@xxxxxxxxx>

Move bpf_get_btf_vmlinux(), bpf_peek_btf_vmlinux() and btf_vmlinux_lock
from verifier.c to btf.c, next to btf_parse_vmlinux().

Parsing the vmlinux BTF on first use (later in this series) makes the
accessor apply deferred kfunc, dtor kfunc and struct_ops registrations
and kept module BTF under btf_vmlinux_lock. That state lives in btf.c;
with the accessor and its lock there, it can stay static.

No functional change.

TODO-NEEDS-IHOR: Signed-off-by: Ihor Solodrai <ihor.solodrai@xxxxxxxxx>
Signed-off-by: Jay Wang <wanjay@xxxxxxxxxx>
---
kernel/bpf/btf.c | 32 ++++++++++++++++++++++++++++++++
kernel/bpf/verifier.c | 31 -------------------------------
2 files changed, 32 insertions(+), 31 deletions(-)

diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 1c7536a22a63..58d8b21d9895 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -6924,6 +6924,38 @@ struct btf *btf_parse_vmlinux(void)
return btf;
}

+static DEFINE_MUTEX(btf_vmlinux_lock);
+
+struct btf *bpf_get_btf_vmlinux(void)
+{
+ /* Pairs with the smp_store_release() on the parse path below. */
+ struct btf *btf = smp_load_acquire(&btf_vmlinux);
+
+ if (!btf && IS_ENABLED(CONFIG_DEBUG_INFO_BTF)) {
+ mutex_lock(&btf_vmlinux_lock);
+ btf = btf_vmlinux;
+ if (!btf) {
+ btf = btf_parse_vmlinux();
+ /*
+ * Order the parsed BTF contents and the globals the
+ * parse populated (e.g. bpf_ctx_convert.t) before
+ * the pointer publication. Pairs with the acquire
+ * on the lockless fast path above.
+ */
+ smp_store_release(&btf_vmlinux, btf);
+ }
+ mutex_unlock(&btf_vmlinux_lock);
+ }
+ return btf;
+}
+
+/* The vmlinux BTF if it is parsed already: for callers that cannot sleep */
+struct btf *bpf_peek_btf_vmlinux(void)
+{
+ /* Pairs with the smp_store_release() in bpf_get_btf_vmlinux() */
+ return smp_load_acquire(&btf_vmlinux);
+}
+
/* If .BTF_ids section was created with distilled base BTF, both base and
* split BTF ids will need to be mapped to actual base/split ids for
* BTF now that it has been relocated.
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 1b901e3cb3c2..e1514a0c2289 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -317,7 +317,6 @@ static const char *btf_type_name(const struct btf *btf, u32 id)
}

static DEFINE_MUTEX(bpf_verifier_lock);
-static DEFINE_MUTEX(btf_vmlinux_lock);
static DEFINE_MUTEX(bpf_percpu_ma_lock);

__printf(2, 3) static void verbose(void *private_data, const char *fmt, ...)
@@ -23144,36 +23143,6 @@ int bpf_check_attach_btf_id_multi(struct btf *btf, struct bpf_prog *prog, u32 bt
return 0;
}

-struct btf *bpf_get_btf_vmlinux(void)
-{
- /* Pairs with the smp_store_release() on the parse path below. */
- struct btf *btf = smp_load_acquire(&btf_vmlinux);
-
- if (!btf && IS_ENABLED(CONFIG_DEBUG_INFO_BTF)) {
- mutex_lock(&btf_vmlinux_lock);
- btf = btf_vmlinux;
- if (!btf) {
- btf = btf_parse_vmlinux();
- /*
- * Order the parsed BTF contents and the globals the
- * parse populated (e.g. bpf_ctx_convert.t) before
- * the pointer publication. Pairs with the acquire
- * on the lockless fast path above.
- */
- smp_store_release(&btf_vmlinux, btf);
- }
- mutex_unlock(&btf_vmlinux_lock);
- }
- return btf;
-}
-
-/* The vmlinux BTF if it is parsed already: for callers that cannot sleep */
-struct btf *bpf_peek_btf_vmlinux(void)
-{
- /* Pairs with the smp_store_release() in bpf_get_btf_vmlinux() */
- return smp_load_acquire(&btf_vmlinux);
-}
-
/*
* The add_fd_from_fd_array() is executed only if fd_array_cnt is non-zero. In
* this case expect that every file descriptor in the array is either a map or
--
2.47.3