Skip to contentSkip to conversation

tracepoints: Add warnings for unused tracepoints and trace events

PATCH Superseded Steven Rostedt 5 participants 15 messages Oct 15, 2025 – Oct 21, 2025

Subsystems (4)

v9 of 10 Superseded Latest is v10 →

lore
Share & tools
lore
#0 lore raw

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
#1 lore raw

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
index 46f860529df5..f19624b3ed92 100644
@@ -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
#2 lore raw

PATCH v9 2/4 tracing: Add a tracepoint verification check at build time

In reply to Steven Rostedt

From: 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
index 17cfa11ca716..a3141890f38f 100644
@@ -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
index 8a9a2e732a65..08ca759fb992 100644
@@ -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
index 826ce3f8e1f8..1e53d3626c78 100644
@@ -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
index f19624b3ed92..0941e5ce7b57 100644
@@ -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
index 433849ff7529..d304029fa6da 100755
@@ -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
#8 lore raw

PATCH v9 3/4 tracepoint: Do not warn for unused event that is exported

In reply to Steven Rostedt

From: 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
index 1e53d3626c78..8a56f3278b1b 100644
@@ -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
#9 lore raw

PATCH v9 4/4 tracing: Add warnings for unused tracepoints for modules

In reply to Steven Rostedt

From: 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
index 542ba462ed3e..6f909979af91 100644
@@ -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
index 6ec30f39d0ad..7e068de9c7f1 100644
@@ -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
#3 lore raw

Re: [PATCH v9 2/4] tracing: Add a tracepoint verification check at build time

In reply to Steven Rostedt

Hi 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
index 8a9a2e732a65..08ca759fb992 100644
@@ -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

maintainer
#4 lore raw

Re: [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
index 8a9a2e732a65..08ca759fb992 100644
@@ -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

#10 lore raw

Re: [PATCH v9 4/4] tracing: Add warnings for unused tracepoints for modules

In reply to Steven Rostedt

Hi Steve,

scripts/Makefile.modfinal ccflags-remove-y := $(CC_FLAGS_CFI) · line 31

Quoted 9 lines · Steven Rostedt
scripts/Makefile.modfinal +1 -0
index 542ba462ed3e..6f909979af91 100644
@@ -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.o
 
scripts/tracepoint-update.c +0 -0
index 6ec30f39d0ad..7e068de9c7f1 100644

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 -0
 	if (!check_data_sec) {
 		fprintf(stderr,	"no __tracepoint_check in file: %s\n", fname);
 		return -1;
Signature · 1 line
2.51.0
#14 lore raw

Re: [PATCH v9 4/4] tracing: Add warnings for unused tracepoints for modules

In reply to Steven Rostedt
kernel 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
maintainer
#5 lore raw

Re: [PATCH v9 2/4] tracing: Add a tracepoint verification check at build time

In reply to Steven Rostedt
Quoted 109 lines · Steven Rostedt

From: 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 +3 -0
index 17cfa11ca716..a3141890f38f 100644
@@ -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

maintainer
#11 lore raw

Re: [PATCH v9 4/4] tracing: Add warnings for unused tracepoints for modules

In reply to Nathan Chancellor
Quoted 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
index 542ba462ed3e..6f909979af91 100644
@@ -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.

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

maintainer
#6 lore raw

Re: [PATCH v9 2/4] tracing: Add a tracepoint verification check at build time

In reply to Nicolas Schier
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_TRACEPOINTS  

Is 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

maintainer
#12 lore raw

Re: [PATCH v9 4/4] tracing: Add warnings for unused tracepoints for modules

In reply to Nicolas Schier
Quoted 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
index 542ba462ed3e..6f909979af91 100644
@@ -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.

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 =
+endif  

The else part is not required, cp. definition of e.g. cmd_checkdoc in scripts/Makefile.build.

Thanks, will do.

-- Steve

maintainer
#13 lore raw

Re: [PATCH v9 4/4] tracing: Add warnings for unused tracepoints for modules

In reply to Nathan Chancellor
Quoted 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
index 542ba462ed3e..6f909979af91 100644
@@ -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 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.

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.o
 
scripts/tracepoint-update.c +0 -0
index 6ec30f39d0ad..7e068de9c7f1 100644
@@ -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 -0
 	if (!check_data_sec) {
 		fprintf(stderr,	"no __tracepoint_check in file: %s\n", fname);
 		return -1;
Signature · 1 line
2.51.0
maintainer
#7 lore raw

Re: [PATCH v9 2/4] tracing: Add a tracepoint verification check at build time

In reply to Steven Rostedt
Quoted 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_TRACEPOINTS  

Is 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