From: Chengkaitao <pilgrimtao@gmail.com>
To: arnd@arndb.de, ast@kernel.org, ihor.solodrai@linux.dev,
daniel@iogearbox.net, andrii@kernel.org, martin.lau@linux.dev,
eddyz87@gmail.com, memxor@gmail.com, song@kernel.org,
yonghong.song@linux.dev, jolsa@kernel.org,
john.fastabend@gmail.com, pengdonglin@xiaomi.com
Cc: linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org,
bpf@vger.kernel.org, Kaitao Cheng <chengkaitao@kylinos.cn>
Subject: [PATCH bpf-next 2/3] bpf: Introduce BTF_SET/ID_SUB and BPF_VERIF_KFUNC_DEF
Date: Sat, 4 Apr 2026 01:08:56 +0800 [thread overview]
Message-ID: <20260403170900.58659-3-pilgrimtao@gmail.com> (raw)
In-Reply-To: <20260403170900.58659-1-pilgrimtao@gmail.com>
From: Kaitao Cheng <chengkaitao@kylinos.cn>
Use BTF_SET_SUB to provide the same kind of grouping as BTF_SET_START/END,
so BTF_ID_SUB no longer has to follow the strict sequence (BTF_SET_START,
BTF_ID, BTF_SET_END). That lets us scatter BTF_ID_SUB definitions across
the file and collect entries with similar properties together, which
reduces maintenance overhead.
Signed-off-by: Kaitao Cheng <chengkaitao@kylinos.cn>
---
include/linux/btf_ids.h | 92 +++++++++++++++++++++++++++++++----
tools/include/linux/btf_ids.h | 83 +++++++++++++++++++++++++++----
2 files changed, 156 insertions(+), 19 deletions(-)
diff --git a/include/linux/btf_ids.h b/include/linux/btf_ids.h
index af011db39ab3..c45275c88649 100644
--- a/include/linux/btf_ids.h
+++ b/include/linux/btf_ids.h
@@ -40,9 +40,9 @@ struct btf_id_set8 {
#define BTF_IDS_SECTION ".BTF_ids"
-#define ____BTF_ID(symbol, word) \
+#define ____BTF_ID(symbol, word, sec) \
asm( \
-".pushsection " BTF_IDS_SECTION ",\"a\"; \n" \
+".pushsection " sec ",\"a\"; \n" \
".local " #symbol " ; \n" \
".type " #symbol ", STT_OBJECT; \n" \
".size " #symbol ", 4; \n" \
@@ -52,7 +52,7 @@ word \
".popsection; \n");
#define __BTF_ID(symbol, word) \
- ____BTF_ID(symbol, word)
+ ____BTF_ID(symbol, word, BTF_IDS_SECTION)
#define __ID(prefix) \
__PASTE(__PASTE(prefix, __COUNTER__), __LINE__)
@@ -86,19 +86,19 @@ word \
* .zero 4
*
*/
-#define __BTF_ID_LIST(name, scope) \
+#define __BTF_ID_LIST(name, scope, sec) \
asm( \
-".pushsection " BTF_IDS_SECTION ",\"a\"; \n" \
+".pushsection " sec ",\"a\"; \n" \
"." #scope " " #name "; \n" \
#name ":; \n" \
".popsection; \n");
#define BTF_ID_LIST(name) \
-__BTF_ID_LIST(name, local) \
+__BTF_ID_LIST(name, local, BTF_IDS_SECTION) \
extern u32 name[];
#define BTF_ID_LIST_GLOBAL(name, n) \
-__BTF_ID_LIST(name, globl)
+__BTF_ID_LIST(name, globl, BTF_IDS_SECTION)
/* The BTF_ID_LIST_SINGLE macro defines a BTF_ID_LIST with
* a single entry.
@@ -154,11 +154,11 @@ asm( \
".popsection; \n");
#define BTF_SET_START(name) \
-__BTF_ID_LIST(name, local) \
+__BTF_ID_LIST(name, local, BTF_IDS_SECTION) \
__BTF_SET_START(name, local)
#define BTF_SET_START_GLOBAL(name) \
-__BTF_ID_LIST(name, globl) \
+__BTF_ID_LIST(name, globl, BTF_IDS_SECTION) \
__BTF_SET_START(name, globl)
#define BTF_SET_END(name) \
@@ -168,6 +168,75 @@ asm( \
".popsection; \n"); \
extern struct btf_id_set name;
+/*
+ * BTF_SET_SUB — place a set in .BTF_ids.<name> so vmlinux.lds.h can merge
+ * multiple input sections into one output .BTF_ids in a fixed order.
+ * <name> must be a single preprocessor token (e.g. bpf_verif_kfunc_arena).
+ *
+ * Member count: begin is __BTF_ID__setsc__<name> (first in .BTF_ids.<name>);
+ * end is linker symbol __BTF_ids_seg_end_<name> (see btf_ids.lds.h). resolve_btfids
+ * uses cnt = (end - begin) / 4 - 1. <name> must not contain "__seg__".
+ *
+ * extern struct btf_id_set name is emitted by BTF_SET_SUB. BTF_ID_SUB(name, ...)
+ * must use the same <name> as the subsection token.
+ */
+#define __BTF_IDS_SUBSEC(sub) ".BTF_ids." #sub
+
+/* Indirection so __ID() expands before ____BTF_ID() stringifies its symbol arg. */
+#define __BTF_ID_SUB(sym, sec) ____BTF_ID(sym, "", sec)
+
+#define BTF_ID_SUB(sub, prefix, name) \
+ __BTF_ID_SUB(__ID(__BTF_ID__##prefix##__##name##__), __BTF_IDS_SUBSEC(sub))
+
+#define __BTF_ID_LIST_SUB(name, scope) \
+ __BTF_ID_LIST(name, scope, __BTF_IDS_SUBSEC(name))
+
+#define __BTF_SET_SUB(name, scope) \
+asm( \
+".pushsection " __BTF_IDS_SUBSEC(name) ",\"a\"; \n" \
+"." #scope " __BTF_ID__setsc__" #name "; \n" \
+"__BTF_ID__setsc__" #name ":; \n" \
+".zero 4 \n" \
+".popsection; \n");
+
+#define BTF_SET_SUB(name) \
+extern struct btf_id_set name; \
+__BTF_ID_LIST_SUB(name, local) \
+__BTF_SET_SUB(name, local)
+
+#include <linux/args.h> /* CONCATENATE, COUNT_ARGS */
+
+/* bpf_verif_kfunc_<sub> (e.g. rbtree_add → bpf_verif_kfunc_rbtree_add) */
+#define __BPF_VERIF_KFUNC_SUB(sub) bpf_verif_kfunc_##sub
+
+/* Cascade: emit first subsection, recurse on the rest (same kfunc @name). Up to 6 subs. */
+#define __BPF_VERIF_KFUNC_DEF_1(name, s1) \
+ BTF_ID_SUB(__BPF_VERIF_KFUNC_SUB(s1), func, name)
+
+#define __BPF_VERIF_KFUNC_DEF_2(name, s1, s2) \
+ BTF_ID_SUB(__BPF_VERIF_KFUNC_SUB(s1), func, name) \
+ __BPF_VERIF_KFUNC_DEF_1(name, s2)
+
+#define __BPF_VERIF_KFUNC_DEF_3(name, s1, s2, s3) \
+ BTF_ID_SUB(__BPF_VERIF_KFUNC_SUB(s1), func, name) \
+ __BPF_VERIF_KFUNC_DEF_2(name, s2, s3)
+
+#define __BPF_VERIF_KFUNC_DEF_4(name, s1, s2, s3, s4) \
+ BTF_ID_SUB(__BPF_VERIF_KFUNC_SUB(s1), func, name) \
+ __BPF_VERIF_KFUNC_DEF_3(name, s2, s3, s4)
+
+#define __BPF_VERIF_KFUNC_DEF_5(name, s1, s2, s3, s4, s5) \
+ BTF_ID_SUB(__BPF_VERIF_KFUNC_SUB(s1), func, name) \
+ __BPF_VERIF_KFUNC_DEF_4(name, s2, s3, s4, s5)
+
+#define __BPF_VERIF_KFUNC_DEF_6(name, s1, s2, s3, s4, s5, s6) \
+ BTF_ID_SUB(__BPF_VERIF_KFUNC_SUB(s1), func, name) \
+ __BPF_VERIF_KFUNC_DEF_5(name, s2, s3, s4, s5, s6)
+
+/* First arg: kfunc symbol; rest: subsection suffix tokens matching bpf_verif_kfunc_<s>. */
+#define BPF_VERIF_KFUNC_DEF(name, ...) \
+ CONCATENATE(__BPF_VERIF_KFUNC_DEF_, COUNT_ARGS(__VA_ARGS__))(name, __VA_ARGS__)
+
/*
* The BTF_SET8_START/END macros pair defines sorted list of
* BTF IDs and their flags plus its members count, with the
@@ -190,7 +259,7 @@ extern struct btf_id_set name;
*
*/
#define __BTF_SET8_START(name, scope, flags) \
-__BTF_ID_LIST(name, local) \
+__BTF_ID_LIST(name, local, BTF_IDS_SECTION) \
asm( \
".pushsection " BTF_IDS_SECTION ",\"a\"; \n" \
"." #scope " __BTF_ID__set8__" #name "; \n" \
@@ -227,6 +296,9 @@ BTF_SET8_END(name)
#define BTF_SET_START(name) static struct btf_id_set __maybe_unused name = { 0 };
#define BTF_SET_START_GLOBAL(name) static struct btf_id_set __maybe_unused name = { 0 };
#define BTF_SET_END(name)
+#define BTF_SET_SUB(name) static struct btf_id_set __maybe_unused name = { 0 };
+#define BTF_ID_SUB(sub, prefix, name)
+#define BPF_VERIF_KFUNC_DEF(name, ...)
#define BTF_SET8_START(name) static struct btf_id_set8 __maybe_unused name = { 0 };
#define BTF_SET8_END(name)
#define BTF_KFUNCS_START(name) static struct btf_id_set8 __maybe_unused name = { .flags = BTF_SET8_KFUNCS };
diff --git a/tools/include/linux/btf_ids.h b/tools/include/linux/btf_ids.h
index 72ea363d434d..026fd5bfc6d5 100644
--- a/tools/include/linux/btf_ids.h
+++ b/tools/include/linux/btf_ids.h
@@ -35,9 +35,9 @@ struct btf_id_set8 {
#define BTF_IDS_SECTION ".BTF_ids"
-#define ____BTF_ID(symbol) \
+#define ____BTF_ID(symbol, sec) \
asm( \
-".pushsection " BTF_IDS_SECTION ",\"a\"; \n" \
+".pushsection " sec ",\"a\"; \n" \
".local " #symbol " ; \n" \
".type " #symbol ", STT_OBJECT; \n" \
".size " #symbol ", 4; \n" \
@@ -46,7 +46,7 @@ asm( \
".popsection; \n");
#define __BTF_ID(symbol) \
- ____BTF_ID(symbol)
+ ____BTF_ID(symbol, BTF_IDS_SECTION)
#define __ID(prefix) \
__PASTE(__PASTE(prefix, __COUNTER__), __LINE__)
@@ -73,19 +73,19 @@ asm( \
* .zero 4
*
*/
-#define __BTF_ID_LIST(name, scope) \
+#define __BTF_ID_LIST(name, scope, sec) \
asm( \
-".pushsection " BTF_IDS_SECTION ",\"a\"; \n" \
+".pushsection " sec ",\"a\"; \n" \
"." #scope " " #name "; \n" \
#name ":; \n" \
".popsection; \n");
#define BTF_ID_LIST(name) \
-__BTF_ID_LIST(name, local) \
+__BTF_ID_LIST(name, local, BTF_IDS_SECTION) \
extern u32 name[];
#define BTF_ID_LIST_GLOBAL(name, n) \
-__BTF_ID_LIST(name, globl)
+__BTF_ID_LIST(name, globl, BTF_IDS_SECTION)
/* The BTF_ID_LIST_SINGLE macro defines a BTF_ID_LIST with
* a single entry.
@@ -141,11 +141,11 @@ asm( \
".popsection; \n");
#define BTF_SET_START(name) \
-__BTF_ID_LIST(name, local) \
+__BTF_ID_LIST(name, local, BTF_IDS_SECTION) \
__BTF_SET_START(name, local)
#define BTF_SET_START_GLOBAL(name) \
-__BTF_ID_LIST(name, globl) \
+__BTF_ID_LIST(name, globl, BTF_IDS_SECTION) \
__BTF_SET_START(name, globl)
#define BTF_SET_END(name) \
@@ -155,6 +155,68 @@ asm( \
".popsection; \n"); \
extern struct btf_id_set name;
+/*
+ * See include/linux/btf_ids.h: BTF_SET_SUB uses __BTF_ids_seg_end_<name> in
+ * btf_ids.lds.h; begin is __BTF_ID__setsc__<name>. extern struct btf_id_set name
+ * is in BTF_SET_SUB.
+ */
+#define __BTF_IDS_SUBSEC(sub) ".BTF_ids." #sub
+
+/* Indirection so __ID() expands before ____BTF_ID() stringifies its symbol arg. */
+#define __BTF_ID_SUB(sym, sec) ____BTF_ID(sym, sec)
+
+#define BTF_ID_SUB(sub, prefix, name) \
+ __BTF_ID_SUB(__ID(__BTF_ID__##prefix##__##name##__), __BTF_IDS_SUBSEC(sub))
+
+#define __BTF_ID_LIST_SUB(name, scope) \
+ __BTF_ID_LIST(name, scope, __BTF_IDS_SUBSEC(name))
+
+#define __BTF_SET_SUB(name, scope) \
+asm( \
+".pushsection " __BTF_IDS_SUBSEC(name) ",\"a\"; \n" \
+"." #scope " __BTF_ID__setsc__" #name "; \n" \
+"__BTF_ID__setsc__" #name ":; \n" \
+".zero 4 \n" \
+".popsection; \n");
+
+#define BTF_SET_SUB(name) \
+extern struct btf_id_set name; \
+__BTF_ID_LIST_SUB(name, local) \
+__BTF_SET_SUB(name, local)
+
+#include <linux/args.h> /* CONCATENATE, COUNT_ARGS */
+
+/* bpf_verif_kfunc_<sub> (e.g. rbtree_add → bpf_verif_kfunc_rbtree_add) */
+#define __BPF_VERIF_KFUNC_SUB(sub) bpf_verif_kfunc_##sub
+
+/* Cascade: emit first subsection, recurse on the rest (same kfunc @name). Up to 6 subs. */
+#define __BPF_VERIF_KFUNC_DEF_1(name, s1) \
+ BTF_ID_SUB(__BPF_VERIF_KFUNC_SUB(s1), func, name)
+
+#define __BPF_VERIF_KFUNC_DEF_2(name, s1, s2) \
+ BTF_ID_SUB(__BPF_VERIF_KFUNC_SUB(s1), func, name) \
+ __BPF_VERIF_KFUNC_DEF_1(name, s2)
+
+#define __BPF_VERIF_KFUNC_DEF_3(name, s1, s2, s3) \
+ BTF_ID_SUB(__BPF_VERIF_KFUNC_SUB(s1), func, name) \
+ __BPF_VERIF_KFUNC_DEF_2(name, s2, s3)
+
+#define __BPF_VERIF_KFUNC_DEF_4(name, s1, s2, s3, s4) \
+ BTF_ID_SUB(__BPF_VERIF_KFUNC_SUB(s1), func, name) \
+ __BPF_VERIF_KFUNC_DEF_3(name, s2, s3, s4)
+
+#define __BPF_VERIF_KFUNC_DEF_5(name, s1, s2, s3, s4, s5) \
+ BTF_ID_SUB(__BPF_VERIF_KFUNC_SUB(s1), func, name) \
+ __BPF_VERIF_KFUNC_DEF_4(name, s2, s3, s4, s5)
+
+#define __BPF_VERIF_KFUNC_DEF_6(name, s1, s2, s3, s4, s5, s6) \
+ BTF_ID_SUB(__BPF_VERIF_KFUNC_SUB(s1), func, name) \
+ __BPF_VERIF_KFUNC_DEF_5(name, s2, s3, s4, s5, s6)
+
+/* First arg: kfunc symbol; rest: subsection suffix tokens matching bpf_verif_kfunc_<s>. */
+#define BPF_VERIF_KFUNC_DEF(name, ...) \
+ CONCATENATE(__BPF_VERIF_KFUNC_DEF_, COUNT_ARGS(__VA_ARGS__))(name, __VA_ARGS__)
+
#else
#define BTF_ID_LIST(name) static u32 __maybe_unused name[5];
@@ -166,6 +228,9 @@ extern struct btf_id_set name;
#define BTF_SET_START(name) static struct btf_id_set __maybe_unused name = { 0 };
#define BTF_SET_START_GLOBAL(name) static struct btf_id_set __maybe_unused name = { 0 };
#define BTF_SET_END(name)
+#define BTF_SET_SUB(name) static struct btf_id_set __maybe_unused name = { 0 };
+#define BTF_ID_SUB(sub, prefix, name)
+#define BPF_VERIF_KFUNC_DEF(name, ...)
#endif /* CONFIG_DEBUG_INFO_BTF */
--
2.43.0
next prev parent reply other threads:[~2026-04-03 17:09 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-03 17:08 [PATCH bpf-next 0/3] bpf: Refactor how the verifier matches kfunc checks Chengkaitao
2026-04-03 17:08 ` [PATCH bpf-next 1/3] bpf: Teach resolve_btfids about the setsc type Chengkaitao
2026-04-03 17:08 ` Chengkaitao [this message]
2026-04-03 17:08 ` [PATCH bpf-next 3/3] bpf: classify rbtree kfuncs with BPF_VERIF_KFUNC_DEF sets Chengkaitao
2026-04-10 2:22 ` [PATCH bpf-next 0/3] bpf: Refactor how the verifier matches kfunc checks Chengkaitao
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260403170900.58659-3-pilgrimtao@gmail.com \
--to=pilgrimtao@gmail.com \
--cc=andrii@kernel.org \
--cc=arnd@arndb.de \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=chengkaitao@kylinos.cn \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=ihor.solodrai@linux.dev \
--cc=john.fastabend@gmail.com \
--cc=jolsa@kernel.org \
--cc=linux-arch@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=martin.lau@linux.dev \
--cc=memxor@gmail.com \
--cc=pengdonglin@xiaomi.com \
--cc=song@kernel.org \
--cc=yonghong.song@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox