BPF List
 help / color / mirror / Atom feed
* [PATCH bpf-next v2 0/6] resolve_btfids: Implement BTF tags emission for kfuncs
@ 2026-08-05 23:06 Ihor Solodrai
  2026-08-05 23:06 ` [PATCH bpf-next v2 1/6] resolve_btfids: Deduplicate BTF after btf2btf transformations Ihor Solodrai
                   ` (5 more replies)
  0 siblings, 6 replies; 27+ messages in thread
From: Ihor Solodrai @ 2026-08-05 23:06 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Kumar Kartikeya Dwivedi
  Cc: Alan Maguire, Jiri Olsa, Emil Tsalapatis, bpf

BTF data for the kernel is generated through the following pipeline:
  * DWARF is emitted by the compiler
  * pahole reads in DWARF and produces BTF
  * resolve_btfids makes kernel-specific btf2btf transformation and
    patches .BTF_ids section

This is orchestrated by link-vmlinux.sh, gen-btf.sh and Makefile.btf
in ./scripts directory.

Historically kernel-specific BTF features were implemented in pahole,
and controlled by the feature flags. This requires kernel build
process to be aware of pahole version used for the build to set
correct runtime arguments for BTF encoding [1].

This is a burden which can be alleviated by splitting kernel/module
BTF generation in two stages:
  1. Generic BTF generation from the kernel source code.
  2. Kernel-specific BTF modifications to support various BPF features.

So far both stages were fused in pahole's BTF encoding. By moving
stage (2) in-tree, the dependency of kernel build on pahole can become
much more loose.

resolve_btfids is already responsible for a few kernel-specific BTF
modifications:
  * .BTF.base generation for modules [2]
  * BTF sorting [3]
  * KF_IMPLICIT_ARGS support [4]

This series completes the migration by emitting BTF kfunc annotations
in-tree: the "bpf_kfunc" and "bpf_fastcall" decl tags and the arena
"address_space(1)" type attribute, dropping the corresponding pahole
feature flags.

The three annotations depend on two pahole feature flags:
"decl_tag_kfuncs" and "attributes".  Since emission is unconditional,
each flag has to be dropped in the same commit as the emission that
replaces it.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/scripts/Makefile.btf?h=v7.1-rc5
[2] https://docs.kernel.org/bpf/btf.html#btf-base-section
[3] https://lore.kernel.org/bpf/20260109130003.3313716-4-dolinux.peng@gmail.com/
[4] https://lore.kernel.org/bpf/20260120222638.3976562-1-ihor.solodrai@linux.dev/
[5] https://lore.kernel.org/bpf/20260722233518.778854-1-ihor.solodrai@linux.dev/
[6] https://lore.kernel.org/bpf/20260617210619.1562858-1-ihor.solodrai@linux.dev/

---

v1->v2:
  * The bottom part of v1 has already been landed [5][6].
  * New patch #1: run btf__dedup() in finalize_btf().
  * Drop the "ensure" pattern. Emission is unconditional; kbuild owns
    the pahole flags, so assume input BTF is not already tagged.
  * Each pahole flag is now dropped in the same commit as the emission
    that replaces it.
  * Fail hard with an error on invalid kfunc declarations such as an
    arena flag naming a missing argument or a non-pointer type.
  * Various cleanups and nits (Andrii, Emil, Jiri, Sashiko).
v1: https://lore.kernel.org/bpf/20260601221805.821394-1-ihor.solodrai@linux.dev/

---

Ihor Solodrai (6):
  resolve_btfids: Deduplicate BTF after btf2btf transformations
  resolve_btfids: Process KF_ARENA_* flags in resolve_btfids
  selftests/bpf: Verify arena type tags in resolve_btfids test
  resolve_btfids: Emit bpf_kfunc and bpf_fastcall decl tags
  selftests/bpf: Verify decl tags emission in resolve_btfids test
  docs, resolve_btfids: Document kfunc BTF annotation emission

 Documentation/bpf/kfuncs.rst                  |   8 +
 Documentation/process/changes.rst             |   7 +-
 scripts/Makefile.btf                          |   7 +-
 tools/bpf/resolve_btfids/main.c               | 192 +++++++++++++++++-
 .../selftests/bpf/prog_tests/resolve_btfids.c | 106 ++++++++++
 tools/testing/selftests/bpf/progs/btf_data.c  |  10 +
 6 files changed, 318 insertions(+), 12 deletions(-)

-- 
2.55.0


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

* [PATCH bpf-next v2 1/6] resolve_btfids: Deduplicate BTF after btf2btf transformations
  2026-08-05 23:06 [PATCH bpf-next v2 0/6] resolve_btfids: Implement BTF tags emission for kfuncs Ihor Solodrai
@ 2026-08-05 23:06 ` Ihor Solodrai
  2026-08-06 19:05   ` Eduard Zingerman
  2026-08-05 23:06 ` [PATCH bpf-next v2 2/6] resolve_btfids: Process KF_ARENA_* flags in resolve_btfids Ihor Solodrai
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 27+ messages in thread
From: Ihor Solodrai @ 2026-08-05 23:06 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Kumar Kartikeya Dwivedi
  Cc: Alan Maguire, Jiri Olsa, Emil Tsalapatis, bpf

btf2btf() adds new types to the BTF: the KF_IMPLICIT_ARGS transform
synthesizes an _impl FUNC together with its FUNC_PROTO and copies of the
kfunc's decl tags. Nothing deduplicates them afterwards. pahole runs
btf__dedup() on its own output, but that happens before resolve_btfids
sees the BTF, so any type the tool itself creates is emitted as-is, even
when a structurally identical type is already present.

Call btf__dedup() at the start of finalize_btf(), so that base
distillation and the by-name sort both operate on the canonical set of
types.

Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 tools/bpf/resolve_btfids/main.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
index 85488935909d..5d168c2a5ff5 100644
--- a/tools/bpf/resolve_btfids/main.c
+++ b/tools/bpf/resolve_btfids/main.c
@@ -1379,6 +1379,12 @@ static int finalize_btf(struct object *obj)
 	struct btf *base_btf = obj->base_btf, *btf = obj->btf;
 	int err;
 
+	err = btf__dedup(obj->btf, NULL);
+	if (err) {
+		pr_err("FAILED to dedup BTF: %s\n", strerror(errno));
+		goto out_err;
+	}
+
 	if (obj->base_btf && obj->distill_base) {
 		err = btf__distill_base(obj->btf, &base_btf, &btf);
 		if (err) {
-- 
2.55.0


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

* [PATCH bpf-next v2 2/6] resolve_btfids: Process KF_ARENA_* flags in resolve_btfids
  2026-08-05 23:06 [PATCH bpf-next v2 0/6] resolve_btfids: Implement BTF tags emission for kfuncs Ihor Solodrai
  2026-08-05 23:06 ` [PATCH bpf-next v2 1/6] resolve_btfids: Deduplicate BTF after btf2btf transformations Ihor Solodrai
@ 2026-08-05 23:06 ` Ihor Solodrai
  2026-08-06 19:12   ` Eduard Zingerman
  2026-08-05 23:06 ` [PATCH bpf-next v2 3/6] selftests/bpf: Verify arena type tags in resolve_btfids test Ihor Solodrai
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 27+ messages in thread
From: Ihor Solodrai @ 2026-08-05 23:06 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Kumar Kartikeya Dwivedi
  Cc: Alan Maguire, Jiri Olsa, Emil Tsalapatis, bpf

For kfuncs flagged with KF_ARENA_RET, KF_ARENA_ARG1 or KF_ARENA_ARG2,
the address_space(1) attribute (a type tag with kflag=1) must be
emitted for the corresponding type in BTF. This was previously done by
pahole via the "attributes" BTF feature [1].

Implement the emission of the arena attributes in resolve_btfids: for
flagged kfuncs create a new function prototype with updated BTF types.
The original proto may be shared with sibling FUNCs, so it is not
modified in place.

Emission is unconditional: kbuild controls the pahole flags, so the
input BTF is expected to not have these attributes. Invalid
declarations are reported as errors.

Drop the "attributes" pahole feature from scripts/Makefile.btf
resolve_btfids now emits them for all supported pahole versions.

[1] https://lore.kernel.org/dwarves/20250228194654.1022535-1-ihor.solodrai@linux.dev/

Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 scripts/Makefile.btf            |   2 -
 tools/bpf/resolve_btfids/main.c | 146 ++++++++++++++++++++++++++++++--
 2 files changed, 141 insertions(+), 7 deletions(-)

diff --git a/scripts/Makefile.btf b/scripts/Makefile.btf
index e66e13e79653..8f73c093d27a 100644
--- a/scripts/Makefile.btf
+++ b/scripts/Makefile.btf
@@ -16,8 +16,6 @@ else
 # Switch to using --btf_features for v1.26 and later.
 pahole-flags-$(call test-ge, $(pahole-ver), 126)  = -j$(JOBS) --btf_features=encode_force,var,float,enum64,decl_tag,type_tag,optimized_func,consistent_func,decl_tag_kfuncs
 
-pahole-flags-$(call test-ge, $(pahole-ver), 130) += --btf_features=attributes
-
 pahole-flags-$(call test-ge, $(pahole-ver), 131) += --btf_features=layout
 
 endif
diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
index 5d168c2a5ff5..30c7f95aa3b1 100644
--- a/tools/bpf/resolve_btfids/main.c
+++ b/tools/bpf/resolve_btfids/main.c
@@ -161,8 +161,12 @@ struct object {
 	u32 addr_syms_cap;
 };
 
+#define KF_ARENA_RET	(1 << 13)
+#define KF_ARENA_ARG1	(1 << 14)
+#define KF_ARENA_ARG2	(1 << 15)
 #define KF_IMPLICIT_ARGS (1 << 16)
 #define KF_IMPL_SUFFIX "_impl"
+#define TYPE_ATTR_ARENA "address_space(1)"
 
 struct kfunc {
 	struct rb_node rb_node;
@@ -1280,6 +1284,133 @@ static int process_kfunc_with_implicit_args(struct btf2btf_context *ctx, struct
 	return 0;
 }
 
+static s32 arena_tag_ptr(struct btf *btf, u32 ptr_id)
+{
+	const struct btf_type *ptr = btf__type_by_id(btf, ptr_id);
+	s32 tag_id;
+
+	if (!btf_is_ptr(ptr))
+		return -EINVAL;
+
+	tag_id = btf__add_type_attr(btf, TYPE_ATTR_ARENA, ptr->type);
+	if (tag_id < 0)
+		return tag_id;
+
+	return btf__add_ptr(btf, tag_id);
+}
+
+/*
+ * Add a FUNC_PROTO for @kfunc with each relevant pointer tagged with
+ * an "address_space(1)" attribute. The original proto may be shared
+ * with other FUNCs, so it is never modified in place.
+ */
+static s32 add_arena_tagged_proto(struct btf *btf, struct kfunc *kfunc)
+{
+	const struct btf_type *func = btf__type_by_id(btf, kfunc->btf_id);
+	u32 proto_id = func->type;
+	const struct btf_type *proto = btf__type_by_id(btf, proto_id);
+	const struct btf_param *params = btf_params(proto);
+	u32 nr_params = btf_vlen(proto);
+	s32 arg0_type_id = nr_params > 0 ? (s32)params[0].type : -1;
+	s32 arg1_type_id = nr_params > 1 ? (s32)params[1].type : -1;
+	s32 new_proto_id, id, param_type_id;
+	s32 ret_type_id = proto->type;
+	const char *name;
+	int err;
+
+	if (kfunc->flags & KF_ARENA_RET) {
+		id = arena_tag_ptr(btf, ret_type_id);
+		if (id < 0) {
+			pr_err("ERROR: resolve_btfids: kfunc %s: KF_ARENA_RET but return type is not a pointer\n",
+			       kfunc->name);
+			return id;
+		}
+		ret_type_id = id;
+	}
+
+	if (kfunc->flags & KF_ARENA_ARG1) {
+		if (nr_params < 1) {
+			pr_err("ERROR: resolve_btfids: kfunc %s: KF_ARENA_ARG1 but it has no argument 1\n",
+			       kfunc->name);
+			return -EINVAL;
+		}
+		id = arena_tag_ptr(btf, arg0_type_id);
+		if (id < 0) {
+			pr_err("ERROR: resolve_btfids: kfunc %s: KF_ARENA_ARG1 but argument 1 is not a pointer\n",
+			       kfunc->name);
+			return id;
+		}
+		arg0_type_id = id;
+	}
+
+	if (kfunc->flags & KF_ARENA_ARG2) {
+		if (nr_params < 2) {
+			pr_err("ERROR: resolve_btfids: kfunc %s: KF_ARENA_ARG2 but it has no argument 2\n",
+			       kfunc->name);
+			return -EINVAL;
+		}
+		id = arena_tag_ptr(btf, arg1_type_id);
+		if (id < 0) {
+			pr_err("ERROR: resolve_btfids: kfunc %s: KF_ARENA_ARG2 but argument 2 is not a pointer\n",
+			       kfunc->name);
+			return id;
+		}
+		arg1_type_id = id;
+	}
+
+	new_proto_id = btf__add_func_proto(btf, ret_type_id);
+	if (new_proto_id < 0) {
+		pr_err("ERROR: resolve_btfids: kfunc %s: failed to add a func proto to BTF\n",
+		       kfunc->name);
+		return new_proto_id;
+	}
+
+	for (u32 i = 0; i < nr_params; i++) {
+		proto = btf__type_by_id(btf, proto_id);
+		params = btf_params(proto);
+		name = btf__name_by_offset(btf, params[i].name_off);
+
+		switch (i) {
+		case 0:
+			param_type_id = arg0_type_id;
+			break;
+		case 1:
+			param_type_id = arg1_type_id;
+			break;
+		default:
+			param_type_id = params[i].type;
+			break;
+		}
+
+		err = btf__add_func_param(btf, name ?: "", param_type_id);
+		if (err < 0) {
+			pr_err("ERROR: resolve_btfids: kfunc %s: failed to add a proto param to BTF\n",
+			       kfunc->name);
+			return err;
+		}
+	}
+
+	pr_debug("added arena-tagged proto for kfunc %s: %d\n", kfunc->name, new_proto_id);
+
+	return new_proto_id;
+}
+
+static int process_kfunc_with_arena_flags(struct btf2btf_context *ctx,
+					  struct kfunc *kfunc)
+{
+	struct btf_type *t;
+	s32 proto_id;
+
+	proto_id = add_arena_tagged_proto(ctx->btf, kfunc);
+	if (proto_id < 0)
+		return proto_id;
+
+	t = (struct btf_type *)btf__type_by_id(ctx->btf, kfunc->btf_id);
+	t->type = proto_id;
+
+	return 0;
+}
+
 static int btf2btf(struct object *obj)
 {
 	struct btf2btf_context ctx = {};
@@ -1293,12 +1424,17 @@ static int btf2btf(struct object *obj)
 	for (next = rb_first(&ctx.kfuncs); next; next = rb_next(next)) {
 		struct kfunc *kfunc = rb_entry(next, struct kfunc, rb_node);
 
-		if (!(kfunc->flags & KF_IMPLICIT_ARGS))
-			continue;
+		if (kfunc->flags & KF_IMPLICIT_ARGS) {
+			err = process_kfunc_with_implicit_args(&ctx, kfunc);
+			if (err)
+				goto out;
+		}
 
-		err = process_kfunc_with_implicit_args(&ctx, kfunc);
-		if (err)
-			goto out;
+		if (kfunc->flags & (KF_ARENA_RET | KF_ARENA_ARG1 | KF_ARENA_ARG2)) {
+			err = process_kfunc_with_arena_flags(&ctx, kfunc);
+			if (err)
+				goto out;
+		}
 	}
 
 	err = 0;
-- 
2.55.0


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

* [PATCH bpf-next v2 3/6] selftests/bpf: Verify arena type tags in resolve_btfids test
  2026-08-05 23:06 [PATCH bpf-next v2 0/6] resolve_btfids: Implement BTF tags emission for kfuncs Ihor Solodrai
  2026-08-05 23:06 ` [PATCH bpf-next v2 1/6] resolve_btfids: Deduplicate BTF after btf2btf transformations Ihor Solodrai
  2026-08-05 23:06 ` [PATCH bpf-next v2 2/6] resolve_btfids: Process KF_ARENA_* flags in resolve_btfids Ihor Solodrai
@ 2026-08-05 23:06 ` Ihor Solodrai
  2026-08-05 23:17   ` sashiko-bot
  2026-08-06 19:15   ` Eduard Zingerman
  2026-08-05 23:06 ` [PATCH bpf-next v2 4/6] resolve_btfids: Emit bpf_kfunc and bpf_fastcall decl tags Ihor Solodrai
                   ` (2 subsequent siblings)
  5 siblings, 2 replies; 27+ messages in thread
From: Ihor Solodrai @ 2026-08-05 23:06 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Kumar Kartikeya Dwivedi
  Cc: Alan Maguire, Jiri Olsa, Emil Tsalapatis, bpf

Extend test_resolve_btfids() to assert that resolve_btfids emits the
address_space(1) type attribute (a BTF_KIND_TYPE_TAG with kflag=1) on
the return type and/or arguments of kfuncs marked KF_ARENA_RET,
KF_ARENA_ARG1 or KF_ARENA_ARG2.

Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 .../selftests/bpf/prog_tests/resolve_btfids.c | 66 +++++++++++++++++++
 tools/testing/selftests/bpf/progs/btf_data.c  | 10 +++
 2 files changed, 76 insertions(+)

diff --git a/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c b/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c
index ac51fd454821..8482f00046d4 100644
--- a/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c
+++ b/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c
@@ -12,9 +12,20 @@
 
 #define BTF_DATA_FILE "resolve_btfids.test.o.BTF"
 
+#define TYPE_ATTR_ARENA "address_space(1)"
+
 #ifndef KF_FASTCALL
 #define KF_FASTCALL (1 << 12)
 #endif
+#ifndef KF_ARENA_RET
+#define KF_ARENA_RET  (1 << 13)
+#endif
+#ifndef KF_ARENA_ARG1
+#define KF_ARENA_ARG1 (1 << 14)
+#endif
+#ifndef KF_ARENA_ARG2
+#define KF_ARENA_ARG2 (1 << 15)
+#endif
 
 struct symbol {
 	const char	*name;
@@ -41,6 +52,8 @@ struct kfunc_symbol {
 static struct kfunc_symbol kfunc_symbols[] = {
 	{ "kfunc_a", -1, 0 },
 	{ "kfunc_b", -1, KF_FASTCALL },
+	{ "kfunc_c", -1, KF_ARENA_RET | KF_ARENA_ARG1 | KF_ARENA_ARG2 },
+	{ "kfunc_d", -1, KF_ARENA_ARG2 },
 };
 
 /* Align the .BTF_ids section to 4 bytes */
@@ -88,6 +101,8 @@ BTF_SET_END(test_set)
 BTF_KFUNCS_START(test_kfunc_set)
 BTF_ID_FLAGS(func, kfunc_a)
 BTF_ID_FLAGS(func, kfunc_b, KF_FASTCALL)
+BTF_ID_FLAGS(func, kfunc_c, KF_ARENA_RET | KF_ARENA_ARG1 | KF_ARENA_ARG2)
+BTF_ID_FLAGS(func, kfunc_d, KF_ARENA_ARG2)
 BTF_KFUNCS_END(test_kfunc_set)
 
 /*
@@ -95,6 +110,8 @@ BTF_KFUNCS_END(test_kfunc_set)
  * actually sort at least one of the two sets.
  */
 BTF_KFUNCS_START(test_kfunc_set_rev)
+BTF_ID_FLAGS(func, kfunc_d, KF_ARENA_ARG2)
+BTF_ID_FLAGS(func, kfunc_c, KF_ARENA_RET | KF_ARENA_ARG1 | KF_ARENA_ARG2)
 BTF_ID_FLAGS(func, kfunc_b, KF_FASTCALL)
 BTF_ID_FLAGS(func, kfunc_a)
 BTF_KFUNCS_END(test_kfunc_set_rev)
@@ -184,6 +201,22 @@ static void check_kfunc_set(struct btf_id_set8 *set)
 	}
 }
 
+/* True if @id is PTR -> TYPE_TAG(kflag=1, "address_space(1)") -> pointee */
+static bool is_arena_tagged_ptr(struct btf *btf, __u32 id)
+{
+	const struct btf_type *ptr, *tag;
+	const char *name;
+
+	ptr = btf__type_by_id(btf, id);
+	if (!btf_is_ptr(ptr))
+		return false;
+	tag = btf__type_by_id(btf, ptr->type);
+	if (!btf_is_type_tag(tag) || !btf_kflag(tag))
+		return false;
+	name = btf__name_by_offset(btf, tag->name_off);
+	return strcmp(name, TYPE_ATTR_ARENA) == 0;
+}
+
 void test_resolve_btfids(void)
 {
 	__u32 *test_list, *test_lists[] = { test_list_local, test_list_global };
@@ -227,6 +260,39 @@ void test_resolve_btfids(void)
 	check_kfunc_set(&test_kfunc_set);
 	check_kfunc_set(&test_kfunc_set_rev);
 
+	/*
+	 * Check resolve_btfids wrapped exactly the arena-flagged return/args
+	 * with the address_space(1) type attribute, and left other
+	 * pointers/returns untouched.
+	 */
+	for (i = 0; i < ARRAY_SIZE(kfunc_symbols); i++) {
+		const struct btf_type *fn, *proto;
+		const struct btf_param *params;
+		const char *name = kfunc_symbols[i].name;
+		u32 fl = kfunc_symbols[i].flags;
+		__u32 nr;
+
+		fn = btf__type_by_id(btf, kfunc_symbols[i].id);
+		if (!ASSERT_TRUE(btf_is_func(fn), name))
+			continue;
+		proto = btf__type_by_id(btf, fn->type);
+		if (!ASSERT_TRUE(btf_is_func_proto(proto), name))
+			continue;
+		params = btf_params(proto);
+		nr = btf_vlen(proto);
+
+		ASSERT_EQ(is_arena_tagged_ptr(btf, proto->type),
+			  !!(fl & KF_ARENA_RET), name);
+		if (nr > 0) {
+			ASSERT_EQ(is_arena_tagged_ptr(btf, params[0].type),
+				  !!(fl & KF_ARENA_ARG1), name);
+		}
+		if (nr > 1) {
+			ASSERT_EQ(is_arena_tagged_ptr(btf, params[1].type),
+				  !!(fl & KF_ARENA_ARG2), name);
+		}
+	}
+
 out:
 	btf__free(btf);
 }
diff --git a/tools/testing/selftests/bpf/progs/btf_data.c b/tools/testing/selftests/bpf/progs/btf_data.c
index 8587658012c3..ec34f7a6e038 100644
--- a/tools/testing/selftests/bpf/progs/btf_data.c
+++ b/tools/testing/selftests/bpf/progs/btf_data.c
@@ -58,3 +58,13 @@ int kfunc_b(struct root_struct *root)
 {
 	return 0;
 }
+
+struct root_struct *kfunc_c(struct root_struct *a, struct root_struct *b)
+{
+	return a;
+}
+
+int kfunc_d(struct root_struct *a, struct root_struct *b)
+{
+	return 0;
+}
-- 
2.55.0


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

* [PATCH bpf-next v2 4/6] resolve_btfids: Emit bpf_kfunc and bpf_fastcall decl tags
  2026-08-05 23:06 [PATCH bpf-next v2 0/6] resolve_btfids: Implement BTF tags emission for kfuncs Ihor Solodrai
                   ` (2 preceding siblings ...)
  2026-08-05 23:06 ` [PATCH bpf-next v2 3/6] selftests/bpf: Verify arena type tags in resolve_btfids test Ihor Solodrai
@ 2026-08-05 23:06 ` Ihor Solodrai
  2026-08-06 19:18   ` Eduard Zingerman
  2026-08-05 23:06 ` [PATCH bpf-next v2 5/6] selftests/bpf: Verify decl tags emission in resolve_btfids test Ihor Solodrai
  2026-08-05 23:06 ` [PATCH bpf-next v2 6/6] docs, resolve_btfids: Document kfunc BTF annotation emission Ihor Solodrai
  5 siblings, 1 reply; 27+ messages in thread
From: Ihor Solodrai @ 2026-08-05 23:06 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Kumar Kartikeya Dwivedi
  Cc: Alan Maguire, Jiri Olsa, Emil Tsalapatis, bpf

Emit the bpf_kfunc decl tag for every discovered kfunc, and bpf_fastcall
for kfuncs flagged KF_FASTCALL. These were previously produced by pahole
under --btf_features=decl_tag_kfuncs.

resolve_btfids now discovers kfuncs from the BTF ID sets [1] and
becomes the source of truth for their annotations.

Drop decl_tag_kfuncs pahole feature flag from scripts/Makefile.btf

[1] https://lore.kernel.org/all/20260722233518.778854-1-ihor.solodrai@linux.dev/

Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 scripts/Makefile.btf            |  2 +-
 tools/bpf/resolve_btfids/main.c | 31 ++++++++++++++++++++++++++++++-
 2 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/scripts/Makefile.btf b/scripts/Makefile.btf
index 8f73c093d27a..a1812985a61a 100644
--- a/scripts/Makefile.btf
+++ b/scripts/Makefile.btf
@@ -14,7 +14,7 @@ pahole-flags-$(call test-ge, $(pahole-ver), 125)	+= --skip_encoding_btf_inconsis
 else
 
 # Switch to using --btf_features for v1.26 and later.
-pahole-flags-$(call test-ge, $(pahole-ver), 126)  = -j$(JOBS) --btf_features=encode_force,var,float,enum64,decl_tag,type_tag,optimized_func,consistent_func,decl_tag_kfuncs
+pahole-flags-$(call test-ge, $(pahole-ver), 126)  = -j$(JOBS) --btf_features=encode_force,var,float,enum64,decl_tag,type_tag,optimized_func,consistent_func
 
 pahole-flags-$(call test-ge, $(pahole-ver), 131) += --btf_features=layout
 
diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
index 30c7f95aa3b1..ea25ca34aa00 100644
--- a/tools/bpf/resolve_btfids/main.c
+++ b/tools/bpf/resolve_btfids/main.c
@@ -161,6 +161,10 @@ struct object {
 	u32 addr_syms_cap;
 };
 
+#define DECL_TAG_FASTCALL "bpf_fastcall"
+#define DECL_TAG_KFUNC "bpf_kfunc"
+
+#define KF_FASTCALL	(1 << 12)
 #define KF_ARENA_RET	(1 << 13)
 #define KF_ARENA_ARG1	(1 << 14)
 #define KF_ARENA_ARG2	(1 << 15)
