On 7/31/26 12:55 AM, Andrii Nakryiko wrote:
> On Thu, Jul 30, 2026 at 5:52 AM Mykyta Yatsenko
> <[email protected]> wrote:
>>
>> 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, which are now file-local.
>>
>> 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]>
>> ---
>>  include/trace/trace_events.h  |  6 ++++--
>>  kernel/trace/trace_syscalls.c | 22 ++++++++++++++--------
>>  2 files changed, 18 insertions(+), 10 deletions(-)
>>
>> diff --git a/include/trace/trace_events.h b/include/trace/trace_events.h
>> index 09ad57ac4b73..45ffbe04b580 100644
>> --- a/include/trace/trace_events.h
>> +++ b/include/trace/trace_events.h
>> @@ -404,10 +404,12 @@ static inline notrace int 
>> trace_event_get_offsets_##call(         \
>>   *   [0] FUNC   __bpf_trace_<call>     (the BPF dispatcher)
>>   *   [1] STRUCT trace_event_raw_<call> (the ring-buffer record)
>>   * Exposed via the events/<sys>/<name>/btf_ids tracefs file.
>> + *
>> + * File-local: the class name is not unique, so a global symbol would
>> + * clash across translation units.
> 
> drop this comment? not super useful and file-local is default behavior
> for BTF_ID_LIST anyways
> 
>>   */
>>  #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)
>>
> 
> This should go into Steven's tree, not bpf-next, right?

yes, thanks for the review!
> 
>> diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
>> index 48ef1a93e576..9b5931f2f280 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"
>> @@ -1305,13 +1306,18 @@ struct trace_event_functions 
>> exit_syscall_print_funcs = {
>>
>>  #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.
>> + * BTF id lists for the shared sys_enter/sys_exit dispatcher tracepoints,
>> + * resolved by resolve_btfids. Defined locally rather than importing the
>> + * DECLARE_EVENT_CLASS-generated lists, which are now file-local to the
>> + * translation unit that instantiates the tracepoint.
> 
> drop "resolved by resolve_btfids", and drop the part about defined
> locally because file-local, too much Claude style
> 
>>   */
>> -extern u32 __bpf_trace_btf_ids_sys_enter[];
>> -extern u32 __bpf_trace_btf_ids_sys_exit[];
>> +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 = {
>> @@ -1321,7 +1327,7 @@ struct trace_event_class __refdata 
>> event_class_syscall_enter = {
>>         .get_fields     = syscall_get_enter_fields,
>>         .raw_init       = init_syscall_trace,
>>  #ifdef CONFIG_BPF_EVENTS
>> -       .btf_ids        = __bpf_trace_btf_ids_sys_enter,
>> +       .btf_ids        = syscall_enter_btf_ids,
>>  #endif
>>  };
>>
>> @@ -1336,7 +1342,7 @@ 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,
>> +       .btf_ids        = syscall_exit_btf_ids,
>>  #endif
>>  };
>>
>>
>> ---
>> base-commit: eadc0725ab8d38c05148fce49f8d5c6a0e01f062
>> change-id: 20260730-b4-fix_btf_tracefs-fdafda5fdb5b
>>
>> Best regards,
>> --
>> Mykyta Yatsenko <[email protected]>
>>


Reply via email to