tracepoints: Add warnings for unused tracepoints and trace events
Subsystems (4)
v9 cover tracepoints: Add warnings for unused tracepoints and trace events
Every trace event can take up to 5K of memory in text and metadata regardless if they are used or not. Trace events should not be created if they are not used. Currently there's several events in the kernel that are defined but unused, either because their callers were removed without removing the trace event with it, or a config hides the trace event caller but not the trace event itself. And in some cases, trace events were simply added but were never called for whatever reason. The number of unused trace events continues to grow.
This patch series aims to fix this.
The first patch moves the elf parsing out of sorttable.c so that it can be used by other tooling.
The second patch creates a new program to run during build called tracepoint-update (note this may be extended to do other tracepoint modifications in the future). It also creates a new section called __tracepoint_check, where all callers of a tracepoint creates a variable that is placed in this section with the name of the tracepoint they use. The scripts/tracepoint-update.c is used to find tracepoints that are defined but not used which would mean they would not be in the __tracepoint_check section. It sorts the names from that section, and then reads the __tracepoint_strings section that has all compiled in tracepoint names. It makes sure that every tracepoint is found in the check section and if not, it prints a warning message about it. This lists the missing tracepoints at build time.
The third patch adds EXPORT_TRACEPOINT() to the __tracepoint_check section as well. There was several locations that adds tracepoints in the kernel proper that are only used in modules. It was getting quite complex trying to move things around that I just decided to make any tracepoint in a EXPORT_TRACEPOINT "used". I'm using the analogy of static and global functions. An unused static function gets a warning but an unused global one does not.
The last patch triggers warnings when a module defines a tracepoint but does not use it.
Instead of hiding this behind a config option, where allmodconfig can cause the warnings to trigger, and we don't want current warnings to suddenly appear. Have the warnings trigger by a new make command line:
make UT=1
This will enable the unused tracepoints warnings. Now this should not be an issue to upstream before all warnings are removed. When all current warnings are removed, we can then make this the default option where it will always cause the build to warn if there's a unused tracepoint defined.
Changes since v8: https://lore.kernel.org/linux-trace-kernel/[email protected]/
- Instead of hiding the unused tracepoint warnings behind a config option, which means allmodconfig will trigger it, make it a make command line option. Now to enable the warnings, on must run
make UT=1
- Trigger warnings for modules as well as built in unused tracepoints.
Steven Rostedt (4):
sorttable: Move ELF parsing into scripts/elf-parse.[ch]
tracing: Add a tracepoint verification check at build time
tracepoint: Do not warn for unused event that is exported
tracing: Add warnings for unused tracepoints for modules
----
Makefile | 15 ++ include/asm-generic/vmlinux.lds.h | 1 + include/linux/tracepoint.h | 13 ++ scripts/Makefile | 6 + scripts/Makefile.modfinal | 7 + scripts/elf-parse.c | 198 ++++++++++++++++ scripts/elf-parse.h | 305 ++++++++++++++++++++++++ scripts/link-vmlinux.sh | 7 + scripts/sorttable.c | 477 +++----------------------------------- scripts/tracepoint-update.c | 239 +++++++++++++++++++ 10 files changed, 825 insertions(+), 443 deletions(-) create mode 100644 scripts/elf-parse.c create mode 100644 scripts/elf-parse.h create mode 100644 scripts/tracepoint-update.c
PATCH v9 1/4 sorttable: Move ELF parsing into scripts/elf-parse.[ch]
From: Steven Rostedt <[email protected]>
In order to share the elf parsing that is in sorttable.c so that other programs could use the same code, move it into elf-parse.c and elf-parse.h.
--- scripts/Makefile | 3 + scripts/elf-parse.c | 198 ++++++++++++++++++ scripts/elf-parse.h | 305 ++++++++++++++++++++++++++++ scripts/sorttable.c | 477 ++++---------------------------------------- 4 files changed, 540 insertions(+), 443 deletions(-) create mode 100644 scripts/elf-parse.c create mode 100644 scripts/elf-parse.h
scripts/Makefile +3 -0
@@ -12,6 +12,8 @@ hostprogs-always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert hostprogs-always-$(CONFIG_RUST_KERNEL_DOCTESTS) += rustdoc_test_builder hostprogs-always-$(CONFIG_RUST_KERNEL_DOCTESTS) += rustdoc_test_gen +sorttable-objs := sorttable.o elf-parse.o + ifneq ($(or $(CONFIG_X86_64),$(CONFIG_X86_32)),) always-$(CONFIG_RUST) += target.json filechk_rust_target = $< < include/config/auto.conf
@@ -25,6 +27,7 @@ generate_rust_target-rust := y rustdoc_test_builder-rust := y rustdoc_test_gen-rust := y +HOSTCFLAGS_elf-parse.o = -I$(srctree)/tools/include HOSTCFLAGS_sorttable.o = -I$(srctree)/tools/include HOSTLDLIBS_sorttable = -lpthread HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include
scripts/elf-parse.c new file +198 -0
198 lines not on this page · raw message
scripts/elf-parse.h new file +305 -0
305 lines not on this page · raw message
scripts/sorttable.c +34 -443
622 lines not on this page · raw message
Signature · 1 line
2.51.0
PATCH v9 2/4 tracing: Add a tracepoint verification check at build time
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
If a tracepoint is defined via DECLARE_TRACE() or TRACE_EVENT() but never called (via the trace_<tracepoint>() function), its metadata is still around in memory and not discarded.
When created via TRACE_EVENT() the situation is worse because the TRACE_EVENT() creates metadata that can be around 5k per trace event. Having unused trace events causes several thousand of wasted bytes.
Add a verifier that injects a string of the name of the tracepoint it calls that is added to the discarded section "__tracepoint_check". For every builtin tracepoint, its name (which is saved in the in-memory section "__tracepoint_strings") will have its name also in the "__tracepoint_check" section if it is used.
Add a new program that is run on build called tracepoint-update. This is executed on the vmlinux.o before the __tracepoint_check section is discarded (the section is discarded before vmlinux is created). This program will create an array of each string in the __tracepoint_check section and then sort it. Then it will walk the strings in the __tracepoint_strings section and do a binary search to check if its name is in the __tracepoint_check section. If it is not, then it is unused and a warning is printed.
Note, this currently only handles tracepoints that are builtin and not in modules.
Enabling this currently with a given config produces:
warning: tracepoint 'sched_move_numa' is unused.
warning: tracepoint 'sched_stick_numa' is unused.
warning: tracepoint 'sched_swap_numa' is unused.
warning: tracepoint 'pelt_hw_tp' is unused.
warning: tracepoint 'pelt_irq_tp' is unused.
warning: tracepoint 'rcu_preempt_task' is unused.
warning: tracepoint 'rcu_unlock_preempted_task' is unused.
warning: tracepoint 'xdp_bulk_tx' is unused.
warning: tracepoint 'xdp_redirect_map' is unused.
warning: tracepoint 'xdp_redirect_map_err' is unused.
warning: tracepoint 'vma_mas_szero' is unused.
warning: tracepoint 'vma_store' is unused.
warning: tracepoint 'hugepage_set_pmd' is unused.
warning: tracepoint 'hugepage_set_pud' is unused.
warning: tracepoint 'hugepage_update_pmd' is unused.
warning: tracepoint 'hugepage_update_pud' is unused.
warning: tracepoint 'block_rq_remap' is unused.
warning: tracepoint 'xhci_dbc_handle_event' is unused.
warning: tracepoint 'xhci_dbc_handle_transfer' is unused.
warning: tracepoint 'xhci_dbc_gadget_ep_queue' is unused.
warning: tracepoint 'xhci_dbc_alloc_request' is unused.
warning: tracepoint 'xhci_dbc_free_request' is unused.
warning: tracepoint 'xhci_dbc_queue_request' is unused.
warning: tracepoint 'xhci_dbc_giveback_request' is unused.
warning: tracepoint 'tcp_ao_wrong_maclen' is unused.
warning: tracepoint 'tcp_ao_mismatch' is unused.
warning: tracepoint 'tcp_ao_key_not_found' is unused.
warning: tracepoint 'tcp_ao_rnext_request' is unused.
warning: tracepoint 'tcp_ao_synack_no_key' is unused.
warning: tracepoint 'tcp_ao_snd_sne_update' is unused.
warning: tracepoint 'tcp_ao_rcv_sne_update' is unused.
Some of the above is totally unused but others are not used due to their "trace_" functions being inside configs, in which case, the defined tracepoints should also be inside those same configs. Others are architecture specific but defined in generic code, where they should either be moved to the architecture or be surrounded by #ifdef for the architectures they are for.
This tool could be updated to process modules in the future.
I'd like to thank Mathieu Desnoyers for suggesting using strings instead of pointers, as using pointers in vmlinux.o required handling relocations and it required implementing almost a full feature linker to do so.
To enable this check, run the build with: make UT=1
---
Changes since v8: https://lore.kernel.org/[email protected]
- Instead of using a config option to enable this, enable it via: make UT=1 This will allow it to go into linux-next without triggering all the current warnings but also allow people to find and fix current unused tracepoints.
Makefile | 15 ++ include/asm-generic/vmlinux.lds.h | 1 + include/linux/tracepoint.h | 11 ++ scripts/Makefile | 3 + scripts/link-vmlinux.sh | 7 + scripts/tracepoint-update.c | 232 ++++++++++++++++++++++++++++++ 6 files changed, 269 insertions(+) create mode 100644 scripts/tracepoint-update.c
Makefile +15 -0
@@ -157,6 +157,20 @@ endif export KBUILD_EXTRA_WARN +# To check for unused tracepoints (tracepoints that are defined but never +# called), run with: +# +# make UT=1 +# +# Each unused tracepoints can take up to 5KB of memory in the running kernel. +# It is best to remove any that are not used. + +ifeq ("$(origin UT)", "command line") + WARN_ON_UNUSED_TRACEPOINTS := $(UT) +endif + +export WARN_ON_UNUSED_TRACEPOINTS + # Kbuild will save output files in the current working directory. # This does not need to match to the root of the kernel source tree. #
@@ -1772,6 +1786,7 @@ help: @echo ' c: extra checks in the configuration stage (Kconfig)' @echo ' e: warnings are being treated as errors' @echo ' Multiple levels can be combined with W=12 or W=123' + @echo ' make UT=1 [targets] Warn if a tracepoint is defined but not used. @$(if $(dtstree), \ echo ' make CHECK_DTBS=1 [targets] Check all generated dtb files against schema'; \ echo ' This can be applied both to "dtbs" and to individual "foo.dtb" targets' ; \
include/asm-generic/vmlinux.lds.h +1 -0
@@ -1048,6 +1048,7 @@ defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG) *(.no_trim_symbol) \ /* ld.bfd warns about .gnu.version* even when not emitted */ \ *(.gnu.version*) \ + *(__tracepoint_check)#define DISCARDS \ /DISCARD/ : { \
include/linux/tracepoint.h +11 -0
@@ -221,6 +221,15 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) __do_trace_##name(args); \ } +/* +* When a tracepoint is used, it's name is added to the __tracepoint_check +* section. This section is only used at build time to make sure all +* defined tracepoints are used. It is discarded after the build. +*/ +# define TRACEPOINT_CHECK (name) \ + static const char __used __section("__tracepoint_check") __trace_check[] = \ + #name; +/* * Make sure the alignment of the structure in the __tracepoints section will * not add unwanted padding between the beginning of the section and the
@@ -270,6 +279,7 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) __DECLARE_TRACE_COMMON(name, PARAMS(proto), PARAMS(args), PARAMS(data_proto)) \ static inline void __do_trace_##name(proto) \ { \ +TRACEPOINT_CHECK (name) \ if (cond) { \guard (preempt_notrace)(); \__DO_TRACE_CALL (name,TP_ARGS (args)); \
@@ -289,6 +299,7 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) __DECLARE_TRACE_COMMON(name, PARAMS(proto), PARAMS(args), PARAMS(data_proto)) \ static inline void __do_trace_##name(proto) \ { \ +TRACEPOINT_CHECK (name) \guard (rcu_tasks_trace )(); \__DO_TRACE_CALL (name,TP_ARGS (args)); \ } \
scripts/Makefile +3 -0
@@ -11,8 +11,10 @@ hostprogs-always-$(CONFIG_MODULE_SIG_FORMAT) += sign-file hostprogs-always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE) += insert-sys-cert hostprogs-always-$(CONFIG_RUST_KERNEL_DOCTESTS) += rustdoc_test_builder hostprogs-always-$(CONFIG_RUST_KERNEL_DOCTESTS) += rustdoc_test_gen +hostprogs-always-$(CONFIG_TRACEPOINTS) += tracepoint-update sorttable-objs := sorttable.o elf-parse.o +tracepoint-update-objs := tracepoint-update.o elf-parse.o ifneq ($(or $(CONFIG_X86_64),$(CONFIG_X86_32)),) always-$(CONFIG_RUST) += target.json
@@ -27,6 +29,7 @@ generate_rust_target-rust := y rustdoc_test_builder-rust := y rustdoc_test_gen-rust := y +HOSTCFLAGS_tracepoint-update.o = -I$(srctree)/tools/include HOSTCFLAGS_elf-parse.o = -I$(srctree)/tools/include HOSTCFLAGS_sorttable.o = -I$(srctree)/tools/include HOSTLDLIBS_sorttable = -lpthread
scripts/link-vmlinux.sh +7 -0
@@ -208,6 +208,13 @@ kallsymso= strip_debug= generate_map= +# Use "make UT=1" to trigger warnings on unused tracepoints +case "${WARN_ON_UNUSED_TRACEPOINTS}" in +*1*) + ${objtree}/scripts/tracepoint-update vmlinux.o + ;; +esac + if is_enabled CONFIG_KALLSYMS; then true > .tmp_vmlinux0.syms kallsyms .tmp_vmlinux0.syms .tmp_vmlinux0.kallsyms
scripts/tracepoint-update.c new file +232 -0
232 lines not on this page · raw message
Signature · 1 line
2.51.0
PATCH v9 3/4 tracepoint: Do not warn for unused event that is exported
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
There are a few generic events that may only be used by modules. They are defined and then set with EXPORT_TRACEPOINT*(). Mark events that are exported as being used, even though they still waste memory in the kernel proper.
--- include/linux/tracepoint.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
include/linux/tracepoint.h +4 -2
@@ -227,8 +227,8 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)* defined tracepoints are used. It is discarded after the build. */ # define TRACEPOINT_CHECK (name) \ - static const char __used __section("__tracepoint_check") __trace_check[] = \ - #name; + static const char __used __section("__tracepoint_check") \ + __trace_check_##name[] = #name;/* * Make sure the alignment of the structure in the __tracepoints section will
@@ -382,10 +382,12 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)__DEFINE_TRACE_EXT (_name,NULL ,PARAMS (_proto),PARAMS (_args));#define EXPORT_TRACEPOINT_SYMBOL_GPL (name) \ + TRACEPOINT_CHECK(name) \ EXPORT_SYMBOL_GPL(__tracepoint_##name); \ EXPORT_SYMBOL_GPL(__traceiter_##name); \ EXPORT_STATIC_CALL_GPL(tp_func_##name)#define EXPORT_TRACEPOINT_SYMBOL (name) \ + TRACEPOINT_CHECK(name) \ EXPORT_SYMBOL(__tracepoint_##name); \ EXPORT_SYMBOL(__traceiter_##name); \ EXPORT_STATIC_CALL(tp_func_##name)
Signature · 1 line
2.51.0
PATCH v9 4/4 tracing: Add warnings for unused tracepoints for modules
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
If a modules has TRACE_EVENT() but does not use it, add a warning about it at build time.
Currently, the build must be made by adding "UT=1" to the make command line in order for this to trigger.
--- scripts/Makefile.modfinal | 7 +++++++ scripts/tracepoint-update.c | 7 +++++++ 2 files changed, 14 insertions(+)
scripts/Makefile.modfinal +7 -0
@@ -28,6 +28,12 @@ ccflags-remove-y := $(CC_FLAGS_CFI) .module-common.o: $(srctree)/scripts/module-common.c FORCE $(call if_changed_rule,cc_o_c) +ifneq ($(WARN_ON_UNUSED_TRACEPOINTS),"") +cmd_check_tracepoint = ${objtree}/scripts/tracepoint-update $<; +else +cmd_check_tracepoint = +endif + quiet_cmd_ld_ko_o = LD [M] $@ cmd_ld_ko_o = \ $(LD) -r $(KBUILD_LDFLAGS) \
@@ -57,6 +63,7 @@ if_changed_except = $(if $(call newer_prereqs_except,$(2))$(cmd-check), \ ifdef CONFIG_DEBUG_INFO_BTF_MODULES +$(if $(newer-prereqs),$(call cmd,btf_ko)) endif + +$(call cmd,check_tracepoint) targets += $(modules:%.o=%.ko) $(modules:%.o=%.mod.o) .module-common.o
scripts/tracepoint-update.c +7 -0
@@ -188,6 +188,13 @@ static int process_tracepoints(void *addr, char const *const fname) } } +/* +* Modules may not have either section. But if it has one section, +* it should have both of them. +*/ +if (!check_data_sec && !tracepoint_data_sec) +return 0 ; +if (!check_data_sec) {fprintf (stderr,"no __tracepoint_check in file: %s\n" , fname);return -1 ;
Signature · 1 line
2.51.0
Nathan Chancellor
maintainerRe: [PATCH v9 2/4] tracing: Add a tracepoint verification check at build time
In reply to Steven RostedtHi Steve,
The kbuild portions of this seem fine, as they mirror existing patterns.
include/asm-generic/vmlinux.lds.h defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG) · line 1051
Quoted 9 lines · Steven Rostedt
include/asm-generic/vmlinux.lds.h +1
-0@@ -1048,6 +1048,7 @@ defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG) *(.no_trim_symbol) \/* ld.bfd warns about .gnu.version* even when not emitted */ \ *(.gnu.version*) \ + *(__tracepoint_check)
Please add a trailing slash like the other lines so that one does not need to be added when someone else needs to grow this macro (also helps with 'git blame').
Cheers,
Nathan
Steven Rostedt
maintainerRe: [PATCH v9 2/4] tracing: Add a tracepoint verification check at build time
Quoted 5 lines · On Wed, 15 Oct 2025 16:12:19 -0700 Nathan Chancellor <[email protected]> wrote:
Hi Steve,
The kbuild portions of this seem fine, as they mirror existing patterns.
On Wed, Oct 15, 2025 at 04:38:44PM -0400, Steven Rostedt wrote:
Quoted 13 lines
include/asm-generic/vmlinux.lds.h defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG) · line 1051
Quoted 9 lines
include/asm-generic/vmlinux.lds.h +1
-0@@ -1048,6 +1048,7 @@ defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELLER_CLANG) *(.no_trim_symbol) \/* ld.bfd warns about .gnu.version* even when not emitted */ \ *(.gnu.version*) \ + *(__tracepoint_check)Please add a trailing slash like the other lines so that one does not need to be added when someone else needs to grow this macro (also helps with 'git blame').
Sure thing! Thanks for looking at these patches!
-- Steve
Nathan Chancellor
maintainerRe: [PATCH v9 4/4] tracing: Add warnings for unused tracepoints for modules
In reply to Steven RostedtHi Steve,
scripts/Makefile.modfinal ccflags-remove-y := $(CC_FLAGS_CFI) · line 31
Quoted 9 lines · Steven Rostedt
scripts/Makefile.modfinal +1
-0@@ -28,6 +28,12 @@ ccflags-remove-y := $(CC_FLAGS_CFI) .module-common.o: $(srctree)/scripts/module-common.c FORCE $(call if_changed_rule,cc_o_c) +ifneq ($(WARN_ON_UNUSED_TRACEPOINTS),"")
Drop the "", nowhere else in Kbuild appears to do this.
scripts/Makefile.modfinal ccflags-remove-y := $(CC_FLAGS_CFI) · line 32
Quoted 1 line
scripts/Makefile.modfinal +1
-0+cmd_check_tracepoint = ${objtree}/scripts/tracepoint-update $<;
Please use $(objtree) to be consistent with the rest of Kbuild.
Quoted 20 lines
scripts/Makefile.modfinal +5
-0+else +cmd_check_tracepoint = +endif + quiet_cmd_ld_ko_o = LD [M] $@ cmd_ld_ko_o = \ $(LD) -r $(KBUILD_LDFLAGS) \@@ -57,6 +63,7 @@ if_changed_except = $(if $(call newer_prereqs_except,$(2))$(cmd-check), \ ifdef CONFIG_DEBUG_INFO_BTF_MODULES +$(if $(newer-prereqs),$(call cmd,btf_ko)) endif + +$(call cmd,check_tracepoint) targets += $(modules:%.o=%.ko) $(modules:%.o=%.mod.o) .module-common.oscripts/tracepoint-update.c +0
-0
scripts/tracepoint-update.c static int process_tracepoints(void *addr, char const *const fname) · line 197
Quoted 10 lines
scripts/tracepoint-update.c +7
-0@@ -188,6 +188,13 @@ static int process_tracepoints(void *addr, char const *const fname) } } +/* +* Modules may not have either section. But if it has one section, +* it should have both of them. +*/ +if (!check_data_sec && !tracepoint_data_sec) +return 0 ; +
This feels like it could be its own patch but I guess it does not make much sense without enablement. It might be worth calling this out a bit more in the commit message.
Quoted 7 lines
scripts/tracepoint-update.c +0
-0if (!check_data_sec) {fprintf (stderr,"no __tracepoint_check in file: %s\n" , fname);return -1 ;Signature · 1 line
2.51.0
kernel test robot
build botRe: [PATCH v9 4/4] tracing: Add warnings for unused tracepoints for modules
In reply to Steven Rostedtkernel test robot noticed the following build errors:
Hi Steven,
kernel test robot noticed the following build errors:
[auto build test ERROR on akpm-mm/mm-everything]
[also build test ERROR on linus/master v6.18-rc1 next-20251015] [cannot apply to trace/for-next arnd-asm-generic/master]
[If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Steven-Rostedt/sorttable-Move-ELF-parsing-into-scripts-elf-parse-ch/20251016-044008 base: https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything patch link: https://lore.kernel.org/r/20251015203924.731213165%40kernel.org patch subject: [PATCH v9 4/4] tracing: Add warnings for unused tracepoints for modules config: microblaze-defconfig (https://download.01.org/0day-ci/archive/20251016/[email protected]/config) compiler: microblaze-linux-gcc (GCC) 15.1.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251016/[email protected]/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
All errors (new ones prefixed by >>):
>> /bin/bash: line 1: ./scripts/tracepoint-update: No such file or directory
Signature · 2 lines
0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
Nicolas Schier
maintainerRe: [PATCH v9 2/4] tracing: Add a tracepoint verification check at build time
In reply to Steven RostedtQuoted 109 lines · Steven Rostedt
From: Steven Rostedt <[email protected]>
If a tracepoint is defined via
DECLARE_TRACE()orTRACE_EVENT()but never called (via the trace_<tracepoint>() function), its metadata is still around in memory and not discarded.When created via
TRACE_EVENT()the situation is worse because theTRACE_EVENT()creates metadata that can be around 5k per trace event. Having unused trace events causes several thousand of wasted bytes.Add a verifier that injects a string of the name of the tracepoint it calls that is added to the discarded section "
__tracepoint_check". For every builtin tracepoint, its name (which is saved in the in-memory section "__tracepoint_strings") will have its name also in the "__tracepoint_check" section if it is used.Add a new program that is run on build called tracepoint-update. This is executed on the vmlinux.o before the
__tracepoint_checksection is discarded (the section is discarded before vmlinux is created). This program will create an array of each string in the__tracepoint_checksection and then sort it. Then it will walk the strings in the__tracepoint_stringssection and do a binary search to check if its name is in the__tracepoint_checksection. If it is not, then it is unused and a warning is printed.Note, this currently only handles tracepoints that are builtin and not in modules.
Enabling this currently with a given config produces:
warning: tracepoint '
sched_move_numa' is unused.
warning: tracepoint 'sched_stick_numa' is unused.
warning: tracepoint 'sched_swap_numa' is unused.
warning: tracepoint 'pelt_hw_tp' is unused.
warning: tracepoint 'pelt_irq_tp' is unused.
warning: tracepoint 'rcu_preempt_task' is unused.
warning: tracepoint 'rcu_unlock_preempted_task' is unused.
warning: tracepoint 'xdp_bulk_tx' is unused.
warning: tracepoint 'xdp_redirect_map' is unused.
warning: tracepoint 'xdp_redirect_map_err' is unused.
warning: tracepoint 'vma_mas_szero' is unused.
warning: tracepoint 'vma_store' is unused.
warning: tracepoint 'hugepage_set_pmd' is unused.
warning: tracepoint 'hugepage_set_pud' is unused.
warning: tracepoint 'hugepage_update_pmd' is unused.
warning: tracepoint 'hugepage_update_pud' is unused.
warning: tracepoint 'block_rq_remap' is unused.
warning: tracepoint 'xhci_dbc_handle_event' is unused.
warning: tracepoint 'xhci_dbc_handle_transfer' is unused.
warning: tracepoint 'xhci_dbc_gadget_ep_queue' is unused.
warning: tracepoint 'xhci_dbc_alloc_request' is unused.
warning: tracepoint 'xhci_dbc_free_request' is unused.
warning: tracepoint 'xhci_dbc_queue_request' is unused.
warning: tracepoint 'xhci_dbc_giveback_request' is unused.
warning: tracepoint 'tcp_ao_wrong_maclen' is unused.
warning: tracepoint 'tcp_ao_mismatch' is unused.
warning: tracepoint 'tcp_ao_key_not_found' is unused.
warning: tracepoint 'tcp_ao_rnext_request' is unused.
warning: tracepoint 'tcp_ao_synack_no_key' is unused.
warning: tracepoint 'tcp_ao_snd_sne_update' is unused.
warning: tracepoint 'tcp_ao_rcv_sne_update' is unused.Some of the above is totally unused but others are not used due to their "
trace_" functions being inside configs, in which case, the defined tracepoints should also be inside those same configs. Others are architecture specific but defined in generic code, where they should either be moved to the architecture or be surrounded by #ifdef for the architectures they are for.This tool could be updated to process modules in the future.
I'd like to thank Mathieu Desnoyers for suggesting using strings instead of pointers, as using pointers in vmlinux.o required handling relocations and it required implementing almost a full feature linker to do so.
To enable this check, run the build with: make UT=1
Signed-off-by Steven Rostedt (Google) <[email protected]>---
Changes since v8: https://lore.kernel.org/[email protected]- Instead of using a config option to enable this, enable it via: make UT=1 This will allow it to go into linux-next without triggering all the current warnings but also allow people to find and fix current unused tracepoints.
Makefile | 15 ++ include/asm-generic/vmlinux.lds.h | 1 + include/linux/tracepoint.h | 11 ++ scripts/Makefile | 3 + scripts/link-vmlinux.sh | 7 + scripts/tracepoint-update.c | 232 ++++++++++++++++++++++++++++++ 6 files changed, 269 insertions(+) create mode 100644 scripts/tracepoint-update.cMakefile +3
-0@@ -157,6 +157,20 @@ endif export KBUILD_EXTRA_WARN +# To check for unused tracepoints (tracepoints that are defined but never +# called), run with: +#
Makefile endif · line 172
Quoted 10 lines
Makefile +10
-0+# make UT=1 +# +# Each unused tracepoints can take up to 5KB of memory in the running kernel. +# It is best to remove any that are not used. + +ifeq ("$(origin UT)", "command line") + WARN_ON_UNUSED_TRACEPOINTS := $(UT) +endif + +export WARN_ON_UNUSED_TRACEPOINTS
Is there a special reason why you chose to introduce a new command-line variable instead of extending KBUILD_EXTRA_WARN / W ?
Kind regards,
Nicolas
Nicolas Schier
maintainerRe: [PATCH v9 4/4] tracing: Add warnings for unused tracepoints for modules
In reply to Nathan ChancellorQuoted 15 lines · Nathan Chancellor
Hi Steve,
scripts/Makefile.modfinal ccflags-remove-y := $(CC_FLAGS_CFI) · line 31
Quoted 9 lines · Steven Rostedt
scripts/Makefile.modfinal +1
-0@@ -28,6 +28,12 @@ ccflags-remove-y := $(CC_FLAGS_CFI) .module-common.o: $(srctree)/scripts/module-common.c FORCE $(call if_changed_rule,cc_o_c) +ifneq ($(WARN_ON_UNUSED_TRACEPOINTS),"")Drop the "", nowhere else in
Kbuildappears to do this.
Quoted 7 lines
scripts/Makefile.modfinal ccflags-remove-y := $(CC_FLAGS_CFI) · line 32
Quoted 1 line
scripts/Makefile.modfinal +1
-0+cmd_check_tracepoint = ${objtree}/scripts/tracepoint-update $<;Please use $(objtree) to be consistent with the rest of
Kbuild.scripts/Makefile.modfinal ccflags-remove-y := $(CC_FLAGS_CFI) · line 35
Quoted 3 lines
scripts/Makefile.modfinal +3
-0+else +cmd_check_tracepoint = +endif
The else part is not required, cp. definition of e.g. cmd_checkdoc in scripts/Makefile.build.
Kind regards
Nicolas
Steven Rostedt
maintainerRe: [PATCH v9 2/4] tracing: Add a tracepoint verification check at build time
In reply to Nicolas SchierQuoted 8 lines · On Fri, 17 Oct 2025 22:15:20 +0200 Nicolas Schier <[email protected]> wrote:
Quoted 8 lines
Makefile +8
-0+# To check for unused tracepoints (tracepoints that are defined but never +# called), run with: +# +# make UT=1 +# +# Each unused tracepoints can take up to 5KB of memory in the running kernel. +# It is best to remove any that are not used. +
Quoted 8 lines
Makefile endif · line 172
Quoted 5 lines
Makefile +5
-0+ifeq ("$(origin UT)", "command line") + WARN_ON_UNUSED_TRACEPOINTS := $(UT) +endif + +export WARN_ON_UNUSED_TRACEPOINTSIs there a special reason why you chose to introduce a new command-line variable instead of extending
KBUILD_EXTRA_WARN/ W ?
Honestly, I didn't think about using KBUILD_EXTRA_WARN. I also want this option to go away after we remove the current unused tracepoints so that any new ones will always cause a warning.
The only reason not to make it always warn is because I don't want to add warnings for the existing code. I'm working on having outreachy projects to remove the currently unused tracepoints. Once that is done, then this option is going to go away and the build will always warn on unused tracepoints.
I thought it might be easier to remove it without any issues if it's a new command line that goes away in the future.
Looking at EXTRA_WARN, it appears to be for basic issues with the code and adds new C compiler warning flags. This isn't exactly the same.
If you think it makes sense to extend EXTRA_WARN, I can still go ahead and do that.
-- Steve
Steven Rostedt
maintainerRe: [PATCH v9 4/4] tracing: Add warnings for unused tracepoints for modules
In reply to Nicolas SchierQuoted 18 lines · On Fri, 17 Oct 2025 22:22:32 +0200 Nicolas Schier <[email protected]> wrote:
Quoted 17 lines · Nathan Chancellor
Hi Steve,
scripts/Makefile.modfinal ccflags-remove-y := $(CC_FLAGS_CFI) · line 31
Quoted 9 lines · Steven Rostedt
scripts/Makefile.modfinal +1
-0@@ -28,6 +28,12 @@ ccflags-remove-y := $(CC_FLAGS_CFI) .module-common.o: $(srctree)/scripts/module-common.c FORCE $(call if_changed_rule,cc_o_c) +ifneq ($(WARN_ON_UNUSED_TRACEPOINTS),"")Drop the "", nowhere else in
Kbuildappears to do this.Quoted 1 line
scripts/Makefile.modfinal +1
-0+cmd_check_tracepoint = ${objtree}/scripts/tracepoint-update $<;
Quoted 8 lines
Quoted 5 lines
Please use $(objtree) to be consistent with the rest of
Kbuild.scripts/Makefile.modfinal ccflags-remove-y := $(CC_FLAGS_CFI) · line 35
Quoted 3 lines
scripts/Makefile.modfinal +3
-0+else +cmd_check_tracepoint = +endifThe else part is not required, cp. definition of e.g.
cmd_checkdocinscripts/Makefile.build.
Thanks, will do.
-- Steve
Steven Rostedt
maintainerRe: [PATCH v9 4/4] tracing: Add warnings for unused tracepoints for modules
In reply to Nathan ChancellorQuoted 11 lines · On Wed, 15 Oct 2025 16:19:28 -0700 Nathan Chancellor <[email protected]> wrote:
Hi Steve,
Quoted 8 lines · Steven Rostedt
scripts/Makefile.modfinal +0
-0@@ -28,6 +28,12 @@ ccflags-remove-y := $(CC_FLAGS_CFI) .module-common.o: $(srctree)/scripts/module-common.c FORCE $(call if_changed_rule,cc_o_c)
Quoted 7 lines
scripts/Makefile.modfinal ccflags-remove-y := $(CC_FLAGS_CFI) · line 31
Quoted 1 line
scripts/Makefile.modfinal +1
-0+ifneq ($(WARN_ON_UNUSED_TRACEPOINTS),"")Drop the "", nowhere else in
Kbuildappears to do this.scripts/Makefile.modfinal ccflags-remove-y := $(CC_FLAGS_CFI) · line 32
Quoted 1 line
scripts/Makefile.modfinal +1
-0+cmd_check_tracepoint = ${objtree}/scripts/tracepoint-update $<;Please use $(objtree) to be consistent with the rest of
Kbuild.
OK for both.
Quoted 24 lines
Quoted 24 lines
scripts/Makefile.modfinal +5
-0+else +cmd_check_tracepoint = +endif + quiet_cmd_ld_ko_o = LD [M] $@ cmd_ld_ko_o = \ $(LD) -r $(KBUILD_LDFLAGS) \@@ -57,6 +63,7 @@ if_changed_except = $(if $(call newer_prereqs_except,$(2))$(cmd-check), \ ifdef CONFIG_DEBUG_INFO_BTF_MODULES +$(if $(newer-prereqs),$(call cmd,btf_ko)) endif + +$(call cmd,check_tracepoint) targets += $(modules:%.o=%.ko) $(modules:%.o=%.mod.o) .module-common.oscripts/tracepoint-update.c +0
-0@@ -188,6 +188,13 @@ static int process_tracepoints(void *addr, char const *const fname) } }
Quoted 12 lines
scripts/tracepoint-update.c static int process_tracepoints(void *addr, char const *const fname) · line 197
Quoted 7 lines
scripts/tracepoint-update.c +7
-0+/* +* Modules may not have either section. But if it has one section, +* it should have both of them. +*/ +if (!check_data_sec && !tracepoint_data_sec) +return 0 ; +This feels like it could be its own patch but I guess it does not make much sense without enablement. It might be worth calling this out a bit more in the commit message.
It was found during debugging. I could make this a separate patch in preparation for this patch.
-- Steve
Quoted 7 lines
Quoted 7 lines
scripts/tracepoint-update.c +0
-0if (!check_data_sec) {fprintf (stderr,"no __tracepoint_check in file: %s\n" , fname);return -1 ;Signature · 1 line
2.51.0
Nicolas Schier
maintainerRe: [PATCH v9 2/4] tracing: Add a tracepoint verification check at build time
In reply to Steven RostedtQuoted 30 lines · Steven Rostedt
Quoted 8 lines · On Fri, 17 Oct 2025 22:15:20 +0200 Nicolas Schier <[email protected]> wrote:
Quoted 8 lines
Makefile +8
-0+# To check for unused tracepoints (tracepoints that are defined but never +# called), run with: +# +# make UT=1 +# +# Each unused tracepoints can take up to 5KB of memory in the running kernel. +# It is best to remove any that are not used. +Quoted 8 lines
Makefile endif · line 172
Quoted 5 lines
Makefile +5
-0+ifeq ("$(origin UT)", "command line") + WARN_ON_UNUSED_TRACEPOINTS := $(UT) +endif + +export WARN_ON_UNUSED_TRACEPOINTSIs there a special reason why you chose to introduce a new command-line variable instead of extending
KBUILD_EXTRA_WARN/ W ?Honestly, I didn't think about using
KBUILD_EXTRA_WARN. I also want this option to go away after we remove the current unused tracepoints so that any new ones will always cause a warning.The only reason not to make it always warn is because I don't want to add warnings for the existing code. I'm working on having outreachy projects to remove the currently unused tracepoints. Once that is done, then this option is going to go away and the build will always warn on unused tracepoints.
Quoted 8 lines
I thought it might be easier to remove it without any issues if it's a new command line that goes away in the future.
Looking at
EXTRA_WARN, it appears to be for basic issues with the code and adds new C compiler warning flags. This isn't exactly the same.If you think it makes sense to extend
EXTRA_WARN, I can still go ahead and do that.
thanks for clarification! For completeness: KBUILD_EXTRA_WARN is also used for non-C related checks (cp. scripts/misc-check).
I somehow missed that UT= shall exist temporarily only - if this is still the plan, I don't see a strong reason to put to much work into integration in KBUILD_EXTRA_WARN.
Kind regards
Nicolas