@@ -1233,7 +1237,7 @@ static int process_kfunc_with_implicit_args(struct btf2btf_context *ctx, struct
 			continue;
 
 		tag_name = btf__name_by_offset(btf, t->name_off);
-		if (strcmp(tag_name, "bpf_kfunc") == 0)
+		if (strcmp(tag_name, DECL_TAG_KFUNC) == 0)
 			continue;
 
 		idx = btf_decl_tag(t)->component_idx;
@@ -1411,6 +1415,21 @@ static int process_kfunc_with_arena_flags(struct btf2btf_context *ctx,
 	return 0;
 }
 
+static int add_decl_tag(struct btf2btf_context *ctx, const char *tag_name,
+			u32 target_btf_id, int component_idx)
+{
+	s32 new_id;
+
+	new_id = btf__add_decl_tag(ctx->btf, tag_name, target_btf_id, component_idx);
+	if (new_id < 0) {
+		pr_err("ERROR: resolve_btfids: failed to add '%s' decl tag for BTF id %u: %d\n",
+		       tag_name, target_btf_id, new_id);
+		return new_id;
+	}
+
+	return push_decl_tag_id(ctx, new_id);
+}
+
 static int btf2btf(struct object *obj)
 {
 	struct btf2btf_context ctx = {};
@@ -1424,6 +1443,16 @@ static int btf2btf(struct object *obj)
 	for (next = rb_first(&ctx.kfuncs); next; next = rb_next(next)) {
 		struct kfunc *kfunc = rb_entry(next, struct kfunc, rb_node);
 
+		err = add_decl_tag(&ctx, DECL_TAG_KFUNC, kfunc->btf_id, -1);
+		if (err)
+			goto out;
+
+		if (kfunc->flags & KF_FASTCALL) {
+			err = add_decl_tag(&ctx, DECL_TAG_FASTCALL, kfunc->btf_id, -1);
+			if (err)
+				goto out;
+		}
+
 		if (kfunc->flags & KF_IMPLICIT_ARGS) {
 			err = process_kfunc_with_implicit_args(&ctx, kfunc);
 			if (err)
-- 
2.55.0


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

* [PATCH bpf-next v2 5/6] selftests/bpf: Verify decl tags emission in resolve_btfids test
  2026-08-05 23:06 [PATCH bpf-next v2 0/6] resolve_btfids: Implement BTF tags emission for kfuncs Ihor Solodrai
                   ` (3 preceding siblings ...)
  2026-08-05 23:06 ` [PATCH bpf-next v2 4/6] resolve_btfids: Emit bpf_kfunc and bpf_fastcall decl tags Ihor Solodrai
@ 2026-08-05 23:06 ` Ihor Solodrai
  2026-08-06 19:20   ` Eduard Zingerman
  2026-08-05 23:06 ` [PATCH bpf-next v2 6/6] docs, resolve_btfids: Document kfunc BTF annotation emission Ihor Solodrai
  5 siblings, 1 reply; 27+ messages in thread
From: Ihor Solodrai @ 2026-08-05 23:06 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Kumar Kartikeya Dwivedi
  Cc: Alan Maguire, Jiri Olsa, Emil Tsalapatis, bpf

Extend test_resolve_btfids() to assert that resolve_btfids emits a
BTF_KIND_DECL_TAG named "bpf_kfunc" for every kfunc, and
"bpf_fastcall" for kfuncs marked KF_FASTCALL.

Add a btf_has_decl_tag() helper that scans the output BTF for a decl
tag matching name and target.

Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 .../selftests/bpf/prog_tests/resolve_btfids.c | 40 +++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c b/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c
index 8482f00046d4..732cfed35e1c 100644
--- a/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c
+++ b/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c
@@ -12,6 +12,8 @@
 
 #define BTF_DATA_FILE "resolve_btfids.test.o.BTF"
 
+#define DECL_TAG_FASTCALL "bpf_fastcall"
+#define DECL_TAG_KFUNC "bpf_kfunc"
 #define TYPE_ATTR_ARENA "address_space(1)"
 
 #ifndef KF_FASTCALL
@@ -176,6 +178,28 @@ static int resolve_symbols(struct btf *btf)
 	return 0;
 }
 
+static bool btf_has_decl_tag(struct btf *btf, const char *tag_name, s32 target_id)
+{
+	const struct btf_type *t;
+	const char *name;
+	int nr, id;
+
+	nr = btf__type_cnt(btf);
+	for (id = 1; id < nr; id++) {
+		t = btf__type_by_id(btf, id);
+		if (!btf_is_decl_tag(t))
+			continue;
+		if (t->type != (__u32)target_id)
+			continue;
+		if (btf_decl_tag(t)->component_idx != -1)
+			continue;
+		name = btf__name_by_offset(btf, t->name_off);
+		if (strcmp(name, tag_name) == 0)
+			return true;
+	}
+	return false;
+}
+
 static void check_kfunc_set(struct btf_id_set8 *set)
 {
 	unsigned int i, j;
@@ -260,6 +284,22 @@ void test_resolve_btfids(void)
 	check_kfunc_set(&test_kfunc_set);
 	check_kfunc_set(&test_kfunc_set_rev);
 
+	/* Check resolve_btfids emitted a bpf_kfunc decl_tag for each kfunc */
+	for (i = 0; i < ARRAY_SIZE(kfunc_symbols); i++) {
+		ASSERT_TRUE(btf_has_decl_tag(btf, DECL_TAG_KFUNC,
+					     kfunc_symbols[i].id),
+			    kfunc_symbols[i].name);
+	}
+
+	/* Check resolve_btfids emitted bpf_fastcall for KF_FASTCALL kfuncs */
+	for (i = 0; i < ARRAY_SIZE(kfunc_symbols); i++) {
+		if (kfunc_symbols[i].flags & KF_FASTCALL) {
+			ASSERT_TRUE(btf_has_decl_tag(btf, DECL_TAG_FASTCALL,
+						     kfunc_symbols[i].id),
+				    kfunc_symbols[i].name);
+		}
+	}
+
 	/*
 	 * Check resolve_btfids wrapped exactly the arena-flagged return/args
 	 * with the address_space(1) type attribute, and left other
-- 
2.55.0


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

* [PATCH bpf-next v2 6/6] docs, resolve_btfids: Document kfunc BTF annotation emission
  2026-08-05 23:06 [PATCH bpf-next v2 0/6] resolve_btfids: Implement BTF tags emission for kfuncs Ihor Solodrai
                   ` (4 preceding siblings ...)
  2026-08-05 23:06 ` [PATCH bpf-next v2 5/6] selftests/bpf: Verify decl tags emission in resolve_btfids test Ihor Solodrai
@ 2026-08-05 23:06 ` Ihor Solodrai
  2026-08-05 23:16   ` sashiko-bot
                     ` (2 more replies)
  5 siblings, 3 replies; 27+ messages in thread
From: Ihor Solodrai @ 2026-08-05 23:06 UTC (permalink / raw)
  To: Alexei Starovoitov, Andrii Nakryiko, Daniel Borkmann,
	Eduard Zingerman, Kumar Kartikeya Dwivedi
  Cc: Alan Maguire, Jiri Olsa, Emil Tsalapatis, bpf

resolve_btfids now emits the bpf_kfunc and bpf_fastcall BTF decl tags and
the arena address_space(1) type attribute for kfuncs, which were
previously produced by pahole.

Reflect this in the in-tree comments and documentation.

Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
---
 Documentation/bpf/kfuncs.rst      |  8 ++++++++
 Documentation/process/changes.rst |  7 +++----
 scripts/Makefile.btf              |  3 +++
 tools/bpf/resolve_btfids/main.c   | 11 +++++++++++
 4 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/Documentation/bpf/kfuncs.rst b/Documentation/bpf/kfuncs.rst
index cbde86d082cc..c60fc574e8b0 100644
--- a/Documentation/bpf/kfuncs.rst
+++ b/Documentation/bpf/kfuncs.rst
@@ -472,6 +472,14 @@ type. An example is shown below::
         }
         late_initcall(init_subsystem);
 
+At kernel build time the ``resolve_btfids`` tool discovers all kfuncs from the
+registered ``BTF_SET8_KFUNCS`` sets and emits their BTF annotations into the
+kernel's BTF; these annotations were historically produced by pahole. For each
+discovered kfunc ``resolve_btfids`` emits a ``bpf_kfunc`` BTF decl tag, a
+``bpf_fastcall`` decl tag when the kfunc is flagged ``KF_FASTCALL``, and the
+``address_space(1)`` type attribute on the return value and/or arguments flagged
+``KF_ARENA_RET``, ``KF_ARENA_ARG1`` or ``KF_ARENA_ARG2`` (see section 2.8).
+
 2.7  Specifying no-cast aliases with ___init
 --------------------------------------------
 
diff --git a/Documentation/process/changes.rst b/Documentation/process/changes.rst
index 1ca8c5f73ad0..6d1dbe4abf0f 100644
--- a/Documentation/process/changes.rst
+++ b/Documentation/process/changes.rst
@@ -147,10 +147,9 @@ Since Linux 5.2, if CONFIG_DEBUG_INFO_BTF is selected, the build system
 generates BTF (BPF Type Format) from DWARF in vmlinux, a bit later from kernel
 modules as well.  This requires pahole v1.22 or later.
 
-Since Linux 7.0, kfuncs annotated with KF_IMPLICIT_ARGS require pahole v1.26
-or later.  Without it, such kfuncs will have incorrect BTF prototypes in
-vmlinux, causing BPF programs to fail to load with a "func_proto incompatible
-with vmlinux" error.  Many sched_ext kfuncs are affected.
+Kfunc BTF annotations (the bpf_kfunc and bpf_fastcall decl tags and the arena
+address_space(1) type attribute) are emitted in-tree by resolve_btfids from the
+BTF_KFUNCS sets, so they no longer depend on a specific pahole version.
 
 It is found in the 'dwarves' or 'pahole' distro packages or from
 https://fedorapeople.org/~acme/dwarves/.
diff --git a/scripts/Makefile.btf b/scripts/Makefile.btf
index a1812985a61a..717e76ce96a7 100644
--- a/scripts/Makefile.btf
+++ b/scripts/Makefile.btf
@@ -14,6 +14,9 @@ pahole-flags-$(call test-ge, $(pahole-ver), 125)	+= --skip_encoding_btf_inconsis
 else
 
 # Switch to using --btf_features for v1.26 and later.
+#
+# kfunc BTF annotations (bpf_kfunc/bpf_fastcall decl tags and the arena
+# address_space(1) type attribute) are emitted by resolve_btfids, not pahole.
 pahole-flags-$(call test-ge, $(pahole-ver), 126)  = -j$(JOBS) --btf_features=encode_force,var,float,enum64,decl_tag,type_tag,optimized_func,consistent_func
 
 pahole-flags-$(call test-ge, $(pahole-ver), 131) += --btf_features=layout
diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
index ea25ca34aa00..66f4014e6aa1 100644
--- a/tools/bpf/resolve_btfids/main.c
+++ b/tools/bpf/resolve_btfids/main.c
@@ -58,6 +58,17 @@
  *             __BTF_ID__func__vfs_fallocate__5:
  *             .zero 4
  *	       .word (1 << 3) | (1 << 1) | (1 << 2)
+ *
+ * In addition to resolving BTF IDs, resolve_btfids performs kernel-specific
+ * BTF-to-BTF transformations for kfuncs found in BTF_SET8_KFUNCS sets. For
+ * each such kfunc it:
+ *
+ *   - emits a "bpf_kfunc" decl tag, and "bpf_fastcall" when KF_FASTCALL is set;
+ *   - wraps the return value and/or arguments flagged KF_ARENA_RET,
+ *     KF_ARENA_ARG1 or KF_ARENA_ARG2 with the "address_space(1)" type attribute;
+ *   - rewrites the prototype of KF_IMPLICIT_ARGS kfuncs.
+ *
+ * These kfunc annotations were historically produced by pahole.
  */
 
 #define  _GNU_SOURCE
-- 
2.55.0


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

* Re: [PATCH bpf-next v2 6/6] docs, resolve_btfids: Document kfunc BTF annotation emission
  2026-08-05 23:06 ` [PATCH bpf-next v2 6/6] docs, resolve_btfids: Document kfunc BTF annotation emission Ihor Solodrai
@ 2026-08-05 23:16   ` sashiko-bot
  2026-08-06 21:12     ` Ihor Solodrai
  2026-08-06  0:01   ` bot+bpf-ci
  2026-08-06 19:47   ` Eduard Zingerman
  2 siblings, 1 reply; 27+ messages in thread
From: sashiko-bot @ 2026-08-05 23:16 UTC (permalink / raw)
  To: Ihor Solodrai; +Cc: bpf

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The minimum required pahole version in the changes.rst table was not reverted to 1.22 after its dependency on 1.26 was removed.
--

--- Patch [6]: [PATCH bpf-next v2 6/6] docs, resolve_btfids: Document kfunc BTF annotation emission ---
commit b5222d5ea4c3ea695d12ac70fc23f3fbadabd591
Author: Ihor Solodrai <ihor.solodrai@linux.dev>

docs, resolve_btfids: Document kfunc BTF annotation emission

This commit updates documentation and comments to clarify that resolve_btfids
now emits BTF annotations for kfuncs instead of pahole. It modifies
changes.rst to reflect that a specific pahole version is no longer required
for these annotations.

> diff --git a/Documentation/process/changes.rst b/Documentation/process/changes.rst
> index 1ca8c5f73ad00..6d1dbe4abf0f0 100644
> --- a/Documentation/process/changes.rst
> +++ b/Documentation/process/changes.rst
[ ... ]
> @@ -147,10 +147,9 @@ Since Linux 5.2, if CONFIG_DEBUG_INFO_BTF is selected, the build system
>  generates BTF (BPF Type Format) from DWARF in vmlinux, a bit later from kernel
>  modules as well.  This requires pahole v1.22 or later.
>  
> -Since Linux 7.0, kfuncs annotated with KF_IMPLICIT_ARGS require pahole v1.26
> -or later.  Without it, such kfuncs will have incorrect BTF prototypes in
> -vmlinux, causing BPF programs to fail to load with a "func_proto incompatible
> -with vmlinux" error.  Many sched_ext kfuncs are affected.
> +Kfunc BTF annotations (the bpf_kfunc and bpf_fastcall decl tags and the arena
> +address_space(1) type attribute) are emitted in-tree by resolve_btfids from the
> +BTF_KFUNCS sets, so they no longer depend on a specific pahole version.
>  
>  It is found in the 'dwarves' or 'pahole' distro packages or from
>  https://fedorapeople.org/~acme/dwarves/.

[Severity: Medium]
Since this removes the dependency on pahole 1.26, should the minimum
required version in the "Current Minimal Requirements" table earlier in
this file be reverted to 1.22?

The table currently still lists 1.26:

Documentation/process/changes.rst:
    openssl & libcrypto    1.0.0            openssl version
    pahole                 1.26             pahole --version
    pcmciautils            004              pccardctl -V

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260805230648.2354989-1-ihor.solodrai@linux.dev?part=6

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

* Re: [PATCH bpf-next v2 3/6] selftests/bpf: Verify arena type tags in resolve_btfids test
  2026-08-05 23:06 ` [PATCH bpf-next v2 3/6] selftests/bpf: Verify arena type tags in resolve_btfids test Ihor Solodrai
@ 2026-08-05 23:17   ` sashiko-bot
  2026-08-06 21:09     ` Ihor Solodrai
  2026-08-06 19:15   ` Eduard Zingerman
  1 sibling, 1 reply; 27+ messages in thread
From: sashiko-bot @ 2026-08-05 23:17 UTC (permalink / raw)
  To: Ihor Solodrai; +Cc: bpf

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Missing NULL pointer check on the result of `btf__type_by_id()` causes a segmentation fault when a kfunc symbol is missing.
--

--- Patch [3]: [PATCH bpf-next v2 3/6] selftests/bpf: Verify arena type tags in resolve_btfids test ---
commit 833ac8bbb8ac1055e25790da1396864987e31541
Author: Ihor Solodrai <ihor.solodrai@linux.dev>

selftests/bpf: Verify arena type tags in resolve_btfids test

This commit extends test_resolve_btfids() to assert that resolve_btfids
emits the address_space(1) type attribute on the return type and arguments
of kfuncs marked with KF_ARENA_RET, KF_ARENA_ARG1 or KF_ARENA_ARG2.

> diff --git a/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c b/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c
> index ac51fd4548214..8482f00046d4c 100644
> --- a/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c
> +++ b/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c
[ ... ]
> @@ -227,6 +260,39 @@ void test_resolve_btfids(void)
>  	check_kfunc_set(&test_kfunc_set);
>  	check_kfunc_set(&test_kfunc_set_rev);
>  
> +	/*
> +	 * Check resolve_btfids wrapped exactly the arena-flagged return/args
> +	 * with the address_space(1) type attribute, and left other
> +	 * pointers/returns untouched.
> +	 */
> +	for (i = 0; i < ARRAY_SIZE(kfunc_symbols); i++) {
> +		const struct btf_type *fn, *proto;
> +		const struct btf_param *params;
> +		const char *name = kfunc_symbols[i].name;
> +		u32 fl = kfunc_symbols[i].flags;
> +		__u32 nr;
> +
> +		fn = btf__type_by_id(btf, kfunc_symbols[i].id);
> +		if (!ASSERT_TRUE(btf_is_func(fn), name))
> +			continue;

[Severity: Medium]
Could this cause a segmentation fault if a kfunc symbol is missing?

If resolve_symbols() fails to find a kfunc in the parsed BTF file, the
symbol's id remains -1. When -1 is passed to btf__type_by_id(), it
returns NULL.

Since btf_is_func() unconditionally accesses the info member, passing a
NULL pointer to it would crash the test program before the ASSERT_TRUE
evaluates.

Should we check if fn is NULL before passing it to btf_is_func()?

> +		proto = btf__type_by_id(btf, fn->type);
> +		if (!ASSERT_TRUE(btf_is_func_proto(proto), name))
> +			continue;
[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260805230648.2354989-1-ihor.solodrai@linux.dev?part=3

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

* Re: [PATCH bpf-next v2 6/6] docs, resolve_btfids: Document kfunc BTF annotation emission
  2026-08-05 23:06 ` [PATCH bpf-next v2 6/6] docs, resolve_btfids: Document kfunc BTF annotation emission Ihor Solodrai
  2026-08-05 23:16   ` sashiko-bot
@ 2026-08-06  0:01   ` bot+bpf-ci
  2026-08-06 21:13     ` Ihor Solodrai
  2026-08-06 19:47   ` Eduard Zingerman
  2 siblings, 1 reply; 27+ messages in thread
From: bot+bpf-ci @ 2026-08-06  0:01 UTC (permalink / raw)
  To: ihor.solodrai, ast, andrii, daniel, eddyz87, memxor
  Cc: alan.maguire, jolsa, emil, bpf, ast, andrii, daniel, martin.lau,
	eddyz87, yonghong.song, clm, ihor.solodrai

[-- Attachment #1: Type: text/plain, Size: 4384 bytes --]

> diff --git a/Documentation/bpf/kfuncs.rst b/Documentation/bpf/kfuncs.rst
> index cbde86d082cce..c60fc574e8b06 100644
> --- a/Documentation/bpf/kfuncs.rst
> +++ b/Documentation/bpf/kfuncs.rst
> @@ -472,6 +472,14 @@ type. An example is shown below::
>          }
>          late_initcall(init_subsystem);
>
> +At kernel build time the ``resolve_btfids`` tool discovers all kfuncs from the
> +registered ``BTF_SET8_KFUNCS`` sets and emits their BTF annotations into the
> +kernel's BTF; these annotations were historically produced by pahole. For each
> +discovered kfunc ``resolve_btfids`` emits a ``bpf_kfunc`` BTF decl tag, a
> +``bpf_fastcall`` decl tag when the kfunc is flagged ``KF_FASTCALL``, and the
> +``address_space(1)`` type attribute on the return value and/or arguments flagged
> +``KF_ARENA_RET``, ``KF_ARENA_ARG1`` or ``KF_ARENA_ARG2`` (see section 2.8).

Emil Tsalapatis suggested in v1 replacing "address_space(1)" with "arena"
throughout the documentation for better readability. This nit was not
addressed in v2.

The term "address_space(1)" appears in four locations across this commit
(kfuncs.rst, changes.rst, Makefile.btf, and main.c). Would using "arena"
be clearer, especially since the code already defines TYPE_ATTR_ARENA?

> +
>  2.7  Specifying no-cast aliases with ___init
>  --------------------------------------------
>
> diff --git a/Documentation/process/changes.rst b/Documentation/process/changes.rst
> index 1ca8c5f73ad00..6d1dbe4abf0f0 100644
> --- a/Documentation/process/changes.rst
> +++ b/Documentation/process/changes.rst
> @@ -147,10 +147,9 @@ Since Linux 5.2, if CONFIG_DEBUG_INFO_BTF is selected, the build system
>  generates BTF (BPF Type Format) from DWARF in vmlinux, a bit later from kernel
>  modules as well.  This requires pahole v1.22 or later.
>
> -Since Linux 7.0, kfuncs annotated with KF_IMPLICIT_ARGS require pahole v1.26
> -or later.  Without it, such kfuncs will have incorrect BTF prototypes in
> -vmlinux, causing BPF programs to fail to load with a "func_proto incompatible
> -with vmlinux" error.  Many sched_ext kfuncs are affected.
> +Kfunc BTF annotations (the bpf_kfunc and bpf_fastcall decl tags and the arena
> +address_space(1) type attribute) are emitted in-tree by resolve_btfids from the
> +BTF_KFUNCS sets, so they no longer depend on a specific pahole version.
>
>  It is found in the 'dwarves' or 'pahole' distro packages or from
>  https://fedorapeople.org/~acme/dwarves/.
> diff --git a/scripts/Makefile.btf b/scripts/Makefile.btf
> index a1812985a61aa..717e76ce96a71 100644
> --- a/scripts/Makefile.btf
> +++ b/scripts/Makefile.btf
> @@ -14,6 +14,9 @@ pahole-flags-$(call test-ge, $(pahole-ver), 125)	+= --skip_encoding_btf_inconsis
>  else
>
>  # Switch to using --btf_features for v1.26 and later.
> +#
> +# kfunc BTF annotations (bpf_kfunc/bpf_fastcall decl tags and the arena
> +# address_space(1) type attribute) are emitted by resolve_btfids, not pahole.
>  pahole-flags-$(call test-ge, $(pahole-ver), 126)  = -j$(JOBS) --btf_features=encode_force,var,float,enum64,decl_tag,type_tag,optimized_func,consistent_func
>
>  pahole-flags-$(call test-ge, $(pahole-ver), 131) += --btf_features=layout
> diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
> index ea25ca34aa006..66f4014e6aa17 100644
> --- a/tools/bpf/resolve_btfids/main.c
> +++ b/tools/bpf/resolve_btfids/main.c
> @@ -58,6 +58,17 @@
>   *             __BTF_ID__func__vfs_fallocate__5:
>   *             .zero 4
>   *	       .word (1 << 3) | (1 << 1) | (1 << 2)
> + *
> + * In addition to resolving BTF IDs, resolve_btfids performs kernel-specific
> + * BTF-to-BTF transformations for kfuncs found in BTF_SET8_KFUNCS sets. For
> + * each such kfunc it:
> + *
> + *   - emits a "bpf_kfunc" decl tag, and "bpf_fastcall" when KF_FASTCALL is set;
> + *   - wraps the return value and/or arguments flagged KF_ARENA_RET,
> + *     KF_ARENA_ARG1 or KF_ARENA_ARG2 with the "address_space(1)" type attribute;
> + *   - rewrites the prototype of KF_IMPLICIT_ARGS kfuncs.
> + *
> + * These kfunc annotations were historically produced by pahole.
>   */
>
>  #define  _GNU_SOURCE


---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md

CI run summary: https://github.com/kernel-patches/bpf/actions/runs/31056256483

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

* Re: [PATCH bpf-next v2 1/6] resolve_btfids: Deduplicate BTF after btf2btf transformations
  2026-08-05 23:06 ` [PATCH bpf-next v2 1/6] resolve_btfids: Deduplicate BTF after btf2btf transformations Ihor Solodrai
@ 2026-08-06 19:05   ` Eduard Zingerman
  2026-08-06 20:48     ` Ihor Solodrai
  0 siblings, 1 reply; 27+ messages in thread
From: Eduard Zingerman @ 2026-08-06 19:05 UTC (permalink / raw)
  To: Ihor Solodrai, Alexei Starovoitov, Andrii Nakryiko,
	Daniel Borkmann, Kumar Kartikeya Dwivedi
  Cc: Alan Maguire, Jiri Olsa, Emil Tsalapatis, bpf

On Wed, 2026-08-05 at 16:06 -0700, Ihor Solodrai wrote:
> btf2btf() adds new types to the BTF: the KF_IMPLICIT_ARGS transform
> synthesizes an _impl FUNC together with its FUNC_PROTO and copies of the
> kfunc's decl tags. Nothing deduplicates them afterwards. pahole runs
> btf__dedup() on its own output, but that happens before resolve_btfids
> sees the BTF, so any type the tool itself creates is emitted as-is, even
> when a structurally identical type is already present.
> 
> Call btf__dedup() at the start of finalize_btf(), so that base
> distillation and the by-name sort both operate on the canonical set of
> types.
> 
> Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
> ---

Hi Ihor,

I'm curious if you had a chance to measure how this affects the
resolve_btfids running time?

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

* Re: [PATCH bpf-next v2 2/6] resolve_btfids: Process KF_ARENA_* flags in resolve_btfids
  2026-08-05 23:06 ` [PATCH bpf-next v2 2/6] resolve_btfids: Process KF_ARENA_* flags in resolve_btfids Ihor Solodrai
@ 2026-08-06 19:12   ` Eduard Zingerman
  2026-08-06 21:02     ` Ihor Solodrai
  0 siblings, 1 reply; 27+ messages in thread
From: Eduard Zingerman @ 2026-08-06 19:12 UTC (permalink / raw)
  To: Ihor Solodrai, Alexei Starovoitov, Andrii Nakryiko,
	Daniel Borkmann, Kumar Kartikeya Dwivedi
  Cc: Alan Maguire, Jiri Olsa, Emil Tsalapatis, bpf

On Wed, 2026-08-05 at 16:06 -0700, Ihor Solodrai wrote:

...

> +static s32 add_arena_tagged_proto(struct btf *btf, struct kfunc *kfunc)
> +{
> +	const struct btf_type *func = btf__type_by_id(btf, kfunc->btf_id);
> +	u32 proto_id = func->type;
> +	const struct btf_type *proto = btf__type_by_id(btf, proto_id);
> +	const struct btf_param *params = btf_params(proto);
> +	u32 nr_params = btf_vlen(proto);
> +	s32 arg0_type_id = nr_params > 0 ? (s32)params[0].type : -1;
> +	s32 arg1_type_id = nr_params > 1 ? (s32)params[1].type : -1;
> +	s32 new_proto_id, id, param_type_id;
> +	s32 ret_type_id = proto->type;
> +	const char *name;
> +	int err;
> +
> +	if (kfunc->flags & KF_ARENA_RET) {
> +		id = arena_tag_ptr(btf, ret_type_id);
> +		if (id < 0) {
> +			pr_err("ERROR: resolve_btfids: kfunc %s: KF_ARENA_RET but return type is not a pointer\n",
> +			       kfunc->name);
> +			return id;
> +		}
> +		ret_type_id = id;
> +	}
> +
> +	if (kfunc->flags & KF_ARENA_ARG1) {

Nit: let's avoid the copy paste and make this code prepared for the
     __arena suffixes by moving the logic inside the parameter
     processing loop below:

     for (i in params) {
       bool add_tag = false;

       param_type_id = params[i].type;
       switch(i) { 0: add_tag = kfunc->flags & KF_ARENA_ARG1; break; ... }
       if (add_tag)
          param_type_id = arena_tag_ptr(btf, param_type_id);
       if (param_type_id < 0)
         ...
     }

> +		if (nr_params < 1) {
> +			pr_err("ERROR: resolve_btfids: kfunc %s: KF_ARENA_ARG1 but it has no argument 1\n",
> +			       kfunc->name);
> +			return -EINVAL;
> +		}
> +		id = arena_tag_ptr(btf, arg0_type_id);
> +		if (id < 0) {
> +			pr_err("ERROR: resolve_btfids: kfunc %s: KF_ARENA_ARG1 but argument 1 is not a pointer\n",
> +			       kfunc->name);

Nit: not a pointer is not the only error condition, btf__add_*()
     functions might fail as well, maybe just push pr_err() down
     to the arena_tag_ptr()?

> +			return id;
> +		}
> +		arg0_type_id = id;
> +	}
> +
> +	if (kfunc->flags & KF_ARENA_ARG2) {
> +		if (nr_params < 2) {
> +			pr_err("ERROR: resolve_btfids: kfunc %s: KF_ARENA_ARG2 but it has no argument 2\n",
> +			       kfunc->name);
> +			return -EINVAL;
> +		}
> +		id = arena_tag_ptr(btf, arg1_type_id);
> +		if (id < 0) {
> +			pr_err("ERROR: resolve_btfids: kfunc %s: KF_ARENA_ARG2 but argument 2 is not a pointer\n",
> +			       kfunc->name);
> +			return id;
> +		}
> +		arg1_type_id = id;
> +	}
> +
> +	new_proto_id = btf__add_func_proto(btf, ret_type_id);
> +	if (new_proto_id < 0) {
> +		pr_err("ERROR: resolve_btfids: kfunc %s: failed to add a func proto to BTF\n",
> +		       kfunc->name);
> +		return new_proto_id;
> +	}
> +
> +	for (u32 i = 0; i < nr_params; i++) {
> +		proto = btf__type_by_id(btf, proto_id);
> +		params = btf_params(proto);

Nit: these two do not need to be in the loop body.

> +		name = btf__name_by_offset(btf, params[i].name_off);
> +
> +		switch (i) {
> +		case 0:
> +			param_type_id = arg0_type_id;
> +			break;
> +		case 1:
> +			param_type_id = arg1_type_id;
> +			break;
> +		default:
> +			param_type_id = params[i].type;
> +			break;
> +		}
> +
> +		err = btf__add_func_param(btf, name ?: "", param_type_id);
> +		if (err < 0) {
> +			pr_err("ERROR: resolve_btfids: kfunc %s: failed to add a proto param to BTF\n",
> +			       kfunc->name);
> +			return err;
> +		}
> +	}
> +
> +	pr_debug("added arena-tagged proto for kfunc %s: %d\n", kfunc->name, new_proto_id);
> +
> +	return new_proto_id;
> +}

...

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

* Re: [PATCH bpf-next v2 3/6] selftests/bpf: Verify arena type tags in resolve_btfids test
  2026-08-05 23:06 ` [PATCH bpf-next v2 3/6] selftests/bpf: Verify arena type tags in resolve_btfids test Ihor Solodrai
  2026-08-05 23:17   ` sashiko-bot
@ 2026-08-06 19:15   ` Eduard Zingerman
  1 sibling, 0 replies; 27+ messages in thread
From: Eduard Zingerman @ 2026-08-06 19:15 UTC (permalink / raw)
  To: Ihor Solodrai, Alexei Starovoitov, Andrii Nakryiko,
	Daniel Borkmann, Kumar Kartikeya Dwivedi
  Cc: Alan Maguire, Jiri Olsa, Emil Tsalapatis, bpf

On Wed, 2026-08-05 at 16:06 -0700, Ihor Solodrai wrote:
> Extend test_resolve_btfids() to assert that resolve_btfids emits the
> address_space(1) type attribute (a BTF_KIND_TYPE_TAG with kflag=1) on
> the return type and/or arguments of kfuncs marked KF_ARENA_RET,
> KF_ARENA_ARG1 or KF_ARENA_ARG2.
> 
> Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
> ---

Acked-by: Eduard Zingerman <eddyz87@gmail.com>

...

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

* Re: [PATCH bpf-next v2 4/6] resolve_btfids: Emit bpf_kfunc and bpf_fastcall decl tags
  2026-08-05 23:06 ` [PATCH bpf-next v2 4/6] resolve_btfids: Emit bpf_kfunc and bpf_fastcall decl tags Ihor Solodrai
@ 2026-08-06 19:18   ` Eduard Zingerman
  0 siblings, 0 replies; 27+ messages in thread
From: Eduard Zingerman @ 2026-08-06 19:18 UTC (permalink / raw)
  To: Ihor Solodrai, Alexei Starovoitov, Andrii Nakryiko,
	Daniel Borkmann, Kumar Kartikeya Dwivedi
  Cc: Alan Maguire, Jiri Olsa, Emil Tsalapatis, bpf

On Wed, 2026-08-05 at 16:06 -0700, Ihor Solodrai wrote:
> Emit the bpf_kfunc decl tag for every discovered kfunc, and bpf_fastcall
> for kfuncs flagged KF_FASTCALL. These were previously produced by pahole
> under --btf_features=decl_tag_kfuncs.
> 
> resolve_btfids now discovers kfuncs from the BTF ID sets [1] and
> becomes the source of truth for their annotations.
> 
> Drop decl_tag_kfuncs pahole feature flag from scripts/Makefile.btf
> 
> [1] https://lore.kernel.org/all/20260722233518.778854-1-ihor.solodrai@linux.dev/
> 
> Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
> ---

Acked-by: Eduard Zingerman <eddyz87@gmail.com>

...

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

* Re: [PATCH bpf-next v2 5/6] selftests/bpf: Verify decl tags emission in resolve_btfids test
  2026-08-05 23:06 ` [PATCH bpf-next v2 5/6] selftests/bpf: Verify decl tags emission in resolve_btfids test Ihor Solodrai
@ 2026-08-06 19:20   ` Eduard Zingerman
  0 siblings, 0 replies; 27+ messages in thread
From: Eduard Zingerman @ 2026-08-06 19:20 UTC (permalink / raw)
  To: Ihor Solodrai, Alexei Starovoitov, Andrii Nakryiko,
	Daniel Borkmann, Kumar Kartikeya Dwivedi
  Cc: Alan Maguire, Jiri Olsa, Emil Tsalapatis, bpf

On Wed, 2026-08-05 at 16:06 -0700, Ihor Solodrai wrote:
> Extend test_resolve_btfids() to assert that resolve_btfids emits a
> BTF_KIND_DECL_TAG named "bpf_kfunc" for every kfunc, and
> "bpf_fastcall" for kfuncs marked KF_FASTCALL.
> 
> Add a btf_has_decl_tag() helper that scans the output BTF for a decl
> tag matching name and target.
> 
> Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
> ---

Acked-by: Eduard Zingerman <eddyz87@gmail.com>

...

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

* Re: [PATCH bpf-next v2 6/6] docs, resolve_btfids: Document kfunc BTF annotation emission
  2026-08-05 23:06 ` [PATCH bpf-next v2 6/6] docs, resolve_btfids: Document kfunc BTF annotation emission Ihor Solodrai
  2026-08-05 23:16   ` sashiko-bot
  2026-08-06  0:01   ` bot+bpf-ci
@ 2026-08-06 19:47   ` Eduard Zingerman
  2026-08-06 21:06     ` Ihor Solodrai
  2 siblings, 1 reply; 27+ messages in thread
From: Eduard Zingerman @ 2026-08-06 19:47 UTC (permalink / raw)
  To: Ihor Solodrai, Alexei Starovoitov, Andrii Nakryiko,
	Daniel Borkmann, Kumar Kartikeya Dwivedi
  Cc: Alan Maguire, Jiri Olsa, Emil Tsalapatis, bpf

On Wed, 2026-08-05 at 16:06 -0700, Ihor Solodrai wrote:

...

> diff --git a/Documentation/bpf/kfuncs.rst b/Documentation/bpf/kfuncs.rst
> index cbde86d082cc..c60fc574e8b0 100644
> --- a/Documentation/bpf/kfuncs.rst
> +++ b/Documentation/bpf/kfuncs.rst
> @@ -472,6 +472,14 @@ type. An example is shown below::
>          }
>          late_initcall(init_subsystem);
>  
> +At kernel build time the ``resolve_btfids`` tool discovers all kfuncs from the
> +registered ``BTF_SET8_KFUNCS`` sets and emits their BTF annotations into the

Note that this is a single occurrence of the word BTF_SET8_KFUNCS in
this .rst file. Also The wording "registered" is confusing as the
above code snippet shows the usage of register_btf_kfunc_id_set()
function, which is completely unrelated.

> +kernel's BTF; these annotations were historically produced by pahole. For each

I'd skip a note about pahole, it does not convey usable information.

> +discovered kfunc ``resolve_btfids`` emits a ``bpf_kfunc`` BTF decl tag, a
> +``bpf_fastcall`` decl tag when the kfunc is flagged ``KF_FASTCALL``, and the
> +``address_space(1)`` type attribute on the return value and/or arguments flagged
> +``KF_ARENA_RET``, ``KF_ARENA_ARG1`` or ``KF_ARENA_ARG2`` (see section 2.8).
> +
>  2.7  Specifying no-cast aliases with ___init
>  --------------------------------------------
>  
> diff --git a/Documentation/process/changes.rst b/Documentation/process/changes.rst
> index 1ca8c5f73ad0..6d1dbe4abf0f 100644
> --- a/Documentation/process/changes.rst
> +++ b/Documentation/process/changes.rst
> @@ -147,10 +147,9 @@ Since Linux 5.2, if CONFIG_DEBUG_INFO_BTF is selected, the build system
>  generates BTF (BPF Type Format) from DWARF in vmlinux, a bit later from kernel
>  modules as well.  This requires pahole v1.22 or later.
>  
> -Since Linux 7.0, kfuncs annotated with KF_IMPLICIT_ARGS require pahole v1.26
> -or later.  Without it, such kfuncs will have incorrect BTF prototypes in
> -vmlinux, causing BPF programs to fail to load with a "func_proto incompatible
> -with vmlinux" error.  Many sched_ext kfuncs are affected.
> +Kfunc BTF annotations (the bpf_kfunc and bpf_fastcall decl tags and the arena
> +address_space(1) type attribute) are emitted in-tree by resolve_btfids from the
> +BTF_KFUNCS sets, so they no longer depend on a specific pahole version.

Just drop the whole paragraph?

>  
>  It is found in the 'dwarves' or 'pahole' distro packages or from
>  https://fedorapeople.org/~acme/dwarves/.
> diff --git a/scripts/Makefile.btf b/scripts/Makefile.btf
> index a1812985a61a..717e76ce96a7 100644
> --- a/scripts/Makefile.btf
> +++ b/scripts/Makefile.btf
> @@ -14,6 +14,9 @@ pahole-flags-$(call test-ge, $(pahole-ver), 125)	+= --skip_encoding_btf_inconsis
>  else
>  
>  # Switch to using --btf_features for v1.26 and later.
> +#
> +# kfunc BTF annotations (bpf_kfunc/bpf_fastcall decl tags and the arena
> +# address_space(1) type attribute) are emitted by resolve_btfids, not pahole.

What's the point of this comment?

>  pahole-flags-$(call test-ge, $(pahole-ver), 126)  = -j$(JOBS) --btf_features=encode_force,var,float,enum64,decl_tag,type_tag,optimized_func,consistent_func
>  
>  pahole-flags-$(call test-ge, $(pahole-ver), 131) += --btf_features=layout

...

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

* Re: [PATCH bpf-next v2 1/6] resolve_btfids: Deduplicate BTF after btf2btf transformations
  2026-08-06 19:05   ` Eduard Zingerman
@ 2026-08-06 20:48     ` Ihor Solodrai
  2026-08-06 20:52       ` Eduard Zingerman
  0 siblings, 1 reply; 27+ messages in thread
From: Ihor Solodrai @ 2026-08-06 20:48 UTC (permalink / raw)
  To: Eduard Zingerman, Alexei Starovoitov, Andrii Nakryiko,
	Daniel Borkmann, Kumar Kartikeya Dwivedi
  Cc: Alan Maguire, Jiri Olsa, Emil Tsalapatis, bpf

On 8/6/26 12:05 PM, Eduard Zingerman wrote:
> On Wed, 2026-08-05 at 16:06 -0700, Ihor Solodrai wrote:
>> btf2btf() adds new types to the BTF: the KF_IMPLICIT_ARGS transform
>> synthesizes an _impl FUNC together with its FUNC_PROTO and copies of the
>> kfunc's decl tags. Nothing deduplicates them afterwards. pahole runs
>> btf__dedup() on its own output, but that happens before resolve_btfids
>> sees the BTF, so any type the tool itself creates is emitted as-is, even
>> when a structurally identical type is already present.
>>
>> Call btf__dedup() at the start of finalize_btf(), so that base
>> distillation and the by-name sort both operate on the canonical set of
>> types.
>>
>> Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
>> ---
> 
> Hi Ihor,
> 
> I'm curious if you had a chance to measure how this affects the
> resolve_btfids running time?

Yes I did. tl;dr is +30-40% runtime for resolve_btfids:

  0.18424  +- 0.00174  seconds time elapsed  ( +-  0.94% )   without dedup
  0.257003 +- 0.000473 seconds time elapsed  ( +-  0.18% )   with dedup

So that's the bad news.

The good news is that it shouldn't grow, because most of the dedup
time is just walking BTF. We emit very few types.

I think it's worth taking a hit, because a non-normalized kernel BTF
is a petri dish for bugs.

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

* Re: [PATCH bpf-next v2 1/6] resolve_btfids: Deduplicate BTF after btf2btf transformations
  2026-08-06 20:48     ` Ihor Solodrai
@ 2026-08-06 20:52       ` Eduard Zingerman
  0 siblings, 0 replies; 27+ messages in thread
From: Eduard Zingerman @ 2026-08-06 20:52 UTC (permalink / raw)
  To: Ihor Solodrai, Alexei Starovoitov, Andrii Nakryiko,
	Daniel Borkmann, Kumar Kartikeya Dwivedi
  Cc: Alan Maguire, Jiri Olsa, Emil Tsalapatis, bpf

On Thu, 2026-08-06 at 13:48 -0700, Ihor Solodrai wrote:
> On 8/6/26 12:05 PM, Eduard Zingerman wrote:
> > On Wed, 2026-08-05 at 16:06 -0700, Ihor Solodrai wrote:
> > > btf2btf() adds new types to the BTF: the KF_IMPLICIT_ARGS transform
> > > synthesizes an _impl FUNC together with its FUNC_PROTO and copies of the
> > > kfunc's decl tags. Nothing deduplicates them afterwards. pahole runs
> > > btf__dedup() on its own output, but that happens before resolve_btfids
> > > sees the BTF, so any type the tool itself creates is emitted as-is, even
> > > when a structurally identical type is already present.
> > > 
> > > Call btf__dedup() at the start of finalize_btf(), so that base
> > > distillation and the by-name sort both operate on the canonical set of
> > > types.
> > > 
> > > Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
> > > ---
> > 
> > Hi Ihor,
> > 
> > I'm curious if you had a chance to measure how this affects the
> > resolve_btfids running time?
> 
> Yes I did. tl;dr is +30-40% runtime for resolve_btfids:
> 
>   0.18424  +- 0.00174  seconds time elapsed  ( +-  0.94% )   without dedup
>   0.257003 +- 0.000473 seconds time elapsed  ( +-  0.18% )   with dedup
>
> So that's the bad news.
> 
> The good news is that it shouldn't grow, because most of the dedup
> time is just walking BTF. We emit very few types.
> 
> I think it's worth taking a hit, because a non-normalized kernel BTF
> is a petri dish for bugs.

Thx, not that scary then.

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

* Re: [PATCH bpf-next v2 2/6] resolve_btfids: Process KF_ARENA_* flags in resolve_btfids
  2026-08-06 19:12   ` Eduard Zingerman
@ 2026-08-06 21:02     ` Ihor Solodrai
  2026-08-06 21:12       ` Eduard Zingerman
  0 siblings, 1 reply; 27+ messages in thread
From: Ihor Solodrai @ 2026-08-06 21:02 UTC (permalink / raw)
  To: Eduard Zingerman, Alexei Starovoitov, Andrii Nakryiko,
	Daniel Borkmann, Kumar Kartikeya Dwivedi
  Cc: Alan Maguire, Jiri Olsa, Emil Tsalapatis, bpf

On 8/6/26 12:12 PM, Eduard Zingerman wrote:
> On Wed, 2026-08-05 at 16:06 -0700, Ihor Solodrai wrote:
> 
> ...
> 
>> +static s32 add_arena_tagged_proto(struct btf *btf, struct kfunc *kfunc)
>> +{
>> +	const struct btf_type *func = btf__type_by_id(btf, kfunc->btf_id);
>> +	u32 proto_id = func->type;
>> +	const struct btf_type *proto = btf__type_by_id(btf, proto_id);
>> +	const struct btf_param *params = btf_params(proto);
>> +	u32 nr_params = btf_vlen(proto);
>> +	s32 arg0_type_id = nr_params > 0 ? (s32)params[0].type : -1;
>> +	s32 arg1_type_id = nr_params > 1 ? (s32)params[1].type : -1;
>> +	s32 new_proto_id, id, param_type_id;
>> +	s32 ret_type_id = proto->type;
>> +	const char *name;
>> +	int err;
>> +
>> +	if (kfunc->flags & KF_ARENA_RET) {
>> +		id = arena_tag_ptr(btf, ret_type_id);
>> +		if (id < 0) {
>> +			pr_err("ERROR: resolve_btfids: kfunc %s: KF_ARENA_RET but return type is not a pointer\n",
>> +			       kfunc->name);
>> +			return id;
>> +		}
>> +		ret_type_id = id;
>> +	}
>> +
>> +	if (kfunc->flags & KF_ARENA_ARG1) {
> 
> Nit: let's avoid the copy paste and make this code prepared for the
>      __arena suffixes by moving the logic inside the parameter
>      processing loop below:
> 
>      for (i in params) {
>        bool add_tag = false;
> 
>        param_type_id = params[i].type;
>        switch(i) { 0: add_tag = kfunc->flags & KF_ARENA_ARG1; break; ... }
>        if (add_tag)
>           param_type_id = arena_tag_ptr(btf, param_type_id);
>        if (param_type_id < 0)
>          ...
>      }

Makes sense. Will do.

> 
>> +		if (nr_params < 1) {
>> +			pr_err("ERROR: resolve_btfids: kfunc %s: KF_ARENA_ARG1 but it has no argument 1\n",
>> +			       kfunc->name);
>> +			return -EINVAL;
>> +		}
>> +		id = arena_tag_ptr(btf, arg0_type_id);
>> +		if (id < 0) {
>> +			pr_err("ERROR: resolve_btfids: kfunc %s: KF_ARENA_ARG1 but argument 1 is not a pointer\n",
>> +			       kfunc->name);
> 
> Nit: not a pointer is not the only error condition, btf__add_*()
>      functions might fail as well, maybe just push pr_err() down
>      to the arena_tag_ptr()?

I guess the question is how much details do we want from the error
messages here. Since this is a part of kernel build pipeline that can
block it, I'd err on the side of more details.

I'll see if I can simplify this though.

> 
>> +			return id;
>> +		}
>> +		arg0_type_id = id;
>> +	}
>> +
>> +	if (kfunc->flags & KF_ARENA_ARG2) {
>> +		if (nr_params < 2) {
>> +			pr_err("ERROR: resolve_btfids: kfunc %s: KF_ARENA_ARG2 but it has no argument 2\n",
>> +			       kfunc->name);
>> +			return -EINVAL;
>> +		}
>> +		id = arena_tag_ptr(btf, arg1_type_id);
>> +		if (id < 0) {
>> +			pr_err("ERROR: resolve_btfids: kfunc %s: KF_ARENA_ARG2 but argument 2 is not a pointer\n",
>> +			       kfunc->name);
>> +			return id;
>> +		}
>> +		arg1_type_id = id;
>> +	}
>> +
>> +	new_proto_id = btf__add_func_proto(btf, ret_type_id);
>> +	if (new_proto_id < 0) {
>> +		pr_err("ERROR: resolve_btfids: kfunc %s: failed to add a func proto to BTF\n",
>> +		       kfunc->name);
>> +		return new_proto_id;
>> +	}
>> +
>> +	for (u32 i = 0; i < nr_params; i++) {
>> +		proto = btf__type_by_id(btf, proto_id);
>> +		params = btf_params(proto);
> 
> Nit: these two do not need to be in the loop body.

They do, because btf__add_func_param() below may move the proto
pointer, no?

> 
>> +		name = btf__name_by_offset(btf, params[i].name_off);
>> +
>> +		switch (i) {
>> +		case 0:
>> +			param_type_id = arg0_type_id;
>> +			break;
>> +		case 1:
>> +			param_type_id = arg1_type_id;
>> +			break;
>> +		default:
>> +			param_type_id = params[i].type;
>> +			break;
>> +		}
>> +
>> +		err = btf__add_func_param(btf, name ?: "", param_type_id);
>> +		if (err < 0) {
>> +			pr_err("ERROR: resolve_btfids: kfunc %s: failed to add a proto param to BTF\n",
>> +			       kfunc->name);
>> +			return err;
>> +		}
>> +	}
>> +
>> +	pr_debug("added arena-tagged proto for kfunc %s: %d\n", kfunc->name, new_proto_id);
>> +
>> +	return new_proto_id;
>> +}
> 
> ...


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

* Re: [PATCH bpf-next v2 6/6] docs, resolve_btfids: Document kfunc BTF annotation emission
  2026-08-06 19:47   ` Eduard Zingerman
@ 2026-08-06 21:06     ` Ihor Solodrai
  2026-08-06 21:17       ` Eduard Zingerman
  0 siblings, 1 reply; 27+ messages in thread
From: Ihor Solodrai @ 2026-08-06 21:06 UTC (permalink / raw)
  To: Eduard Zingerman, Alexei Starovoitov, Andrii Nakryiko,
	Daniel Borkmann, Kumar Kartikeya Dwivedi
  Cc: Alan Maguire, Jiri Olsa, Emil Tsalapatis, bpf

On 8/6/26 12:47 PM, Eduard Zingerman wrote:
> On Wed, 2026-08-05 at 16:06 -0700, Ihor Solodrai wrote:
> 
> ...
> 
>> diff --git a/Documentation/bpf/kfuncs.rst b/Documentation/bpf/kfuncs.rst
>> index cbde86d082cc..c60fc574e8b0 100644
>> --- a/Documentation/bpf/kfuncs.rst
>> +++ b/Documentation/bpf/kfuncs.rst
>> @@ -472,6 +472,14 @@ type. An example is shown below::
>>          }
>>          late_initcall(init_subsystem);
>>  
>> +At kernel build time the ``resolve_btfids`` tool discovers all kfuncs from the
>> +registered ``BTF_SET8_KFUNCS`` sets and emits their BTF annotations into the
> 
> Note that this is a single occurrence of the word BTF_SET8_KFUNCS in
> this .rst file. Also The wording "registered" is confusing as the
> above code snippet shows the usage of register_btf_kfunc_id_set()
> function, which is completely unrelated.
> 
>> +kernel's BTF; these annotations were historically produced by pahole. For each
> 
> I'd skip a note about pahole, it does not convey usable information.

ack

> 
>> +discovered kfunc ``resolve_btfids`` emits a ``bpf_kfunc`` BTF decl tag, a
>> +``bpf_fastcall`` decl tag when the kfunc is flagged ``KF_FASTCALL``, and the
>> +``address_space(1)`` type attribute on the return value and/or arguments flagged
>> +``KF_ARENA_RET``, ``KF_ARENA_ARG1`` or ``KF_ARENA_ARG2`` (see section 2.8).
>> +
>>  2.7  Specifying no-cast aliases with ___init
>>  --------------------------------------------
>>  
>> diff --git a/Documentation/process/changes.rst b/Documentation/process/changes.rst
>> index 1ca8c5f73ad0..6d1dbe4abf0f 100644
>> --- a/Documentation/process/changes.rst
>> +++ b/Documentation/process/changes.rst
>> @@ -147,10 +147,9 @@ Since Linux 5.2, if CONFIG_DEBUG_INFO_BTF is selected, the build system
>>  generates BTF (BPF Type Format) from DWARF in vmlinux, a bit later from kernel
>>  modules as well.  This requires pahole v1.22 or later.
>>  
>> -Since Linux 7.0, kfuncs annotated with KF_IMPLICIT_ARGS require pahole v1.26
>> -or later.  Without it, such kfuncs will have incorrect BTF prototypes in
>> -vmlinux, causing BPF programs to fail to load with a "func_proto incompatible
>> -with vmlinux" error.  Many sched_ext kfuncs are affected.
>> +Kfunc BTF annotations (the bpf_kfunc and bpf_fastcall decl tags and the arena
>> +address_space(1) type attribute) are emitted in-tree by resolve_btfids from the
>> +BTF_KFUNCS sets, so they no longer depend on a specific pahole version.
> 
> Just drop the whole paragraph?

hmm... yeah you're right

> 
>>  
>>  It is found in the 'dwarves' or 'pahole' distro packages or from
>>  https://fedorapeople.org/~acme/dwarves/.
>> diff --git a/scripts/Makefile.btf b/scripts/Makefile.btf
>> index a1812985a61a..717e76ce96a7 100644
>> --- a/scripts/Makefile.btf
>> +++ b/scripts/Makefile.btf
>> @@ -14,6 +14,9 @@ pahole-flags-$(call test-ge, $(pahole-ver), 125)	+= --skip_encoding_btf_inconsis
>>  else
>>  
>>  # Switch to using --btf_features for v1.26 and later.
>> +#
>> +# kfunc BTF annotations (bpf_kfunc/bpf_fastcall decl tags and the arena
>> +# address_space(1) type attribute) are emitted by resolve_btfids, not pahole.
> 
> What's the point of this comment?

The point is to inform the reader "where did decl_tag_kfuncs go?".
Question is whether the git log will be enough, or is a comment
also appropriate?

> 
>>  pahole-flags-$(call test-ge, $(pahole-ver), 126)  = -j$(JOBS) --btf_features=encode_force,var,float,enum64,decl_tag,type_tag,optimized_func,consistent_func
>>  
>>  pahole-flags-$(call test-ge, $(pahole-ver), 131) += --btf_features=layout
> 
> ...


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

* Re: [PATCH bpf-next v2 3/6] selftests/bpf: Verify arena type tags in resolve_btfids test
  2026-08-05 23:17   ` sashiko-bot
@ 2026-08-06 21:09     ` Ihor Solodrai
  0 siblings, 0 replies; 27+ messages in thread
From: Ihor Solodrai @ 2026-08-06 21:09 UTC (permalink / raw)
  To: sashiko-reviews; +Cc: bpf

On 8/5/26 4:17 PM, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [Medium] Missing NULL pointer check on the result of `btf__type_by_id()` causes a segmentation fault when a kfunc symbol is missing.
> --
> 
> --- Patch [3]: [PATCH bpf-next v2 3/6] selftests/bpf: Verify arena type tags in resolve_btfids test ---
> commit 833ac8bbb8ac1055e25790da1396864987e31541
> Author: Ihor Solodrai <ihor.solodrai@linux.dev>
> 
> selftests/bpf: Verify arena type tags in resolve_btfids test
> 
> This commit extends test_resolve_btfids() to assert that resolve_btfids
> emits the address_space(1) type attribute on the return type and arguments
> of kfuncs marked with KF_ARENA_RET, KF_ARENA_ARG1 or KF_ARENA_ARG2.
> 
>> diff --git a/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c b/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c
>> index ac51fd4548214..8482f00046d4c 100644
>> --- a/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c
>> +++ b/tools/testing/selftests/bpf/prog_tests/resolve_btfids.c
> [ ... ]
>> @@ -227,6 +260,39 @@ void test_resolve_btfids(void)
>>  	check_kfunc_set(&test_kfunc_set);
>>  	check_kfunc_set(&test_kfunc_set_rev);
>>  
>> +	/*
>> +	 * Check resolve_btfids wrapped exactly the arena-flagged return/args
>> +	 * with the address_space(1) type attribute, and left other
>> +	 * pointers/returns untouched.
>> +	 */
>> +	for (i = 0; i < ARRAY_SIZE(kfunc_symbols); i++) {
>> +		const struct btf_type *fn, *proto;
>> +		const struct btf_param *params;
>> +		const char *name = kfunc_symbols[i].name;
>> +		u32 fl = kfunc_symbols[i].flags;
>> +		__u32 nr;
>> +
>> +		fn = btf__type_by_id(btf, kfunc_symbols[i].id);
>> +		if (!ASSERT_TRUE(btf_is_func(fn), name))
>> +			continue;
> 
> [Severity: Medium]
> Could this cause a segmentation fault if a kfunc symbol is missing?
> 
> If resolve_symbols() fails to find a kfunc in the parsed BTF file, the
> symbol's id remains -1. When -1 is passed to btf__type_by_id(), it
> returns NULL.
> 
> Since btf_is_func() unconditionally accesses the info member, passing a
> NULL pointer to it would crash the test program before the ASSERT_TRUE
> evaluates.
> 
> Should we check if fn is NULL before passing it to btf_is_func()?

We are fine with the test program crashing here. Wontfix.

> 
>> +		proto = btf__type_by_id(btf, fn->type);
>> +		if (!ASSERT_TRUE(btf_is_func_proto(proto), name))
>> +			continue;
> [ ... ]
> 


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

* Re: [PATCH bpf-next v2 6/6] docs, resolve_btfids: Document kfunc BTF annotation emission
  2026-08-05 23:16   ` sashiko-bot
@ 2026-08-06 21:12     ` Ihor Solodrai
  0 siblings, 0 replies; 27+ messages in thread
From: Ihor Solodrai @ 2026-08-06 21:12 UTC (permalink / raw)
  To: sashiko-reviews; +Cc: bpf

On 8/5/26 4:16 PM, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [Medium] The minimum required pahole version in the changes.rst table was not reverted to 1.22 after its dependency on 1.26 was removed.
> --
> 
> --- Patch [6]: [PATCH bpf-next v2 6/6] docs, resolve_btfids: Document kfunc BTF annotation emission ---
> commit b5222d5ea4c3ea695d12ac70fc23f3fbadabd591
> Author: Ihor Solodrai <ihor.solodrai@linux.dev>
> 
> docs, resolve_btfids: Document kfunc BTF annotation emission
> 
> This commit updates documentation and comments to clarify that resolve_btfids
> now emits BTF annotations for kfuncs instead of pahole. It modifies
> changes.rst to reflect that a specific pahole version is no longer required
> for these annotations.
> 
>> diff --git a/Documentation/process/changes.rst b/Documentation/process/changes.rst
>> index 1ca8c5f73ad00..6d1dbe4abf0f0 100644
>> --- a/Documentation/process/changes.rst
>> +++ b/Documentation/process/changes.rst
> [ ... ]
>> @@ -147,10 +147,9 @@ Since Linux 5.2, if CONFIG_DEBUG_INFO_BTF is selected, the build system
>>  generates BTF (BPF Type Format) from DWARF in vmlinux, a bit later from kernel
>>  modules as well.  This requires pahole v1.22 or later.
>>  
>> -Since Linux 7.0, kfuncs annotated with KF_IMPLICIT_ARGS require pahole v1.26
>> -or later.  Without it, such kfuncs will have incorrect BTF prototypes in
>> -vmlinux, causing BPF programs to fail to load with a "func_proto incompatible
>> -with vmlinux" error.  Many sched_ext kfuncs are affected.
>> +Kfunc BTF annotations (the bpf_kfunc and bpf_fastcall decl tags and the arena
>> +address_space(1) type attribute) are emitted in-tree by resolve_btfids from the
>> +BTF_KFUNCS sets, so they no longer depend on a specific pahole version.
>>  
>>  It is found in the 'dwarves' or 'pahole' distro packages or from
>>  https://fedorapeople.org/~acme/dwarves/.
> 
> [Severity: Medium]
> Since this removes the dependency on pahole 1.26, should the minimum
> required version in the "Current Minimal Requirements" table earlier in
> this file be reverted to 1.22?

That's a good question. I'd like to check what pahole version is
actually minimal with this series.

But this is not a blocker for the series.


> 
> The table currently still lists 1.26:
> 
> Documentation/process/changes.rst:
>     openssl & libcrypto    1.0.0            openssl version
>     pahole                 1.26             pahole --version
>     pcmciautils            004              pccardctl -V
> 


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

* Re: [PATCH bpf-next v2 2/6] resolve_btfids: Process KF_ARENA_* flags in resolve_btfids
  2026-08-06 21:02     ` Ihor Solodrai
@ 2026-08-06 21:12       ` Eduard Zingerman
  2026-08-06 21:16         ` Ihor Solodrai
  0 siblings, 1 reply; 27+ messages in thread
From: Eduard Zingerman @ 2026-08-06 21:12 UTC (permalink / raw)
  To: Ihor Solodrai, Alexei Starovoitov, Andrii Nakryiko,
	Daniel Borkmann, Kumar Kartikeya Dwivedi
  Cc: Alan Maguire, Jiri Olsa, Emil Tsalapatis, bpf

On Thu, 2026-08-06 at 14:02 -0700, Ihor Solodrai wrote:

...

> > > +		if (nr_params < 1) {
> > > +			pr_err("ERROR: resolve_btfids: kfunc %s: KF_ARENA_ARG1 but it has no argument 1\n",
> > > +			       kfunc->name);
> > > +			return -EINVAL;
> > > +		}
> > > +		id = arena_tag_ptr(btf, arg0_type_id);
> > > +		if (id < 0) {
> > > +			pr_err("ERROR: resolve_btfids: kfunc %s: KF_ARENA_ARG1 but argument 1 is not a pointer\n",
> > > +			       kfunc->name);
> > 
> > Nit: not a pointer is not the only error condition, btf__add_*()
> >      functions might fail as well, maybe just push pr_err() down
> >      to the arena_tag_ptr()?
> 
> I guess the question is how much details do we want from the error
> messages here. Since this is a part of kernel build pipeline that can
> block it, I'd err on the side of more details.
> 
> I'll see if I can simplify this though.

Well, we don't want the errors to lie either :)

> > 
> > > +			return id;
> > > +		}
> > > +		arg0_type_id = id;
> > > +	}
> > > +
> > > +	if (kfunc->flags & KF_ARENA_ARG2) {
> > > +		if (nr_params < 2) {
> > > +			pr_err("ERROR: resolve_btfids: kfunc %s: KF_ARENA_ARG2 but it has no argument 2\n",
> > > +			       kfunc->name);
> > > +			return -EINVAL;
> > > +		}
> > > +		id = arena_tag_ptr(btf, arg1_type_id);
> > > +		if (id < 0) {
> > > +			pr_err("ERROR: resolve_btfids: kfunc %s: KF_ARENA_ARG2 but argument 2 is not a pointer\n",
> > > +			       kfunc->name);
> > > +			return id;
> > > +		}
> > > +		arg1_type_id = id;
> > > +	}
> > > +
> > > +	new_proto_id = btf__add_func_proto(btf, ret_type_id);
> > > +	if (new_proto_id < 0) {
> > > +		pr_err("ERROR: resolve_btfids: kfunc %s: failed to add a func proto to BTF\n",
> > > +		       kfunc->name);
> > > +		return new_proto_id;
> > > +	}
> > > +
> > > +	for (u32 i = 0; i < nr_params; i++) {
> > > +		proto = btf__type_by_id(btf, proto_id);
> > > +		params = btf_params(proto);
> > 
> > Nit: these two do not need to be in the loop body.
> 
> They do, because btf__add_func_param() below may move the proto
> pointer, no?

Huh, indeed.

> > > +		name = btf__name_by_offset(btf, params[i].name_off);
> > > +
> > > +		switch (i) {
> > > +		case 0:
> > > +			param_type_id = arg0_type_id;
> > > +			break;
> > > +		case 1:
> > > +			param_type_id = arg1_type_id;
> > > +			break;
> > > +		default:
> > > +			param_type_id = params[i].type;
> > > +			break;
> > > +		}
> > > +
> > > +		err = btf__add_func_param(btf, name ?: "", param_type_id);
> > > +		if (err < 0) {
> > > +			pr_err("ERROR: resolve_btfids: kfunc %s: failed to add a proto param to BTF\n",
> > > +			       kfunc->name);
> > > +			return err;
> > > +		}
> > > +	}
> > > +
> > > +	pr_debug("added arena-tagged proto for kfunc %s: %d\n", kfunc->name, new_proto_id);
> > > +
> > > +	return new_proto_id;
> > > +}
> > 
> > ...

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

* Re: [PATCH bpf-next v2 6/6] docs, resolve_btfids: Document kfunc BTF annotation emission
  2026-08-06  0:01   ` bot+bpf-ci
@ 2026-08-06 21:13     ` Ihor Solodrai
  0 siblings, 0 replies; 27+ messages in thread
From: Ihor Solodrai @ 2026-08-06 21:13 UTC (permalink / raw)
  To: bot+bpf-ci, ast, andrii, daniel, eddyz87, memxor
  Cc: alan.maguire, jolsa, emil, bpf, martin.lau, yonghong.song, clm

On 8/5/26 5:01 PM, bot+bpf-ci@kernel.org wrote:
>> diff --git a/Documentation/bpf/kfuncs.rst b/Documentation/bpf/kfuncs.rst
>> index cbde86d082cce..c60fc574e8b06 100644
>> --- a/Documentation/bpf/kfuncs.rst
>> +++ b/Documentation/bpf/kfuncs.rst
>> @@ -472,6 +472,14 @@ type. An example is shown below::
>>          }
>>          late_initcall(init_subsystem);
>>
>> +At kernel build time the ``resolve_btfids`` tool discovers all kfuncs from the
>> +registered ``BTF_SET8_KFUNCS`` sets and emits their BTF annotations into the
>> +kernel's BTF; these annotations were historically produced by pahole. For each
>> +discovered kfunc ``resolve_btfids`` emits a ``bpf_kfunc`` BTF decl tag, a
>> +``bpf_fastcall`` decl tag when the kfunc is flagged ``KF_FASTCALL``, and the
>> +``address_space(1)`` type attribute on the return value and/or arguments flagged
>> +``KF_ARENA_RET``, ``KF_ARENA_ARG1`` or ``KF_ARENA_ARG2`` (see section 2.8).
> 
> Emil Tsalapatis suggested in v1 replacing "address_space(1)" with "arena"
> throughout the documentation for better readability. This nit was not
> addressed in v2.
> 
> The term "address_space(1)" appears in four locations across this commit
> (kfuncs.rst, changes.rst, Makefile.btf, and main.c). Would using "arena"
> be clearer, especially since the code already defines TYPE_ATTR_ARENA?

Nonsense feedback from the bot. Ignoring.

> 
>> +
>>  2.7  Specifying no-cast aliases with ___init
>>  --------------------------------------------
>>
>> diff --git a/Documentation/process/changes.rst b/Documentation/process/changes.rst
>> index 1ca8c5f73ad00..6d1dbe4abf0f0 100644
>> --- a/Documentation/process/changes.rst
>> +++ b/Documentation/process/changes.rst
>> @@ -147,10 +147,9 @@ Since Linux 5.2, if CONFIG_DEBUG_INFO_BTF is selected, the build system
>>  generates BTF (BPF Type Format) from DWARF in vmlinux, a bit later from kernel
>>  modules as well.  This requires pahole v1.22 or later.
>>
>> -Since Linux 7.0, kfuncs annotated with KF_IMPLICIT_ARGS require pahole v1.26
>> -or later.  Without it, such kfuncs will have incorrect BTF prototypes in
>> -vmlinux, causing BPF programs to fail to load with a "func_proto incompatible
>> -with vmlinux" error.  Many sched_ext kfuncs are affected.
>> +Kfunc BTF annotations (the bpf_kfunc and bpf_fastcall decl tags and the arena
>> +address_space(1) type attribute) are emitted in-tree by resolve_btfids from the
>> +BTF_KFUNCS sets, so they no longer depend on a specific pahole version.
>>
>>  It is found in the 'dwarves' or 'pahole' distro packages or from
>>  https://fedorapeople.org/~acme/dwarves/.
>> diff --git a/scripts/Makefile.btf b/scripts/Makefile.btf
>> index a1812985a61aa..717e76ce96a71 100644
>> --- a/scripts/Makefile.btf
>> +++ b/scripts/Makefile.btf
>> @@ -14,6 +14,9 @@ pahole-flags-$(call test-ge, $(pahole-ver), 125)	+= --skip_encoding_btf_inconsis
>>  else
>>
>>  # Switch to using --btf_features for v1.26 and later.
>> +#
>> +# kfunc BTF annotations (bpf_kfunc/bpf_fastcall decl tags and the arena
>> +# address_space(1) type attribute) are emitted by resolve_btfids, not pahole.
>>  pahole-flags-$(call test-ge, $(pahole-ver), 126)  = -j$(JOBS) --btf_features=encode_force,var,float,enum64,decl_tag,type_tag,optimized_func,consistent_func
>>
>>  pahole-flags-$(call test-ge, $(pahole-ver), 131) += --btf_features=layout
>> diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
>> index ea25ca34aa006..66f4014e6aa17 100644
>> --- a/tools/bpf/resolve_btfids/main.c
>> +++ b/tools/bpf/resolve_btfids/main.c
>> @@ -58,6 +58,17 @@
>>   *             __BTF_ID__func__vfs_fallocate__5:
>>   *             .zero 4
>>   *	       .word (1 << 3) | (1 << 1) | (1 << 2)
>> + *
>> + * In addition to resolving BTF IDs, resolve_btfids performs kernel-specific
>> + * BTF-to-BTF transformations for kfuncs found in BTF_SET8_KFUNCS sets. For
>> + * each such kfunc it:
>> + *
>> + *   - emits a "bpf_kfunc" decl tag, and "bpf_fastcall" when KF_FASTCALL is set;
>> + *   - wraps the return value and/or arguments flagged KF_ARENA_RET,
>> + *     KF_ARENA_ARG1 or KF_ARENA_ARG2 with the "address_space(1)" type attribute;
>> + *   - rewrites the prototype of KF_IMPLICIT_ARGS kfuncs.
>> + *
>> + * These kfunc annotations were historically produced by pahole.
>>   */
>>
>>  #define  _GNU_SOURCE
> 
> 
> ---
> AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
> See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
> 
> CI run summary: https://github.com/kernel-patches/bpf/actions/runs/31056256483


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

