[PATCH v2] tracing: Make per-template BTF id lists file-local
Mykyta Yatsenko <[email protected]> Thu, 30 Jul 2026 17:17:39 -0700
| Newsgroups | org.kernel.vger.linux-next,org.kernel.vger.bpf,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]>