Tracing is a half of the kernel.h in terms of LOCs, although it's
a self-consistent part. It is intended for quick debugging purposes
and isn't used by the normal tracing utilities.
Move it to a separate header. If someone needs to just throw a
trace_printk() in their driver, they will not have to pull all
the heavy tracing machinery.
This is a pure move, except for removing a few 'extern's.
Acked-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Yury Norov (NVIDIA) <yury.norov@gmail.com>
---
include/linux/kernel.h | 196 +--------------------------------
include/linux/trace_printk.h | 205 +++++++++++++++++++++++++++++++++++
2 files changed, 206 insertions(+), 195 deletions(-)
create mode 100644 include/linux/trace_printk.h
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 5b879bfea948..a377335e01da 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -32,7 +32,7 @@
#include <linux/build_bug.h>
#include <linux/sprintf.h>
#include <linux/static_call_types.h>
-#include <linux/instruction_pointer.h>
+#include <linux/trace_printk.h>
#include <linux/util_macros.h>
#include <linux/wordpart.h>
@@ -190,200 +190,6 @@ enum system_states {
};
extern enum system_states system_state;
-/*
- * General tracing related utility functions - trace_printk(),
- * tracing_on/tracing_off and tracing_start()/tracing_stop
- *
- * Use tracing_on/tracing_off when you want to quickly turn on or off
- * tracing. It simply enables or disables the recording of the trace events.
- * This also corresponds to the user space /sys/kernel/tracing/tracing_on
- * file, which gives a means for the kernel and userspace to interact.
- * Place a tracing_off() in the kernel where you want tracing to end.
- * From user space, examine the trace, and then echo 1 > tracing_on
- * to continue tracing.
- *
- * tracing_stop/tracing_start has slightly more overhead. It is used
- * by things like suspend to ram where disabling the recording of the
- * trace is not enough, but tracing must actually stop because things
- * like calling smp_processor_id() may crash the system.
- *
- * Most likely, you want to use tracing_on/tracing_off.
- */
-
-enum ftrace_dump_mode {
- DUMP_NONE,
- DUMP_ALL,
- DUMP_ORIG,
- DUMP_PARAM,
-};
-
-#ifdef CONFIG_TRACING
-void tracing_on(void);
-void tracing_off(void);
-int tracing_is_on(void);
-void tracing_snapshot(void);
-void tracing_snapshot_alloc(void);
-
-extern void tracing_start(void);
-extern void tracing_stop(void);
-
-static inline __printf(1, 2)
-void ____trace_printk_check_format(const char *fmt, ...)
-{
-}
-#define __trace_printk_check_format(fmt, args...) \
-do { \
- if (0) \
- ____trace_printk_check_format(fmt, ##args); \
-} while (0)
-
-/**
- * trace_printk - printf formatting in the ftrace buffer
- * @fmt: the printf format for printing
- *
- * Note: __trace_printk is an internal function for trace_printk() and
- * the @ip is passed in via the trace_printk() macro.
- *
- * This function allows a kernel developer to debug fast path sections
- * that printk is not appropriate for. By scattering in various
- * printk like tracing in the code, a developer can quickly see
- * where problems are occurring.
- *
- * This is intended as a debugging tool for the developer only.
- * Please refrain from leaving trace_printks scattered around in
- * your code. (Extra memory is used for special buffers that are
- * allocated when trace_printk() is used.)
- *
- * A little optimization trick is done here. If there's only one
- * argument, there's no need to scan the string for printf formats.
- * The trace_puts() will suffice. But how can we take advantage of
- * using trace_puts() when trace_printk() has only one argument?
- * By stringifying the args and checking the size we can tell
- * whether or not there are args. __stringify((__VA_ARGS__)) will
- * turn into "()\0" with a size of 3 when there are no args, anything
- * else will be bigger. All we need to do is define a string to this,
- * and then take its size and compare to 3. If it's bigger, use
- * do_trace_printk() otherwise, optimize it to trace_puts(). Then just
- * let gcc optimize the rest.
- */
-
-#define trace_printk(fmt, ...) \
-do { \
- char _______STR[] = __stringify((__VA_ARGS__)); \
- if (sizeof(_______STR) > 3) \
- do_trace_printk(fmt, ##__VA_ARGS__); \
- else \
- trace_puts(fmt); \
-} while (0)
-
-#define do_trace_printk(fmt, args...) \
-do { \
- static const char *trace_printk_fmt __used \
- __section("__trace_printk_fmt") = \
- __builtin_constant_p(fmt) ? fmt : NULL; \
- \
- __trace_printk_check_format(fmt, ##args); \
- \
- if (__builtin_constant_p(fmt)) \
- __trace_bprintk(_THIS_IP_, trace_printk_fmt, ##args); \
- else \
- __trace_printk(_THIS_IP_, fmt, ##args); \
-} while (0)
-
-extern __printf(2, 3)
-int __trace_bprintk(unsigned long ip, const char *fmt, ...);
-
-extern __printf(2, 3)
-int __trace_printk(unsigned long ip, const char *fmt, ...);
-
-/**
- * trace_puts - write a string into the ftrace buffer
- * @str: the string to record
- *
- * Note: __trace_bputs is an internal function for trace_puts and
- * the @ip is passed in via the trace_puts macro.
- *
- * This is similar to trace_printk() but is made for those really fast
- * paths that a developer wants the least amount of "Heisenbug" effects,
- * where the processing of the print format is still too much.
- *
- * This function allows a kernel developer to debug fast path sections
- * that printk is not appropriate for. By scattering in various
- * printk like tracing in the code, a developer can quickly see
- * where problems are occurring.
- *
- * This is intended as a debugging tool for the developer only.
- * Please refrain from leaving trace_puts scattered around in
- * your code. (Extra memory is used for special buffers that are
- * allocated when trace_puts() is used.)
- *
- * Returns: 0 if nothing was written, positive # if string was.
- * (1 when __trace_bputs is used, strlen(str) when __trace_puts is used)
- */
-
-#define trace_puts(str) ({ \
- static const char *trace_printk_fmt __used \
- __section("__trace_printk_fmt") = \
- __builtin_constant_p(str) ? str : NULL; \
- \
- if (__builtin_constant_p(str)) \
- __trace_bputs(_THIS_IP_, trace_printk_fmt); \
- else \
- __trace_puts(_THIS_IP_, str, strlen(str)); \
-})
-extern int __trace_bputs(unsigned long ip, const char *str);
-extern int __trace_puts(unsigned long ip, const char *str, int size);
-
-extern void trace_dump_stack(int skip);
-
-/*
- * The double __builtin_constant_p is because gcc will give us an error
- * if we try to allocate the static variable to fmt if it is not a
- * constant. Even with the outer if statement.
- */
-#define ftrace_vprintk(fmt, vargs) \
-do { \
- if (__builtin_constant_p(fmt)) { \
- static const char *trace_printk_fmt __used \
- __section("__trace_printk_fmt") = \
- __builtin_constant_p(fmt) ? fmt : NULL; \
- \
- __ftrace_vbprintk(_THIS_IP_, trace_printk_fmt, vargs); \
- } else \
- __ftrace_vprintk(_THIS_IP_, fmt, vargs); \
-} while (0)
-
-extern __printf(2, 0) int
-__ftrace_vbprintk(unsigned long ip, const char *fmt, va_list ap);
-
-extern __printf(2, 0) int
-__ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap);
-
-extern void ftrace_dump(enum ftrace_dump_mode oops_dump_mode);
-#else
-static inline void tracing_start(void) { }
-static inline void tracing_stop(void) { }
-static inline void trace_dump_stack(int skip) { }
-
-static inline void tracing_on(void) { }
-static inline void tracing_off(void) { }
-static inline int tracing_is_on(void) { return 0; }
-static inline void tracing_snapshot(void) { }
-static inline void tracing_snapshot_alloc(void) { }
-
-static inline __printf(1, 2)
-int trace_printk(const char *fmt, ...)
-{
- return 0;
-}
-static __printf(1, 0) inline int
-ftrace_vprintk(const char *fmt, va_list ap)
-{
- return 0;
-}
-static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { }
-#endif /* CONFIG_TRACING */
-
/* Rebuild everything on CONFIG_DYNAMIC_FTRACE */
#ifdef CONFIG_DYNAMIC_FTRACE
# define REBUILD_DUE_TO_DYNAMIC_FTRACE
diff --git a/include/linux/trace_printk.h b/include/linux/trace_printk.h
new file mode 100644
index 000000000000..5c9785c49c8e
--- /dev/null
+++ b/include/linux/trace_printk.h
@@ -0,0 +1,205 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_TRACE_PRINTK_H
+#define _LINUX_TRACE_PRINTK_H
+
+#include <linux/compiler_attributes.h>
+#include <linux/instruction_pointer.h>
+#include <linux/stddef.h>
+#include <linux/stringify.h>
+#include <linux/string.h>
+
+/*
+ * General tracing related utility functions - trace_printk(),
+ * tracing_on/tracing_off and tracing_start()/tracing_stop
+ *
+ * Use tracing_on/tracing_off when you want to quickly turn on or off
+ * tracing. It simply enables or disables the recording of the trace events.
+ * This also corresponds to the user space /sys/kernel/tracing/tracing_on
+ * file, which gives a means for the kernel and userspace to interact.
+ * Place a tracing_off() in the kernel where you want tracing to end.
+ * From user space, examine the trace, and then echo 1 > tracing_on
+ * to continue tracing.
+ *
+ * tracing_stop/tracing_start has slightly more overhead. It is used
+ * by things like suspend to ram where disabling the recording of the
+ * trace is not enough, but tracing must actually stop because things
+ * like calling smp_processor_id() may crash the system.
+ *
+ * Most likely, you want to use tracing_on/tracing_off.
+ */
+
+enum ftrace_dump_mode {
+ DUMP_NONE,
+ DUMP_ALL,
+ DUMP_ORIG,
+ DUMP_PARAM,
+};
+
+#ifdef CONFIG_TRACING
+void tracing_on(void);
+void tracing_off(void);
+int tracing_is_on(void);
+void tracing_snapshot(void);
+void tracing_snapshot_alloc(void);
+
+void tracing_start(void);
+void tracing_stop(void);
+
+static inline __printf(1, 2)
+void ____trace_printk_check_format(const char *fmt, ...)
+{
+}
+#define __trace_printk_check_format(fmt, args...) \
+do { \
+ if (0) \
+ ____trace_printk_check_format(fmt, ##args); \
+} while (0)
+
+/**
+ * trace_printk - printf formatting in the ftrace buffer
+ * @fmt: the printf format for printing
+ *
+ * Note: __trace_printk is an internal function for trace_printk() and
+ * the @ip is passed in via the trace_printk() macro.
+ *
+ * This function allows a kernel developer to debug fast path sections
+ * that printk is not appropriate for. By scattering in various
+ * printk like tracing in the code, a developer can quickly see
+ * where problems are occurring.
+ *
+ * This is intended as a debugging tool for the developer only.
+ * Please refrain from leaving trace_printks scattered around in
+ * your code. (Extra memory is used for special buffers that are
+ * allocated when trace_printk() is used.)
+ *
+ * A little optimization trick is done here. If there's only one
+ * argument, there's no need to scan the string for printf formats.
+ * The trace_puts() will suffice. But how can we take advantage of
+ * using trace_puts() when trace_printk() has only one argument?
+ * By stringifying the args and checking the size we can tell
+ * whether or not there are args. __stringify((__VA_ARGS__)) will
+ * turn into "()\0" with a size of 3 when there are no args, anything
+ * else will be bigger. All we need to do is define a string to this,
+ * and then take its size and compare to 3. If it's bigger, use
+ * do_trace_printk() otherwise, optimize it to trace_puts(). Then just
+ * let gcc optimize the rest.
+ */
+
+#define trace_printk(fmt, ...) \
+do { \
+ char _______STR[] = __stringify((__VA_ARGS__)); \
+ if (sizeof(_______STR) > 3) \
+ do_trace_printk(fmt, ##__VA_ARGS__); \
+ else \
+ trace_puts(fmt); \
+} while (0)
+
+#define do_trace_printk(fmt, args...) \
+do { \
+ static const char *trace_printk_fmt __used \
+ __section("__trace_printk_fmt") = \
+ __builtin_constant_p(fmt) ? fmt : NULL; \
+ \
+ __trace_printk_check_format(fmt, ##args); \
+ \
+ if (__builtin_constant_p(fmt)) \
+ __trace_bprintk(_THIS_IP_, trace_printk_fmt, ##args); \
+ else \
+ __trace_printk(_THIS_IP_, fmt, ##args); \
+} while (0)
+
+__printf(2, 3)
+int __trace_bprintk(unsigned long ip, const char *fmt, ...);
+
+__printf(2, 3)
+int __trace_printk(unsigned long ip, const char *fmt, ...);
+
+/**
+ * trace_puts - write a string into the ftrace buffer
+ * @str: the string to record
+ *
+ * Note: __trace_bputs is an internal function for trace_puts and
+ * the @ip is passed in via the trace_puts macro.
+ *
+ * This is similar to trace_printk() but is made for those really fast
+ * paths that a developer wants the least amount of "Heisenbug" effects,
+ * where the processing of the print format is still too much.
+ *
+ * This function allows a kernel developer to debug fast path sections
+ * that printk is not appropriate for. By scattering in various
+ * printk like tracing in the code, a developer can quickly see
+ * where problems are occurring.
+ *
+ * This is intended as a debugging tool for the developer only.
+ * Please refrain from leaving trace_puts scattered around in
+ * your code. (Extra memory is used for special buffers that are
+ * allocated when trace_puts() is used.)
+ *
+ * Returns: 0 if nothing was written, positive # if string was.
+ * (1 when __trace_bputs is used, strlen(str) when __trace_puts is used)
+ */
+
+#define trace_puts(str) ({ \
+ static const char *trace_printk_fmt __used \
+ __section("__trace_printk_fmt") = \
+ __builtin_constant_p(str) ? str : NULL; \
+ \
+ if (__builtin_constant_p(str)) \
+ __trace_bputs(_THIS_IP_, trace_printk_fmt); \
+ else \
+ __trace_puts(_THIS_IP_, str, strlen(str)); \
+})
+int __trace_bputs(unsigned long ip, const char *str);
+int __trace_puts(unsigned long ip, const char *str, int size);
+
+void trace_dump_stack(int skip);
+
+/*
+ * The double __builtin_constant_p is because gcc will give us an error
+ * if we try to allocate the static variable to fmt if it is not a
+ * constant. Even with the outer if statement.
+ */
+#define ftrace_vprintk(fmt, vargs) \
+do { \
+ if (__builtin_constant_p(fmt)) { \
+ static const char *trace_printk_fmt __used \
+ __section("__trace_printk_fmt") = \
+ __builtin_constant_p(fmt) ? fmt : NULL; \
+ \
+ __ftrace_vbprintk(_THIS_IP_, trace_printk_fmt, vargs); \
+ } else \
+ __ftrace_vprintk(_THIS_IP_, fmt, vargs); \
+} while (0)
+
+__printf(2, 0) int
+__ftrace_vbprintk(unsigned long ip, const char *fmt, va_list ap);
+
+__printf(2, 0) int
+__ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap);
+
+void ftrace_dump(enum ftrace_dump_mode oops_dump_mode);
+#else
+static inline void tracing_start(void) { }
+static inline void tracing_stop(void) { }
+static inline void trace_dump_stack(int skip) { }
+
+static inline void tracing_on(void) { }
+static inline void tracing_off(void) { }
+static inline int tracing_is_on(void) { return 0; }
+static inline void tracing_snapshot(void) { }
+static inline void tracing_snapshot_alloc(void) { }
+
+static inline __printf(1, 2)
+int trace_printk(const char *fmt, ...)
+{
+ return 0;
+}
+static __printf(1, 0) inline int
+ftrace_vprintk(const char *fmt, va_list ap)
+{
+ return 0;
+}
+static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { }
+#endif /* CONFIG_TRACING */
+
+#endif
--
2.43.0
On Fri, 5 Dec 2025 12:52:35 -0500 "Yury Norov (NVIDIA)" <yury.norov@gmail.com> wrote:
> Tracing is a half of the kernel.h in terms of LOCs, although it's
> a self-consistent part. It is intended for quick debugging purposes
> and isn't used by the normal tracing utilities.
>
> Move it to a separate header. If someone needs to just throw a
> trace_printk() in their driver, they will not have to pull all
> the heavy tracing machinery.
>
> This is a pure move, except for removing a few 'extern's.
>
This one blows up my x86_64 allmodconfig, gcc-15.2.0:
In file included from ./include/linux/string.h:386,
from ./include/linux/trace_printk.h:9,
from ./include/linux/kernel.h:34,
from arch/x86/purgatory/purgatory.c:12:
./include/linux/fortify-string.h:626:63: error: expected identifier or '(' before '{' token
626 | p_size_field, q_size_field, op) ({ \
| ^
./include/linux/fortify-string.h:694:27: note: in expansion of macro '__fortify_memcpy_chk'
694 | #define memmove(p, q, s) __fortify_memcpy_chk(p, q, s, \
| ^~~~~~~~~~~~~~~~~~~~
arch/x86/purgatory/../boot/string.h:11:7: note: in expansion of macro 'memmove'
11 | void *memmove(void *dst, const void *src, size_t len);
| ^~~~~~~
./include/linux/fortify-string.h:258:9: error: expected identifier or '(' before '__builtin_choose_expr'
258 | __builtin_choose_expr(__is_constexpr(__builtin_strlen(p)), \
| ^~~~~~~~~~~~~~~~~~~~~
arch/x86/purgatory/../boot/string.h:23:15: note: in expansion of macro 'strlen'
23 | extern size_t strlen(const char *s);
| ^~~~~~
make[4]: *** [scripts/Makefile.build:287: arch/x86/purgatory/purgatory.o] Error 1
make[3]: *** [scripts/Makefile.build:556: arch/x86/purgatory] Error 2
make[2]: *** [scripts/Makefile.build:556: arch/x86] Error 2
make[1]: *** [/usr/src/25/Makefile:2054: .] Error 2
make: *** [Makefile:248: __sub-make] Error 2
[adding Kees]
On 12/16/25 4:13 PM, Andrew Morton wrote:
> On Fri, 5 Dec 2025 12:52:35 -0500 "Yury Norov (NVIDIA)" <yury.norov@gmail.com> wrote:
>
>> Tracing is a half of the kernel.h in terms of LOCs, although it's
>> a self-consistent part. It is intended for quick debugging purposes
>> and isn't used by the normal tracing utilities.
>>
>> Move it to a separate header. If someone needs to just throw a
>> trace_printk() in their driver, they will not have to pull all
>> the heavy tracing machinery.
>>
>> This is a pure move, except for removing a few 'extern's.
>>
Hm, for a pure move, this shouldn't be necessary. Anyway, not using
FORTIFY in purgatory.o fixes this build error.
Or maybe there's a better answer.
---
arch/x86/purgatory/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/x86/purgatory/Makefile
+++ b/arch/x86/purgatory/Makefile
@@ -62,7 +62,7 @@ PURGATORY_CFLAGS_REMOVE += $(CC_FLAGS_C
endif
CFLAGS_REMOVE_purgatory.o += $(PURGATORY_CFLAGS_REMOVE)
-CFLAGS_purgatory.o += $(PURGATORY_CFLAGS)
+CFLAGS_purgatory.o += $(PURGATORY_CFLAGS) -D__NO_FORTIFY
CFLAGS_REMOVE_sha256.o += $(PURGATORY_CFLAGS_REMOVE)
CFLAGS_sha256.o += $(PURGATORY_CFLAGS)
>
> This one blows up my x86_64 allmodconfig, gcc-15.2.0:
>
> In file included from ./include/linux/string.h:386,
> from ./include/linux/trace_printk.h:9,
> from ./include/linux/kernel.h:34,
> from arch/x86/purgatory/purgatory.c:12:
> ./include/linux/fortify-string.h:626:63: error: expected identifier or '(' before '{' token
> 626 | p_size_field, q_size_field, op) ({ \
> | ^
> ./include/linux/fortify-string.h:694:27: note: in expansion of macro '__fortify_memcpy_chk'
> 694 | #define memmove(p, q, s) __fortify_memcpy_chk(p, q, s, \
> | ^~~~~~~~~~~~~~~~~~~~
> arch/x86/purgatory/../boot/string.h:11:7: note: in expansion of macro 'memmove'
> 11 | void *memmove(void *dst, const void *src, size_t len);
> | ^~~~~~~
> ./include/linux/fortify-string.h:258:9: error: expected identifier or '(' before '__builtin_choose_expr'
> 258 | __builtin_choose_expr(__is_constexpr(__builtin_strlen(p)), \
> | ^~~~~~~~~~~~~~~~~~~~~
> arch/x86/purgatory/../boot/string.h:23:15: note: in expansion of macro 'strlen'
> 23 | extern size_t strlen(const char *s);
> | ^~~~~~
> make[4]: *** [scripts/Makefile.build:287: arch/x86/purgatory/purgatory.o] Error 1
> make[3]: *** [scripts/Makefile.build:556: arch/x86/purgatory] Error 2
> make[2]: *** [scripts/Makefile.build:556: arch/x86] Error 2
> make[1]: *** [/usr/src/25/Makefile:2054: .] Error 2
> make: *** [Makefile:248: __sub-make] Error 2
>
--
~Randy
On Tue, Dec 16, 2025 at 09:24:55PM -0800, Randy Dunlap wrote:
> [adding Kees]
>
> On 12/16/25 4:13 PM, Andrew Morton wrote:
> > On Fri, 5 Dec 2025 12:52:35 -0500 "Yury Norov (NVIDIA)" <yury.norov@gmail.com> wrote:
> >
> >> Tracing is a half of the kernel.h in terms of LOCs, although it's
> >> a self-consistent part. It is intended for quick debugging purposes
> >> and isn't used by the normal tracing utilities.
> >>
> >> Move it to a separate header. If someone needs to just throw a
> >> trace_printk() in their driver, they will not have to pull all
> >> the heavy tracing machinery.
> >>
> >> This is a pure move, except for removing a few 'extern's.
> >>
>
> Hm, for a pure move, this shouldn't be necessary. Anyway, not using
> FORTIFY in purgatory.o fixes this build error.
> Or maybe there's a better answer.
>
> ---
> arch/x86/purgatory/Makefile | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> --- a/arch/x86/purgatory/Makefile
> +++ b/arch/x86/purgatory/Makefile
> @@ -62,7 +62,7 @@ PURGATORY_CFLAGS_REMOVE += $(CC_FLAGS_C
> endif
>
> CFLAGS_REMOVE_purgatory.o += $(PURGATORY_CFLAGS_REMOVE)
> -CFLAGS_purgatory.o += $(PURGATORY_CFLAGS)
> +CFLAGS_purgatory.o += $(PURGATORY_CFLAGS) -D__NO_FORTIFY
>
> CFLAGS_REMOVE_sha256.o += $(PURGATORY_CFLAGS_REMOVE)
> CFLAGS_sha256.o += $(PURGATORY_CFLAGS)
That happened because the new trace_printk.h includes string.h for
strlen(), so all kernel.h users now indirectly include it, and it
causes, seemingly, a circular dependency if FORTIFY is enabled.
A fix would be dropping trace_printk.h from kernel.h, or switching the
only user of string.h, trace_puts(), to __builtin_strlen().
Notice, Andy has concerned about this on the previous round, and also
suggested __builtin_strlen():
https://lkml.org/lkml/2025/12/3/910
I deem to drop trace_printk.h from kernel.h - it is more aligned with
the idea of unloading the header. The original motivation to keep
trace_printk.h in kernel.h was just because a similar printk.h is living
there. But after all, this is a purely debugging header, so no need for
almost every C file to bear debugging stuff.
I can actually do both - switch to an intrinsic and drop the header.
Guys, please let me know what do you thing.
Thanks,
Yury
On Wed, 17 Dec 2025 22:59:33 -0500 Yury Norov <yury.norov@gmail.com> wrote: > I deem to drop trace_printk.h from kernel.h - it is more aligned with > the idea of unloading the header. The original motivation to keep > trace_printk.h in kernel.h was just because a similar printk.h is living > there. But after all, this is a purely debugging header, so no need for > almost every C file to bear debugging stuff. It is a big deal for debugging stuff. A lot of developers debug their code with trace_printk(), and do the "shotgun approach", where they cut and paste trace_printk()s all over their code in several files. Having to now add: #include <linux/trace_printk.h> whenever a trace_printk() is added is going to be a big PITA and slow down all debugging efforts. -- Steve
On 12/18/25 9:33 AM, Steven Rostedt wrote: > On Wed, 17 Dec 2025 22:59:33 -0500 > Yury Norov <yury.norov@gmail.com> wrote: > >> I deem to drop trace_printk.h from kernel.h - it is more aligned with >> the idea of unloading the header. The original motivation to keep >> trace_printk.h in kernel.h was just because a similar printk.h is living >> there. But after all, this is a purely debugging header, so no need for >> almost every C file to bear debugging stuff. > > It is a big deal for debugging stuff. A lot of developers debug their code > with trace_printk(), and do the "shotgun approach", where they cut and > paste trace_printk()s all over their code in several files. Having to now add: > > #include <linux/trace_printk.h> > > whenever a trace_printk() is added is going to be a big PITA and slow down > all debugging efforts. Eh? Maybe a PITA, but surely not a big one. Slow down "all debugging efforts?" Please cut down on the hyperbole. -- ~Randy
On Thu, Dec 18, 2025 at 10:34:07AM -0800, Randy Dunlap wrote: > > > On 12/18/25 9:33 AM, Steven Rostedt wrote: > > On Wed, 17 Dec 2025 22:59:33 -0500 > > Yury Norov <yury.norov@gmail.com> wrote: > > > >> I deem to drop trace_printk.h from kernel.h - it is more aligned with > >> the idea of unloading the header. The original motivation to keep > >> trace_printk.h in kernel.h was just because a similar printk.h is living > >> there. But after all, this is a purely debugging header, so no need for > >> almost every C file to bear debugging stuff. > > > > It is a big deal for debugging stuff. A lot of developers debug their code > > with trace_printk(), and do the "shotgun approach", where they cut and > > paste trace_printk()s all over their code in several files. Having to now add: > > > > #include <linux/trace_printk.h> > > > > whenever a trace_printk() is added is going to be a big PITA and slow down > > all debugging efforts. > > Eh? Maybe a PITA, but surely not a big one. > Slow down "all debugging efforts?" > Please cut down on the hyperbole. For me, removing trace_prink.h saves 1.5-2% of compile time: Before: #1 real 5m12.602s #2 real 5m11.333s After: #1 real 5m6.190s #2 real 5m7.151s I'm building ubuntu-derived localyesconfig with a couple extra drivers. Steven, if you're not absolutely against, lets drop the trace_printk.h? Thanks, Yury
On Thu, 18 Dec 2025 12:33:49 -0500
Steven Rostedt <rostedt@goodmis.org> wrote:
> On Wed, 17 Dec 2025 22:59:33 -0500
> Yury Norov <yury.norov@gmail.com> wrote:
>
> > I deem to drop trace_printk.h from kernel.h - it is more aligned with
> > the idea of unloading the header. The original motivation to keep
> > trace_printk.h in kernel.h was just because a similar printk.h is living
> > there. But after all, this is a purely debugging header, so no need for
> > almost every C file to bear debugging stuff.
>
> It is a big deal for debugging stuff. A lot of developers debug their code
> with trace_printk(), and do the "shotgun approach", where they cut and
> paste trace_printk()s all over their code in several files. Having to now add:
>
> #include <linux/trace_printk.h>
>
> whenever a trace_printk() is added is going to be a big PITA and slow down
> all debugging efforts.
>
I don't actually remember why I had __trace_puts() pass in the size. I
could change it to:
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 5b46924fdff5..d5a939b8c391 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -331,10 +331,10 @@ int __trace_printk(unsigned long ip, const char *fmt, ...);
if (__builtin_constant_p(str)) \
__trace_bputs(_THIS_IP_, trace_printk_fmt); \
else \
- __trace_puts(_THIS_IP_, str, strlen(str)); \
+ __trace_puts(_THIS_IP_, str); \
})
extern int __trace_bputs(unsigned long ip, const char *str);
-extern int __trace_puts(unsigned long ip, const char *str, int size);
+extern int __trace_puts(unsigned long ip, const char *str);
extern void trace_dump_stack(int skip);
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index e575956ef9b5..686741edb803 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -1178,11 +1178,10 @@ EXPORT_SYMBOL_GPL(__trace_array_puts);
* __trace_puts - write a constant string into the trace buffer.
* @ip: The address of the caller
* @str: The constant string to write
- * @size: The size of the string.
*/
-int __trace_puts(unsigned long ip, const char *str, int size)
+int __trace_puts(unsigned long ip, const char *str)
{
- return __trace_array_puts(printk_trace, ip, str, size);
+ return __trace_array_puts(printk_trace, ip, str, strlen(str));
}
EXPORT_SYMBOL_GPL(__trace_puts);
@@ -1201,7 +1200,7 @@ int __trace_bputs(unsigned long ip, const char *str)
int size = sizeof(struct bputs_entry);
if (!printk_binsafe(tr))
- return __trace_puts(ip, str, strlen(str));
+ return __trace_puts(ip, str);
if (!(tr->trace_flags & TRACE_ITER(PRINTK)))
return 0;
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index b6d42fe06115..de4e6713b84e 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -2116,7 +2116,7 @@ extern void tracing_log_err(struct trace_array *tr,
* about performance). The internal_trace_puts() is for such
* a purpose.
*/
-#define internal_trace_puts(str) __trace_puts(_THIS_IP_, str, strlen(str))
+#define internal_trace_puts(str) __trace_puts(_THIS_IP_, str)
#undef FTRACE_ENTRY
#define FTRACE_ENTRY(call, struct_name, id, tstruct, print) \
Which removes the strlen() altogether.
-- Steve
On Thu, Dec 18, 2025 at 12:43:26PM -0500, Steven Rostedt wrote:
> On Thu, 18 Dec 2025 12:33:49 -0500
> Steven Rostedt <rostedt@goodmis.org> wrote:
>
> > On Wed, 17 Dec 2025 22:59:33 -0500
> > Yury Norov <yury.norov@gmail.com> wrote:
> >
> > > I deem to drop trace_printk.h from kernel.h - it is more aligned with
> > > the idea of unloading the header. The original motivation to keep
> > > trace_printk.h in kernel.h was just because a similar printk.h is living
> > > there. But after all, this is a purely debugging header, so no need for
> > > almost every C file to bear debugging stuff.
> >
> > It is a big deal for debugging stuff. A lot of developers debug their code
> > with trace_printk(), and do the "shotgun approach", where they cut and
> > paste trace_printk()s all over their code in several files. Having to now add:
> >
> > #include <linux/trace_printk.h>
> >
> > whenever a trace_printk() is added is going to be a big PITA and slow down
> > all debugging efforts.
> >
>
> I don't actually remember why I had __trace_puts() pass in the size. I
> could change it to:
This is the best approach. I'll schedule it for v4. Would you like me to
take it as-is, or you'd send a patch?
> diff --git a/include/linux/kernel.h b/include/linux/kernel.h
> index 5b46924fdff5..d5a939b8c391 100644
> --- a/include/linux/kernel.h
> +++ b/include/linux/kernel.h
> @@ -331,10 +331,10 @@ int __trace_printk(unsigned long ip, const char *fmt, ...);
> if (__builtin_constant_p(str)) \
> __trace_bputs(_THIS_IP_, trace_printk_fmt); \
> else \
> - __trace_puts(_THIS_IP_, str, strlen(str)); \
> + __trace_puts(_THIS_IP_, str); \
> })
> extern int __trace_bputs(unsigned long ip, const char *str);
> -extern int __trace_puts(unsigned long ip, const char *str, int size);
> +extern int __trace_puts(unsigned long ip, const char *str);
>
> extern void trace_dump_stack(int skip);
>
> diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
> index e575956ef9b5..686741edb803 100644
> --- a/kernel/trace/trace.c
> +++ b/kernel/trace/trace.c
> @@ -1178,11 +1178,10 @@ EXPORT_SYMBOL_GPL(__trace_array_puts);
> * __trace_puts - write a constant string into the trace buffer.
> * @ip: The address of the caller
> * @str: The constant string to write
> - * @size: The size of the string.
> */
> -int __trace_puts(unsigned long ip, const char *str, int size)
> +int __trace_puts(unsigned long ip, const char *str)
> {
> - return __trace_array_puts(printk_trace, ip, str, size);
> + return __trace_array_puts(printk_trace, ip, str, strlen(str));
> }
> EXPORT_SYMBOL_GPL(__trace_puts);
>
> @@ -1201,7 +1200,7 @@ int __trace_bputs(unsigned long ip, const char *str)
> int size = sizeof(struct bputs_entry);
>
> if (!printk_binsafe(tr))
> - return __trace_puts(ip, str, strlen(str));
> + return __trace_puts(ip, str);
>
> if (!(tr->trace_flags & TRACE_ITER(PRINTK)))
> return 0;
> diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
> index b6d42fe06115..de4e6713b84e 100644
> --- a/kernel/trace/trace.h
> +++ b/kernel/trace/trace.h
> @@ -2116,7 +2116,7 @@ extern void tracing_log_err(struct trace_array *tr,
> * about performance). The internal_trace_puts() is for such
> * a purpose.
> */
> -#define internal_trace_puts(str) __trace_puts(_THIS_IP_, str, strlen(str))
> +#define internal_trace_puts(str) __trace_puts(_THIS_IP_, str)
>
> #undef FTRACE_ENTRY
> #define FTRACE_ENTRY(call, struct_name, id, tstruct, print) \
>
>
>
> Which removes the strlen() altogether.
>
> -- Steve
On Thu, 18 Dec 2025 15:33:47 -0500 Yury Norov <yury.norov@gmail.com> wrote: > > I don't actually remember why I had __trace_puts() pass in the size. I > > could change it to: > > This is the best approach. I'll schedule it for v4. Would you like me to > take it as-is, or you'd send a patch? > Let me send an official patch. -- Steve
On Thu, 18 Dec 2025 16:25:42 -0500 Steven Rostedt <rostedt@goodmis.org> wrote: > On Thu, 18 Dec 2025 15:33:47 -0500 > Yury Norov <yury.norov@gmail.com> wrote: > > > > I don't actually remember why I had __trace_puts() pass in the size. I > > > could change it to: > > > > This is the best approach. I'll schedule it for v4. Would you like me to > > take it as-is, or you'd send a patch? > > > > Let me send an official patch. > You can find it here (I Cc'd you too). Feel free to add it to your patch set. https://lore.kernel.org/all/20251218163739.5605f9ea@gandalf.local.home/ -- Steve
On Thu, Dec 18, 2025 at 04:41:03PM -0500, Steven Rostedt wrote: > On Thu, 18 Dec 2025 16:25:42 -0500 > Steven Rostedt <rostedt@goodmis.org> wrote: > > > On Thu, 18 Dec 2025 15:33:47 -0500 > > Yury Norov <yury.norov@gmail.com> wrote: > > > > > > I don't actually remember why I had __trace_puts() pass in the size. I > > > > could change it to: > > > > > > This is the best approach. I'll schedule it for v4. Would you like me to > > > take it as-is, or you'd send a patch? > > > > > > > Let me send an official patch. > > > > You can find it here (I Cc'd you too). Feel free to add it to your patch set. > > https://lore.kernel.org/all/20251218163739.5605f9ea@gandalf.local.home/ Thanks, will do.
On 12/17/25 7:59 PM, Yury Norov wrote:
> On Tue, Dec 16, 2025 at 09:24:55PM -0800, Randy Dunlap wrote:
>> [adding Kees]
>>
>> On 12/16/25 4:13 PM, Andrew Morton wrote:
>>> On Fri, 5 Dec 2025 12:52:35 -0500 "Yury Norov (NVIDIA)" <yury.norov@gmail.com> wrote:
>>>
>>>> Tracing is a half of the kernel.h in terms of LOCs, although it's
>>>> a self-consistent part. It is intended for quick debugging purposes
>>>> and isn't used by the normal tracing utilities.
>>>>
>>>> Move it to a separate header. If someone needs to just throw a
>>>> trace_printk() in their driver, they will not have to pull all
>>>> the heavy tracing machinery.
>>>>
>>>> This is a pure move, except for removing a few 'extern's.
>>>>
>>
>> Hm, for a pure move, this shouldn't be necessary. Anyway, not using
>> FORTIFY in purgatory.o fixes this build error.
>> Or maybe there's a better answer.
>>
>> ---
>> arch/x86/purgatory/Makefile | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> --- a/arch/x86/purgatory/Makefile
>> +++ b/arch/x86/purgatory/Makefile
>> @@ -62,7 +62,7 @@ PURGATORY_CFLAGS_REMOVE += $(CC_FLAGS_C
>> endif
>>
>> CFLAGS_REMOVE_purgatory.o += $(PURGATORY_CFLAGS_REMOVE)
>> -CFLAGS_purgatory.o += $(PURGATORY_CFLAGS)
>> +CFLAGS_purgatory.o += $(PURGATORY_CFLAGS) -D__NO_FORTIFY
>>
>> CFLAGS_REMOVE_sha256.o += $(PURGATORY_CFLAGS_REMOVE)
>> CFLAGS_sha256.o += $(PURGATORY_CFLAGS)
>
> That happened because the new trace_printk.h includes string.h for
> strlen(), so all kernel.h users now indirectly include it, and it
> causes, seemingly, a circular dependency if FORTIFY is enabled.
>
> A fix would be dropping trace_printk.h from kernel.h, or switching the
> only user of string.h, trace_puts(), to __builtin_strlen().
>
> Notice, Andy has concerned about this on the previous round, and also
> suggested __builtin_strlen():
>
> https://lkml.org/lkml/2025/12/3/910
>
> I deem to drop trace_printk.h from kernel.h - it is more aligned with
> the idea of unloading the header. The original motivation to keep
> trace_printk.h in kernel.h was just because a similar printk.h is living
> there. But after all, this is a purely debugging header, so no need for
> almost every C file to bear debugging stuff.
>
> I can actually do both - switch to an intrinsic and drop the header.
>
> Guys, please let me know what do you thing.
There are some problems with using __builtin_mem{cpy,set} -- don't
know about __builtin_str{whatever}. See
commit 4ce97317f41d
Author: Nick Desaulniers <nick.desaulniers+lkml@gmail.com>
Date: Wed Aug 7 15:15:32 2019 -0700
x86/purgatory: Do not use __builtin_memcpy and __builtin_memset
We should drop the header from kernel.h soon anyway, whether now or
in a few weeks/months. IMHO.
--
~Randy
On Tue, Dec 16, 2025 at 04:13:16PM -0800, Andrew Morton wrote: > On Fri, 5 Dec 2025 12:52:35 -0500 "Yury Norov (NVIDIA)" <yury.norov@gmail.com> wrote: > > > Tracing is a half of the kernel.h in terms of LOCs, although it's > > a self-consistent part. It is intended for quick debugging purposes > > and isn't used by the normal tracing utilities. > > > > Move it to a separate header. If someone needs to just throw a > > trace_printk() in their driver, they will not have to pull all > > the heavy tracing machinery. > > > > This is a pure move, except for removing a few 'extern's. > > > > This one blows up my x86_64 allmodconfig, gcc-15.2.0: Thanks, Andrew. I'll take a look.
On Fri, Dec 05, 2025 at 12:52:35PM -0500, Yury Norov (NVIDIA) wrote: > Tracing is a half of the kernel.h in terms of LOCs, although it's > a self-consistent part. It is intended for quick debugging purposes > and isn't used by the normal tracing utilities. > > Move it to a separate header. If someone needs to just throw a > trace_printk() in their driver, they will not have to pull all > the heavy tracing machinery. > > This is a pure move, except for removing a few 'extern's. Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> -- With Best Regards, Andy Shevchenko
© 2016 - 2026 Red Hat, Inc.