[PATCH bpf-next 2/3] bpf: Introduce BTF_SET/ID_SUB and BPF_VERIF_KFUNC_DEF

Chengkaitao posted 3 patches 3 days, 19 hours ago
[PATCH bpf-next 2/3] bpf: Introduce BTF_SET/ID_SUB and BPF_VERIF_KFUNC_DEF
Posted by Chengkaitao 3 days, 19 hours ago
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