[PATCH v2] tracing: Make per-template BTF id lists file-local

Mykyta Yatsenko <[email protected]>
Newsgroups org.kernel.vger.bpf,org.kernel.vger.linux-next,org.kernel.vger.linux-trace-kernel
Message-ID <[email protected]>
From: Mykyta Yatsenko <[email protected]>

DECLARE_EVENT_CLASS emitted __bpf_trace_btf_ids_<call> through
BTF_ID_LIST_GLOBAL, i.e. a global symbol named after the event class.
The class name is not unique across the kernel, so the symbol
multiply-defines whenever two translation units instantiate the same
class.

Switch to the file-local BTF_ID_LIST: the list is reached
only through the event_class_<call>.btf_ids pointer, initialised in the
same unit, so tracefs readers never reference the symbol by name and
resolve_btfids still fills the now-local .BTF_ids entries.

The handcrafted syscall classes are the one cross-unit consumer: give
them their own local BTF_ID_LIST rather than importing the generated
sys_{enter,exit} lists.

Fixes: eadc0725ab8d3 ("tracing: Expose tracepoint BTF ids via tracefs")
Reported-by: Mark Brown <[email protected]>
Closes: https://lore.kernel.org/all/[email protected]/
Signed-off-by: Mykyta Yatsenko <[email protected]>
---
Changes in v2:
- Emit the per-class BTF id list only under CONFIG_DEBUG_INFO_BTF;
  without BTF the ids are unresolved and BTF_ID_LIST falls back to a
  128-entry (512-byte) per-class stub, adding hundreds of KB of BSS
  across the ~1000 event classes (reported in review of v1).
- Link to v1: https://patch.msgid.link/[email protected]
---
Changes in v2:
- Emit the per-class BTF id list only under CONFIG_DEBUG_INFO_BTF;
without BTF the ids are unresolved and BTF_ID_LIST falls back to a
128-entry stub.
- Remove verbose comments (Andrii)
- Link to v1: https://patch.msgid.link/[email protected]
---
 include/trace/trace_events.h  |  7 +++----
 kernel/trace/trace_syscalls.c | 27 ++++++++++++++-------------
 2 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/include/trace/trace_events.h b/include/trace/trace_events.h
index 09ad57ac4b73..93011f800d0f 100644
--- a/include/trace/trace_events.h
+++ b/include/trace/trace_events.h
@@ -398,7 +398,7 @@ static inline notrace int trace_event_get_offsets_##call(		\
 #define _TRACE_PERF_INIT(call)
 #endif /* CONFIG_PERF_EVENTS */
 
-#ifdef CONFIG_BPF_EVENTS
+#if defined(CONFIG_BPF_EVENTS) && defined(CONFIG_DEBUG_INFO_BTF)
 /*
  * Per-template BTF id list, populated at link time by resolve_btfids:
  *   [0] FUNC   __bpf_trace_<call>     (the BPF dispatcher)
@@ -406,8 +406,7 @@ static inline notrace int trace_event_get_offsets_##call(		\
  * Exposed via the events/<sys>/<name>/btf_ids tracefs file.
  */
 #define _TRACE_BTF_IDS_DECLARE(call)					\
-	extern u32 __bpf_trace_btf_ids_##call[];			\
-	BTF_ID_LIST_GLOBAL(__bpf_trace_btf_ids_##call, 2)		\
+	BTF_ID_LIST(__bpf_trace_btf_ids_##call)				\
 	BTF_ID(func,   __bpf_trace_##call)				\
 	BTF_ID(struct, trace_event_raw_##call)
 
@@ -417,7 +416,7 @@ static inline notrace int trace_event_get_offsets_##call(		\
 #else
 #define _TRACE_BTF_IDS_DECLARE(call)
 #define _TRACE_BTF_IDS_INIT(call)
-#endif /* CONFIG_BPF_EVENTS */
+#endif /* CONFIG_BPF_EVENTS && CONFIG_DEBUG_INFO_BTF */
 
 #include "stages/stage6_event_callback.h"
 
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
index 48ef1a93e576..e35744049e3f 100644
--- a/kernel/trace/trace_syscalls.c
+++ b/kernel/trace/trace_syscalls.c
@@ -9,6 +9,7 @@
 #include <linux/ftrace.h>
 #include <linux/perf_event.h>
 #include <linux/xarray.h>
+#include <linux/btf_ids.h>
 #include <asm/syscall.h>
 
 #include "trace_output.h"
@@ -1303,15 +1304,15 @@ struct trace_event_functions exit_syscall_print_funcs = {
 	.trace		= print_syscall_exit,
 };
 
-#ifdef CONFIG_BPF_EVENTS
-/*
- * BTF id lists generated by DECLARE_EVENT_CLASS for the sys_enter and
- * sys_exit tracepoints. The auto-generated event_class_sys_{enter,exit}
- * is unused (per-syscall events share the handcrafted classes below),
- * but the id lists themselves are global and reusable.
- */
-extern u32 __bpf_trace_btf_ids_sys_enter[];
-extern u32 __bpf_trace_btf_ids_sys_exit[];
+#if defined(CONFIG_BPF_EVENTS) && defined(CONFIG_DEBUG_INFO_BTF)
+/* BTF id lists for the shared sys_enter/sys_exit dispatcher tracepoints. */
+BTF_ID_LIST(syscall_enter_btf_ids)
+BTF_ID(func,   __bpf_trace_sys_enter)
+BTF_ID(struct, trace_event_raw_sys_enter)
+
+BTF_ID_LIST(syscall_exit_btf_ids)
+BTF_ID(func,   __bpf_trace_sys_exit)
+BTF_ID(struct, trace_event_raw_sys_exit)
 #endif
 
 struct trace_event_class __refdata event_class_syscall_enter = {
@@ -1320,8 +1321,8 @@ struct trace_event_class __refdata event_class_syscall_enter = {
 	.fields_array	= syscall_enter_fields_array,
 	.get_fields	= syscall_get_enter_fields,
 	.raw_init	= init_syscall_trace,
-#ifdef CONFIG_BPF_EVENTS
-	.btf_ids	= __bpf_trace_btf_ids_sys_enter,
+#if defined(CONFIG_BPF_EVENTS) && defined(CONFIG_DEBUG_INFO_BTF)
+	.btf_ids	= syscall_enter_btf_ids,
 #endif
 };
 
@@ -1335,8 +1336,8 @@ struct trace_event_class __refdata event_class_syscall_exit = {
 	},
 	.fields		= LIST_HEAD_INIT(event_class_syscall_exit.fields),
 	.raw_init	= init_syscall_trace,
-#ifdef CONFIG_BPF_EVENTS
-	.btf_ids	= __bpf_trace_btf_ids_sys_exit,
+#if defined(CONFIG_BPF_EVENTS) && defined(CONFIG_DEBUG_INFO_BTF)
+	.btf_ids	= syscall_exit_btf_ids,
 #endif
 };
 

---
base-commit: eadc0725ab8d38c05148fce49f8d5c6a0e01f062
change-id: 20260730-b4-fix_btf_tracefs-fdafda5fdb5b

Best regards,
--  
Mykyta Yatsenko <[email protected]>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.