* Re: [PATCH bpf-next v2 2/6] resolve_btfids: Process KF_ARENA_* flags in resolve_btfids
  2026-08-06 21:12       ` Eduard Zingerman
@ 2026-08-06 21:16         ` Ihor Solodrai
  0 siblings, 0 replies; 27+ messages in thread
From: Ihor Solodrai @ 2026-08-06 21:16 UTC (permalink / raw)
  To: Eduard Zingerman, Alexei Starovoitov, Andrii Nakryiko,
	Daniel Borkmann, Kumar Kartikeya Dwivedi
  Cc: Alan Maguire, Jiri Olsa, Emil Tsalapatis, bpf

On 8/6/26 2:12 PM, Eduard Zingerman wrote:
> On Thu, 2026-08-06 at 14:02 -0700, Ihor Solodrai wrote:
> 
> ...
> 
>>>> +		if (nr_params < 1) {
>>>> +			pr_err("ERROR: resolve_btfids: kfunc %s: KF_ARENA_ARG1 but it has no argument 1\n",
>>>> +			       kfunc->name);
>>>> +			return -EINVAL;
>>>> +		}
>>>> +		id = arena_tag_ptr(btf, arg0_type_id);
>>>> +		if (id < 0) {
>>>> +			pr_err("ERROR: resolve_btfids: kfunc %s: KF_ARENA_ARG1 but argument 1 is not a pointer\n",
>>>> +			       kfunc->name);
>>>
>>> Nit: not a pointer is not the only error condition, btf__add_*()
>>>      functions might fail as well, maybe just push pr_err() down
>>>      to the arena_tag_ptr()?
>>
>> I guess the question is how much details do we want from the error
>> messages here. Since this is a part of kernel build pipeline that can
>> block it, I'd err on the side of more details.
>>
>> I'll see if I can simplify this though.
> 
> Well, we don't want the errors to lie either :)

Why not? We can create many beautiful debugging evenings for the people,
and now for AIs too!

:bilbo_why_shouldnt_I_meme:

> 
>>>
>>>> +			return id;
>>>> +		}
>>>> +		arg0_type_id = id;
>>>> +	}
>>>> +
>>>> +	if (kfunc->flags & KF_ARENA_ARG2) {
>>>> +		if (nr_params < 2) {
>>>> +			pr_err("ERROR: resolve_btfids: kfunc %s: KF_ARENA_ARG2 but it has no argument 2\n",
>>>> +			       kfunc->name);
>>>> +			return -EINVAL;
>>>> +		}
>>>> +		id = arena_tag_ptr(btf, arg1_type_id);
>>>> +		if (id < 0) {
>>>> +			pr_err("ERROR: resolve_btfids: kfunc %s: KF_ARENA_ARG2 but argument 2 is not a pointer\n",
>>>> +			       kfunc->name);
>>>> +			return id;
>>>> +		}
>>>> +		arg1_type_id = id;
>>>> +	}
>>>> +
>>>> +	new_proto_id = btf__add_func_proto(btf, ret_type_id);
>>>> +	if (new_proto_id < 0) {
>>>> +		pr_err("ERROR: resolve_btfids: kfunc %s: failed to add a func proto to BTF\n",
>>>> +		       kfunc->name);
>>>> +		return new_proto_id;
>>>> +	}
>>>> +
>>>> +	for (u32 i = 0; i < nr_params; i++) {
>>>> +		proto = btf__type_by_id(btf, proto_id);
>>>> +		params = btf_params(proto);
>>>
>>> Nit: these two do not need to be in the loop body.
>>
>> They do, because btf__add_func_param() below may move the proto
>> pointer, no?
> 
> Huh, indeed.
> 
>>>> +		name = btf__name_by_offset(btf, params[i].name_off);
>>>> +
>>>> +		switch (i) {
>>>> +		case 0:
>>>> +			param_type_id = arg0_type_id;
>>>> +			break;
>>>> +		case 1:
>>>> +			param_type_id = arg1_type_id;
>>>> +			break;
>>>> +		default:
>>>> +			param_type_id = params[i].type;
>>>> +			break;
>>>> +		}
>>>> +
>>>> +		err = btf__add_func_param(btf, name ?: "", param_type_id);
>>>> +		if (err < 0) {
>>>> +			pr_err("ERROR: resolve_btfids: kfunc %s: failed to add a proto param to BTF\n",
>>>> +			       kfunc->name);
>>>> +			return err;
>>>> +		}
>>>> +	}
>>>> +
>>>> +	pr_debug("added arena-tagged proto for kfunc %s: %d\n", kfunc->name, new_proto_id);
>>>> +
>>>> +	return new_proto_id;
>>>> +}
>>>
>>> ...


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

* Re: [PATCH bpf-next v2 6/6] docs, resolve_btfids: Document kfunc BTF annotation emission
  2026-08-06 21:06     ` Ihor Solodrai
@ 2026-08-06 21:17       ` Eduard Zingerman
  2026-08-06 21:19         ` Ihor Solodrai
  0 siblings, 1 reply; 27+ messages in thread
From: Eduard Zingerman @ 2026-08-06 21:17 UTC (permalink / raw)
  To: Ihor Solodrai, Alexei Starovoitov, Andrii Nakryiko,
	Daniel Borkmann, Kumar Kartikeya Dwivedi
  Cc: Alan Maguire, Jiri Olsa, Emil Tsalapatis, bpf

On Thu, 2026-08-06 at 14:06 -0700, Ihor Solodrai wrote:

...

> > > @@ -14,6 +14,9 @@ pahole-flags-$(call test-ge, $(pahole-ver), 125)	+= --skip_encoding_btf_inconsis
> > >  else
> > >  
> > >  # Switch to using --btf_features for v1.26 and later.
> > > +#
> > > +# kfunc BTF annotations (bpf_kfunc/bpf_fastcall decl tags and the arena
> > > +# address_space(1) type attribute) are emitted by resolve_btfids, not pahole.
> > 
> > What's the point of this comment?
> 
> The point is to inform the reader "where did decl_tag_kfuncs go?".
> Question is whether the git log will be enough, or is a comment
> also appropriate?

I don't think we don't do this usually. E.g. it would be a first such
comment in this makefile. Also, the comment looks suspiciously like
something Claude inserts :)

> > 
> > >  pahole-flags-$(call test-ge, $(pahole-ver), 126)  = -j$(JOBS) --btf_features=encode_force,var,float,enum64,decl_tag,type_tag,optimized_func,consistent_func
> > >  
> > >  pahole-flags-$(call test-ge, $(pahole-ver), 131) += --btf_features=layout
> > 
> > ...

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

* Re: [PATCH bpf-next v2 6/6] docs, resolve_btfids: Document kfunc BTF annotation emission
  2026-08-06 21:17       ` Eduard Zingerman
@ 2026-08-06 21:19         ` Ihor Solodrai
  0 siblings, 0 replies; 27+ messages in thread
From: Ihor Solodrai @ 2026-08-06 21:19 UTC (permalink / raw)
  To: Eduard Zingerman, Alexei Starovoitov, Andrii Nakryiko,
	Daniel Borkmann, Kumar Kartikeya Dwivedi
  Cc: Alan Maguire, Jiri Olsa, Emil Tsalapatis, bpf

On 8/6/26 2:17 PM, Eduard Zingerman wrote:
> On Thu, 2026-08-06 at 14:06 -0700, Ihor Solodrai wrote:
> 
> ...
> 
>>>> @@ -14,6 +14,9 @@ pahole-flags-$(call test-ge, $(pahole-ver), 125)	+= --skip_encoding_btf_inconsis
>>>>  else
>>>>  
>>>>  # Switch to using --btf_features for v1.26 and later.
>>>> +#
>>>> +# kfunc BTF annotations (bpf_kfunc/bpf_fastcall decl tags and the arena
>>>> +# address_space(1) type attribute) are emitted by resolve_btfids, not pahole.
>>>
>>> What's the point of this comment?
>>
>> The point is to inform the reader "where did decl_tag_kfuncs go?".
>> Question is whether the git log will be enough, or is a comment
>> also appropriate?
> 
> I don't think we don't do this usually. E.g. it would be a first such
> comment in this makefile. Also, the comment looks suspiciously like
> something Claude inserts :)

It was written by Claude, that is true.

I removed many generated comments, AIs *love* comments.
But this wasn't one of them.

Will clean up.

> 
>>>
>>>>  pahole-flags-$(call test-ge, $(pahole-ver), 126)  = -j$(JOBS) --btf_features=encode_force,var,float,enum64,decl_tag,type_tag,optimized_func,consistent_func
>>>>  
>>>>  pahole-flags-$(call test-ge, $(pahole-ver), 131) += --btf_features=layout
>>>
>>> ...


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

end of thread, other threads:[~2026-08-06 21:19 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-05 23:06 [PATCH bpf-next v2 0/6] resolve_btfids: Implement BTF tags emission for kfuncs Ihor Solodrai
2026-08-05 23:06 ` [PATCH bpf-next v2 1/6] resolve_btfids: Deduplicate BTF after btf2btf transformations Ihor Solodrai
2026-08-06 19:05   ` Eduard Zingerman
2026-08-06 20:48     ` Ihor Solodrai
2026-08-06 20:52       ` Eduard Zingerman
2026-08-05 23:06 ` [PATCH bpf-next v2 2/6] resolve_btfids: Process KF_ARENA_* flags in resolve_btfids Ihor Solodrai
2026-08-06 19:12   ` Eduard Zingerman
2026-08-06 21:02     ` Ihor Solodrai
2026-08-06 21:12       ` Eduard Zingerman
2026-08-06 21:16         ` Ihor Solodrai
2026-08-05 23:06 ` [PATCH bpf-next v2 3/6] selftests/bpf: Verify arena type tags in resolve_btfids test Ihor Solodrai
2026-08-05 23:17   ` sashiko-bot
2026-08-06 21:09     ` Ihor Solodrai
2026-08-06 19:15   ` Eduard Zingerman
2026-08-05 23:06 ` [PATCH bpf-next v2 4/6] resolve_btfids: Emit bpf_kfunc and bpf_fastcall decl tags Ihor Solodrai
2026-08-06 19:18   ` Eduard Zingerman
2026-08-05 23:06 ` [PATCH bpf-next v2 5/6] selftests/bpf: Verify decl tags emission in resolve_btfids test Ihor Solodrai
2026-08-06 19:20   ` Eduard Zingerman
2026-08-05 23:06 ` [PATCH bpf-next v2 6/6] docs, resolve_btfids: Document kfunc BTF annotation emission Ihor Solodrai
2026-08-05 23:16   ` sashiko-bot
2026-08-06 21:12     ` Ihor Solodrai
2026-08-06  0:01   ` bot+bpf-ci
2026-08-06 21:13     ` Ihor Solodrai
2026-08-06 19:47   ` Eduard Zingerman
2026-08-06 21:06     ` Ihor Solodrai
2026-08-06 21:17       ` Eduard Zingerman
2026-08-06 21:19         ` Ihor Solodrai

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox