tracing: Updates for 7.2
Subsystems (6)
cover tracing: Updates for 7.2
git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git
trace/for-next
Head SHA1: 292c8197e3685aa7ea5a3803ca240b2210fcd021
Ao Sun (1):
tracing: Fix README path for synthetic_events
David Carlier (1):
tracepoint: Add lockdep rcu_is_watching() check to trace_##name##_enabled()
Martin Kaiser (1):
tracefs: Fix typo in a comment of eventfs_callback() kerneldoc
Pengpeng Hou (1):
tracing: Bound synthetic-field strings with seq_buf
Qian-Yu Lin (1):
tracing: Remove local variable for argument detection from trace_printk()
Rosen Penev (1):
tracing: Simplify pages allocation for tracing_map logic
Shuvam Pandey (1):
seq_buf: Export seq_buf_putmem_hex() and add KUnit tests
Steven Rostedt (2):
tracing: Allow perf to read synthetic events
tracing: Move trace_iterator_increment() into trace_find_next_entry_inc()
Vineeth Pillai (2):
cpufreq: amd-pstate: Use trace_call__##name() at guarded tracepoint call site
HID: Use trace_call__##name() at guarded tracepoint call sites
Yash Suthar (2):
tracing: Remove redundant IS_ERR() check in trace_pipe_open()
tracing: Switch trace_recursion_record.c code over to use guard()
Yu Peng (2):
tracing/branch: Use pr_warn() instead of printk(KERN_WARNING)
tracing: Use krealloc_array() for trace option array growth
----
drivers/cpufreq/amd-pstate.c | 3 +- drivers/hid/intel-ish-hid/ipc/pci-ish.c | 2 +- include/linux/trace_printk.h | 3 +- include/linux/tracefs.h | 2 +- include/linux/tracepoint.h | 4 ++ kernel/trace/trace.c | 25 +++---- kernel/trace/trace_branch.c | 9 +-- kernel/trace/trace_events_hist.c | 41 +++++++---- kernel/trace/trace_events_synth.c | 121 +++++++++++++++++++++++++------- kernel/trace/trace_recursion_record.c | 8 +-- kernel/trace/trace_remote.c | 2 +- kernel/trace/tracing_map.c | 30 +++----- kernel/trace/tracing_map.h | 2 +- lib/seq_buf.c | 1 + lib/tests/seq_buf_kunit.c | 34 +++++++++ 15 files changed, 197 insertions(+), 90 deletions(-)
PATCH 1/15 tracing: Remove redundant IS_ERR() check in trace_pipe_open()
From: Yash Suthar <[email protected]>
in trace_pipe_open() already check the IS_ERR(iter) and return early on error,so iter after will be valid and it is safe to return 0 at end.
--- kernel/trace/trace_remote.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/trace/trace_remote.c +1 -1
@@ -602,7 +602,7 @@ static int trace_pipe_open(struct inode *inode, struct file *filp) filp->private_data = iter; -return IS_ERR (iter) ?PTR_ERR (iter) :0 ; +return 0 ; }static int trace_pipe_release (struct inode *inode,struct file *filp)
Signature · 1 line
2.53.0
PATCH 2/15 seq_buf: Export seq_buf_putmem_hex() and add KUnit tests
In reply to Steven RostedtFrom: Shuvam Pandey <[email protected]>
The seq_buf KUnit suite does not exercise seq_buf_putmem_hex().
Add one test for the len > 8 chunking path and one overflow test where a later chunk no longer fits in the buffer.
Export seq_buf_putmem_hex() as well so SEQ_BUF_KUNIT_TEST=m links cleanly. Without the export, modpost reports seq_buf_putmem_hex as undefined when seq_buf_kunit is built as a module.
--- lib/seq_buf.c | 1 + lib/tests/seq_buf_kunit.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+)
lib/seq_buf.c +1 -0
@@ -298,6 +298,7 @@ int seq_buf_putmem_hex(struct seq_buf *s, const void *mem, }return 0 ; } +EXPORT_SYMBOL_GPL (seq_buf_putmem_hex);/** * seq_buf_path - copy a path into the sequence buffer
lib/tests/seq_buf_kunit.c +34 -0
@@ -184,6 +184,38 @@ static void seq_buf_get_buf_commit_test(struct kunit *test)KUNIT_EXPECT_TRUE (test,seq_buf_has_overflowed (&s)); } +static void seq_buf_putmem_hex_test (struct kunit *test) +{ +DECLARE_SEQ_BUF (s,24 ); +const u8 data[] = {0 ,1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 }; +#ifdef __BIG_ENDIAN +const char *expected ="0001020304050607 0809 " ; +#else +const char *expected ="0706050403020100 0908 " ; +#endif + +KUNIT_EXPECT_EQ (test,seq_buf_putmem_hex (&s, data,sizeof (data)),0 ); +KUNIT_EXPECT_FALSE (test,seq_buf_has_overflowed (&s)); +KUNIT_EXPECT_EQ (test,seq_buf_used (&s),strlen (expected)); +KUNIT_EXPECT_STREQ (test,seq_buf_str (&s), expected); +} + +static void seq_buf_putmem_hex_overflow_test (struct kunit *test) +{ +DECLARE_SEQ_BUF (s,20 ); +const u8 data[] = {0 ,1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 }; +#ifdef __BIG_ENDIAN +const char *expected ="0001020304050607 " ; +#else +const char *expected ="0706050403020100 " ; +#endif + +KUNIT_EXPECT_EQ (test,seq_buf_putmem_hex (&s, data,sizeof (data)),-1 ); +KUNIT_EXPECT_TRUE (test,seq_buf_has_overflowed (&s)); +KUNIT_EXPECT_EQ (test,seq_buf_used (&s),20 ); +KUNIT_EXPECT_STREQ (test,seq_buf_str (&s), expected); +} +static struct kunit_case seq_buf_test_cases[] = {KUNIT_CASE (seq_buf_init_test),KUNIT_CASE (seq_buf_declare_test),
@@ -194,6 +226,8 @@ static struct kunit_case seq_buf_test_cases[] = {KUNIT_CASE (seq_buf_printf_test),KUNIT_CASE (seq_buf_printf_overflow_test),KUNIT_CASE (seq_buf_get_buf_commit_test), +KUNIT_CASE (seq_buf_putmem_hex_test), + KUNIT_CASE(seq_buf_putmem_hex_overflow_test), {} };
Signature · 1 line
2.53.0
PATCH 3/15 tracing: Bound synthetic-field strings with seq_buf
In reply to Steven RostedtFrom: Pengpeng Hou <[email protected]>
The synthetic field helpers build a prefixed synthetic variable name and a generated hist command in fixed MAX_FILTER_STR_VAL buffers. The current code appends those strings with raw strcat(), so long key lists, field names, or saved filters can run past the end of the staging buffers.
Build both strings with seq_buf and propagate -E2BIG if either the synthetic variable name or the generated command exceeds MAX_FILTER_STR_VAL. This keeps the existing tracing-side limit while using the helper intended for bounded command construction.
--- kernel/trace/trace_events_hist.c | 41 ++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 12 deletions(-)
kernel/trace/trace_events_hist.c +29 -12
@@ -8,6 +8,7 @@#include <linux/module.h> #include <linux/kallsyms.h> #include <linux/security.h> +#include <linux/seq_buf.h> #include <linux/mutex.h> #include <linux/slab.h> #include <linux/stacktrace.h>
@@ -2967,13 +2968,22 @@ find_synthetic_field_var(struct hist_trigger_data *target_hist_data, {struct hist_field *event_var;char *synthetic_name; +struct seq_buf s; synthetic_name =kzalloc (MAX_FILTER_STR_VAL ,GFP_KERNEL );if (!synthetic_name)return ERR_PTR (-ENOMEM ); -strcpy (synthetic_name,"synthetic_" ); -strcat (synthetic_name, field_name); +seq_buf_init (&s, synthetic_name,MAX_FILTER_STR_VAL ); +seq_buf_printf (&s,"synthetic_%s" , field_name); + +/* Terminate synthetic_name with a NUL. */ +seq_buf_str (&s); + +if (seq_buf_has_overflowed (&s)) { +kfree (synthetic_name); +return ERR_PTR (-E2BIG ); + } event_var =find_event_var (target_hist_data, system, event_name, synthetic_name);
@@ -3019,6 +3029,7 @@ create_field_var_hist(struct hist_trigger_data *target_hist_data,struct hist_field *key_field;struct hist_field *event_var;char *saved_filter; +struct seq_buf s;char *cmd;int ret;
@@ -3063,28 +3074,34 @@ create_field_var_hist(struct hist_trigger_data *target_hist_data,return ERR_PTR (-ENOMEM ); } +seq_buf_init (&s, cmd,MAX_FILTER_STR_VAL ); +/* Use the same keys as the compatible histogram */ -strcat (cmd,"keys=" ); +seq_buf_puts (&s,"keys=" );for_each_hist_key_field (i, hist_data) { key_field = hist_data->fields[i];if (!first) -strcat (cmd,"," ); -strcat (cmd, key_field->field->name); +seq_buf_putc (&s,',' ); +seq_buf_puts (&s, key_field->field->name); first = false; }/* Create the synthetic field variable specification */ -strcat (cmd,":synthetic_" ); -strcat (cmd, field_name); -strcat (cmd,"=" ); -strcat (cmd, field_name); +seq_buf_printf (&s,":synthetic_%s=%s" , field_name, field_name);/* Use the same filter as the compatible histogram */ saved_filter =find_trigger_filter (hist_data, file); -if (saved_filter) { -strcat (cmd," if " ); -strcat (cmd, saved_filter); +if (saved_filter) +seq_buf_printf (&s," if %s" , saved_filter); + +/* Terminate cmd with a NUL. */ +seq_buf_str (&s); + +if (seq_buf_has_overflowed (&s)) { +kfree (cmd); +kfree (var_hist); +return ERR_PTR (-E2BIG ); } var_hist->cmd =kstrdup (cmd,GFP_KERNEL );
Signature · 1 line
2.53.0
PATCH 4/15 tracepoint: Add lockdep rcu_is_watching() check to trace_##name##_enabled()
In reply to Steven RostedtFrom: David Carlier <[email protected]>
The trace_##name##_enabled() static call branch is used when work needs to be done for a tracepoint. It allows that work to be skipped when the tracepoint is not active and still uses the static_branch() of the tracepoint to keep performance.
Tracepoints themselves require being called in "RCU watching" locations otherwise races can occur that corrupts things. In order to make sure lockdep triggers at tracepoint locations, the lockdep checks are added to the tracepoint calling location and trigger even if the tracepoint is not enabled. This is done because a poorly placed tracepoint may never be detected if it is never enabled when lockdep is enabled.
As trace_##name##_enabled() also prevents the lockdep checks when the tracepoint is disabled add lockdep checks to that as well so that if one is placed in a location that RCU is not watching, it will trigger a lockdep splat even when the tracepoint is not enabled.
--- include/linux/tracepoint.h | 4 ++++ 1 file changed, 4 insertions(+)
include/linux/tracepoint.h +4 -0
@@ -293,6 +293,10 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) static inline bool \ trace_##name##_enabled(void) \ { \ + if (IS_ENABLED(CONFIG_LOCKDEP)) { \ + WARN_ONCE(!rcu_is_watching(), \ + "RCU not watching for tracepoint"); \ + } \ return static_branch_unlikely(&__tracepoint_##name.key);\ }
Signature · 1 line
2.53.0
Re: [for-next][PATCH 04/15] tracepoint: Add lockdep rcu_is_watching() check to trace_##name##_enabled()
Hi Steven, David,
Quoted 19 lines · Steven Rostedt
From: David Carlier <[email protected]>
The trace_##name##_enabled() static call branch is used when work needs to be done for a tracepoint. It allows that work to be skipped when the tracepoint is not active and still uses the
static_branch()of the tracepoint to keep performance.Tracepoints themselves require being called in "RCU watching" locations otherwise races can occur that corrupts things. In order to make sure lockdep triggers at tracepoint locations, the lockdep checks are added to the tracepoint calling location and trigger even if the tracepoint is not enabled. This is done because a poorly placed tracepoint may never be detected if it is never enabled when lockdep is enabled.
As trace_##name##_enabled() also prevents the lockdep checks when the tracepoint is disabled add lockdep checks to that as well so that if one is placed in a location that RCU is not watching, it will trigger a lockdep splat even when the tracepoint is not enabled.
Quoted 8 lines
Cc Vineeth Pillai (Google) <[email protected]>Cc Mathieu Desnoyers <[email protected]>Cc Masami Hiramatsu <[email protected]>Cc Peter Zijlstra <[email protected]>Signed-off-by David Carlier <[email protected]>[ Updated the change log ]Signed-off-by Steven Rostedt <[email protected]>
Thanks for your patch, which is now commit 9764e731ef6abacd ("tracepoint: Add lockdep rcu_is_watching() check to trace_##name##_enabled()") in v7.2-rc1.
This is causing multiple warnings during system suspend on Renesas SH-Mobile AG5, R-Car H1. and R-Car M2-W:
PM: suspend entry (deep)
-Filesystems sync: 0.018 seconds
+Filesystems sync: 0.027 seconds
Freezing user space processes
Freezing user space processes completed (elapsed 0.001 seconds) OOM killer disabled.
Freezing remaining freezable tasks
Freezing remaining freezable tasks completed (elapsed 0.001 seconds)
-PM: suspend devices took 0.110 seconds
+------------[ cut here ]------------
+WARNING: include/trace/events/preemptirq.h:36 at
trace_irq_disable_enabled+0x3c/0x64, CPU#0: swapper/0/0
+------------[ cut here ]------------
+RCU not watching for tracepoint
+Modules linked in:
+WARNING: include/trace/events/preemptirq.h:40 at
trace_irq_enable_enabled+0x3c/0x64, CPU#1: swapper/1/0
+
+RCU not watching for tracepoint
+CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted7.1.0-rc4-koelsch-00006-g9764e731ef6a #2337 VOLUNTARY
+Hardware name: Generic R-Car Gen2 (Flattened Device Tree) +Call trace:
+ unwind_backtrace from show_stack+0x10/0x14
+ show_stack from dump_stack_lvl+0x7c/0xb0
+ dump_stack_lvl from __warn+0x98/0x27c
+ __warn from warn_slowpath_fmt+0xc0/0x124
+ warn_slowpath_fmt from trace_irq_disable_enabled+0x3c/0x64
+ trace_irq_disable_enabled from trace_hardirqs_off+0x6c/0xb0
+ trace_hardirqs_off from __irq_svc+0x48/0xac +Exception stack(0xc1401f20 to 0xc1401f68)
+1f20: c027a764 effb0e88 00000000 00000001 c140b080 c027a764c140801c c140b080
+1f40: c1407fe0 00000000 c140801c 00000000 fffffff8 c1401f70
c0b35980 c0b359d8
+1f60: 20000113 ffffffff
+ __irq_svc from cpu_idle_poll+0x114/0x130
+ cpu_idle_poll from do_idle+0xb8/0x268
+ do_idle from cpu_startup_entry+0x28/0x2c
+ cpu_startup_entry from rest_init+0x150/0x178
+ rest_init from start_kernel+0x634/0x6d8 +irq event stamp: 19112
+Modules linked in:
+hardirqs last enabled at (19111): [<c0b35adc>]
default_idle_call+0xe8/0x104
+
+hardirqs last disabled at (19112): [<c0200b88>] __irq_svc+0x48/0xac
+CPU: 1 UID: 0 PID: 0 Comm: swapper/1 Not tainted7.1.0-rc4-koelsch-00006-g9764e731ef6a #2337 VOLUNTARY
+Hardware name: Generic R-Car Gen2 (Flattened Device Tree) +Call trace:
+ unwind_backtrace from show_stack+0x10/0x14
+ show_stack from dump_stack_lvl+0x7c/0xb0
+ dump_stack_lvl from __warn+0x98/0x27c
+ __warn from warn_slowpath_fmt+0xc0/0x124
+ warn_slowpath_fmt from trace_irq_enable_enabled+0x3c/0x64
+ trace_irq_enable_enabled from trace_hardirqs_on+0x40/0xbc
+ trace_hardirqs_on from __irq_svc+0x94/0xac +Exception stack(0xf0865f48 to 0xf0865f90)
+5f40: c027a764 effc2e88 00000000 00000001c227cec0 c027a764
+5f60: c140801c c227cec0 c1407fe0 413fc0f2 c140801c 00000000
fffffff8 f0865f98
+5f80: c0b35980 c0b35988 20000013 ffffffff
+ __irq_svc from cpu_idle_poll+0xc4/0x130
+ cpu_idle_poll from do_idle+0xb8/0x268
+ do_idle from cpu_startup_entry+0x28/0x2c
+ cpu_startup_entry from secondary_start_kernel+0xdc/0xf0
+ secondary_start_kernel from 0x4020f094
+irq event stamp: 27461
+softirqs last enabled at (19008): [<c02341ec>] handle_softirqs+0x174/0x3e4
+hardirqs last enabled at (27461): [<c027a7d0>] do_idle+0x124/0x268
+softirqs last disabled at (18991): [<c0234a84>] __irq_exit_rcu+0xf0/0x194
+hardirqs last disabled at (27460): [<c027a734>] do_idle+0x88/0x268
+---[ end trace 0000000000000000 ]---
+softirqs last enabled at (27438): [<c02341ec>] handle_softirqs+0x174/0x3e4
+softirqs last disabled at (27425): [<c0234a84>] __irq_exit_rcu+0xf0/0x194
+---[ end trace 0000000000000000 ]---
+PM: suspend devices took 0.380 seconds
Disabling non-boot CPUs ...Other Renesas ARM32 platforms I tried (R-Mobile A1, RZ/A1H, RZ/A2M) are unafffected, perhaps because they are not SMP?
All Renesas ARM64 platforms I tried (R-Car Gen3/4) are also unaffected.
Reverting the commit fixes the issue.
Do you have a clue?
Thanks!
include/linux/tracepoint.h static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) · line 301
Quoted 12 lines
include/linux/tracepoint.h +4
-0@@ -293,6 +293,10 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) static inline bool \ trace_##name##_enabled(void) \ { \ + if (IS_ENABLED(CONFIG_LOCKDEP)) { \ + WARN_ONCE(!rcu_is_watching(), \ + "RCU not watching for tracepoint"); \ + } \ return static_branch_unlikely(&__tracepoint_##name.key);\ }
Gr{oetje,eeting}s,
Geert
Signature · 5 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected] In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Re: [for-next][PATCH 04/15] tracepoint: Add lockdep rcu_is_watching() check to trace_##name##_enabled()
Quoted 7 lines · On Tue, 30 Jun 2026 19:39:02 +0200 Geert Uytterhoeven <[email protected]>…
Other Renesas ARM32 platforms I tried (R-Mobile A1, RZ/A1H, RZ/A2M) are unafffected, perhaps because they are not SMP?
All Renesas ARM64 platforms I tried (R-Car Gen3/4) are also unaffected.Reverting the commit fixes the issue.
Do you have a clue?
Yes, it means the code was buggy before the commit. The commit will trigger warnings in places that have issues. Before the commit, the buggy code was never caught.
It's like enabling KASAN and finding code that has use-after-free. Disabling KASAN is not the fix.
Tracepoints are managed by using RCU. There's places that RCU is turned off, meaning a tracepoint in one of those locations can be triggered when RCU is not active which may have a use-after-free semantic when the tracepoint is enabled.
Tracepoints hidden by trace_#tracepoint#_enabled() are not caught when RCU is disabled and the tracepoint is not active. This commit makes these locations trigger even when the tracepoint is not active.
One way to find out if this is an existing bug or not, could you enable the preemptirq tracepoints and run the tests again with the commit reverted?
echo 1 > /sys/kernel/tracing/events/preemptirq/enable
This will enable the events that are hidden without the commit. If it triggers when enabled, it shows the commit found a bug.
If you get the same errors, the bug isn't with the commit in question, it's with the tracepoints being called during suspend/resume. We will need to fix that if that's the case.
-- Steve
Re: [for-next][PATCH 04/15] tracepoint: Add lockdep rcu_is_watching() check to trace_##name##_enabled()
Hi Steven,
Quoted 17 lines · Steven Rostedt
Quoted 7 lines · On Tue, 30 Jun 2026 19:39:02 +0200 Geert Uytterhoeven <[email protected]>…
Other Renesas ARM32 platforms I tried (R-Mobile A1, RZ/A1H, RZ/A2M) are unafffected, perhaps because they are not SMP?
All Renesas ARM64 platforms I tried (R-Car Gen3/4) are also unaffected.Reverting the commit fixes the issue.
Do you have a clue?
Yes, it means the code was buggy before the commit. The commit will trigger warnings in places that have issues. Before the commit, the buggy code was never caught.
It's like enabling KASAN and finding code that has use-after-free. Disabling KASAN is not the fix.
Quoted 8 lines
Tracepoints are managed by using RCU. There's places that RCU is turned off, meaning a tracepoint in one of those locations can be triggered when RCU is not active which may have a use-after-free semantic when the tracepoint is enabled.
Tracepoints hidden by trace_#tracepoint#_enabled() are not caught when RCU is disabled and the tracepoint is not active. This commit makes these locations trigger even when the tracepoint is not active.
Sorry, my wording could indeed be better: this commit probably does not "cause" the issue, but merely exposes it.
Quoted 11 lines
One way to find out if this is an existing bug or not, could you enable the preemptirq tracepoints and run the tests again with the commit reverted?
echo 1 >
/sys/kernel/tracing/events/preemptirq/enableThis will enable the events that are hidden without the commit. If it triggers when enabled, it shows the commit found a bug.
If you get the same errors, the bug isn't with the commit in question, it's with the tracepoints being called during suspend/resume. We will need to fix that if that's the case.
Thanks, it does not trigger with the commit reverted and the "echo 1 > ...".
Gr{oetje,eeting}s,
Geert
Signature · 5 lines
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected] In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Re: [for-next][PATCH 04/15] tracepoint: Add lockdep rcu_is_watching() check to trace_##name##_enabled()
Quoted 1 line · On Wed, 1 Jul 2026 11:24:31 +0200 Geert Uytterhoeven <[email protected]>…
Thanks, it does not trigger with the commit reverted and the "echo 1 > ...".
Ah found the issue;
#define trace(point, args) \
do { \
if (trace_##point##_enabled()) { \
bool exit_rcu = false; \
if (in_nmi()) \
break; \
if (!IS_ENABLED(CONFIG_TINY_RCU) && \
is_idle_task(current)) { \
ct_irq_enter(); \
exit_rcu = true; \
} \
trace_##point(args); \
if (exit_rcu) \
ct_irq_exit(); \
} \
} while (0)#endif
The code within the enabled() call checks if RCU is watching, and if not, it makes it watch. So yeah, this is a special case.
The following patch should fix the issue:
include/linux/tracepoint.h +11 -1
@@ -292,13 +292,18 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) { \ } \ static inline bool \ + __trace_##name##_enabled(void) \ + { \ + return static_branch_unlikely(&__tracepoint_##name.key);\ + } \ + static inline bool \ trace_##name##_enabled(void) \ { \ if (IS_ENABLED(CONFIG_LOCKDEP)) { \ WARN_ONCE(!rcu_is_watching(), \ "RCU not watching for tracepoint"); \ } \ - return static_branch_unlikely(&__tracepoint_##name.key);\ + return __trace_##name##_enabled(); \ }#define __DECLARE_TRACE (name, proto, args, cond, data_proto) \
@@ -457,6 +462,11 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) { \ } \ static inline bool \ + __trace_##name##_enabled(void) \ + { \ + return false; \ + } \ + static inline bool \ trace_##name##_enabled(void) \ { \ return false; \
kernel/trace/trace_preemptirq.c +1 -1
@@ -30,7 +30,7 @@#else #define trace (point, args) \ do { \ - if (trace_##point##_enabled()) { \ + if (__trace_##point##_enabled()) { \ bool exit_rcu = false; \ if (in_nmi()) \ break; \
PATCH 5/15 tracing: Remove local variable for argument detection from trace_printk()
In reply to Steven RostedtFrom: Qian-Yu Lin <[email protected]>
The trace_printk() macro uses a local variable _______STR to detect whether variadic arguments are present. This name can shadow outer variables.
Replace the local variable with sizeof applied directly to the stringified arguments:
if (sizeof __stringify((__VA_ARGS__)) > 3)
This eliminates the shadowing risk entirely without introducing any additional includes or local variables.
Verified with objdump on samples/trace_printk that all four cases branch correctly: __trace_bputs, __trace_puts, __trace_bprintk, and __trace_printk.
--- include/linux/trace_printk.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
include/linux/trace_printk.h +1 -2
@@ -86,8 +86,7 @@ do { \#define trace_printk (fmt, ...) \ do { \ - char _______STR[] = __stringify((__VA_ARGS__)); \ - if (sizeof(_______STR) > 3) \ + if (sizeof __stringify((__VA_ARGS__)) > 3) \ do_trace_printk(fmt, ##__VA_ARGS__); \ else \ trace_puts(fmt); \
Signature · 1 line
2.53.0
PATCH 6/15 tracing: Switch trace_recursion_record.c code over to use guard()
In reply to Steven RostedtFrom: Yash Suthar <[email protected]>
Switch mutex_lock()/mutex_unlock() to guard(). also drop the ret local variable and return directly.
--- kernel/trace/trace_recursion_record.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
kernel/trace/trace_recursion_record.c +3 -5
@@ -180,9 +180,8 @@ static const struct seq_operations recursed_function_seq_ops = {static int recursed_function_open (struct inode *inode,struct file *file) { -int ret =0 ; +guard (mutex)(&recursed_function_lock); -mutex_lock (&recursed_function_lock);/* If this file was opened for write, then erase contents */ if ((file->f_mode &FMODE_WRITE ) && (file->f_flags &O_TRUNC )) {/* disable updating records */
@@ -194,10 +193,9 @@ static int recursed_function_open(struct inode *inode, struct file *file)atomic_set (&nr_records,0 ); }if (file->f_mode &FMODE_READ ) - ret =seq_open (file, &recursed_function_seq_ops); -mutex_unlock (&recursed_function_lock); +return seq_open (file, &recursed_function_seq_ops); -return ret; +return 0 ; } static ssize_t recursed_function_write(struct file *file,
Signature · 1 line
2.53.0
PATCH 7/15 tracefs: Fix typo in a comment of eventfs_callback() kerneldoc
In reply to Steven RostedtFrom: Martin Kaiser <[email protected]>
Fix a typo "evetnfs files" to "eventfs files" in a comment.
--- include/linux/tracefs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/tracefs.h +1 -1
@@ -30,7 +30,7 @@ struct eventfs_file;* @data: data to pass to the created file ops * @fops: the file operations of the created file * -* The evetnfs files are dynamically created. The struct eventfs_entry array +* The eventfs files are dynamically created. The struct eventfs_entry array * is passed to eventfs_create_dir() or eventfs_create_events_dir() that will * be used to create the files within those directories. When a lookup * or access to a file within the directory is made, the struct eventfs_entry
Signature · 1 line
2.53.0
PATCH 8/15 cpufreq: amd-pstate: Use trace_call__##name() at guarded tracepoint call site
In reply to Steven RostedtFrom: Vineeth Pillai <[email protected]>
Replace trace_foo() with the new trace_call__foo() at sites already guarded by trace_foo_enabled(), avoiding a redundant static_branch_unlikely() re-evaluation inside the tracepoint. trace_call__foo() calls the tracepoint callbacks directly without utilizing the static branch again.
--- drivers/cpufreq/amd-pstate.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/cpufreq/amd-pstate.c +2 -1
@@ -368,7 +368,8 @@ static int amd_pstate_set_floor_perf(struct cpufreq_policy *policy, u8 perf) out_trace:if (trace_amd_pstate_cppc_req2_enabled ()) -trace_amd_pstate_cppc_req2 (cpudata->cpu, perf, changed, ret); +trace_call__amd_pstate_cppc_req2 (cpudata->cpu, perf, changed, + ret);return ret; }
Signature · 1 line
2.53.0
PATCH 9/15 HID: Use trace_call__##name() at guarded tracepoint call sites
In reply to Steven RostedtFrom: Vineeth Pillai <[email protected]>
Replace trace_foo() with the new trace_call__foo() at sites already guarded by trace_foo_enabled(), avoiding a redundant static_branch_unlikely() re-evaluation inside the tracepoint. trace_call__foo() calls the tracepoint callbacks directly without utilizing the static branch again.
Original v2 series:
https://lore.kernel.org/linux-trace-kernel/[email protected]/
Parts of the original v2 series have already been merged in mainline. This patch is being reposted as a follow-up cleanup for the remaining unmerged pieces.
--- drivers/hid/intel-ish-hid/ipc/pci-ish.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hid/intel-ish-hid/ipc/pci-ish.c +1 -1
@@ -110,7 +110,7 @@ void ish_event_tracer(struct ishtp_device *dev, const char *format, ...)vsnprintf (tmp_buf,sizeof (tmp_buf), format, args);va_end (args); -trace_ishtp_dump (tmp_buf); +trace_call__ishtp_dump (tmp_buf); } }
Signature · 1 line
2.53.0
PATCH 10/15 tracing: Allow perf to read synthetic events
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
Currently, perf can not enable synthetic events. When it does, it either causes a warning in the kernel or errors with "no such device".
Add the necessary code to allow perf to also attach to synthetic events.
--- kernel/trace/trace_events_synth.c | 121 +++++++++++++++++++++++------- 1 file changed, 94 insertions(+), 27 deletions(-)
kernel/trace/trace_events_synth.c +94 -27
@@ -499,28 +499,19 @@ static unsigned int trace_stack(struct synth_trace_event *entry,return len; } -static void trace_event_raw_event_synth (void *__data, -u64 *var_ref_vals, -unsigned int *var_ref_idx) +static __always_inline int get_field_size(struct synth_event *event, +u64 *var_ref_vals, +unsigned int *var_ref_idx) { -unsigned int i, n_u64, val_idx, len, data_size =0 ; -struct trace_event_file *trace_file = __data; -struct synth_trace_event *entry; -struct trace_event_buffer fbuffer; -struct trace_buffer *buffer; -struct synth_event *event; -int fields_size =0 ; - - event = trace_file->event_call->data; - -if (trace_trigger_soft_disabled (trace_file)) -return ; +int fields_size; fields_size = event->n_u64 *sizeof (u64); -for (i =0 ; i < event->n_dynamic_fields; i++) { +for (int i =0 ; i < event->n_dynamic_fields; i++) {unsigned int field_pos = event->dynamic_fields[i]->field_pos;char *str_val; +int val_idx; +int len; val_idx = var_ref_idx[field_pos]; str_val = (char *)(long )var_ref_vals[val_idx];
@@ -535,18 +526,18 @@ static void trace_event_raw_event_synth(void *__data, fields_size += len; } +return fields_size; +} -/* -* Avoid ring buffer recursion detection, as this event -* is being performed within another event. -*/ - buffer = trace_file->tr->array_buffer.buffer; -guard (ring_buffer_nest)(buffer); - - entry =trace_event_buffer_reserve (&fbuffer, trace_file, -sizeof (*entry) + fields_size); -if (!entry) -return ; +static __always_inline void write_synth_entry(struct synth_event *event, +struct synth_trace_event *entry, +u64 *var_ref_vals, +unsigned int *var_ref_idx) +{ +int data_size =0 ; +int i, n_u64; +int val_idx; +int len;for (i =0 , n_u64 =0 ; i < event->n_fields; i++) { val_idx = var_ref_idx[i];
@@ -587,10 +578,83 @@ static void trace_event_raw_event_synth(void *__data, n_u64++; } } +} + +static void trace_event_raw_event_synth (void *__data, +u64 *var_ref_vals, +unsigned int *var_ref_idx) +{ +struct trace_event_file *trace_file = __data; +struct synth_trace_event *entry; +struct trace_event_buffer fbuffer; +struct trace_buffer *buffer; +struct synth_event *event; +int fields_size; + + event = trace_file->event_call->data; + +if (trace_trigger_soft_disabled (trace_file)) +return ; + + fields_size =get_field_size (event, var_ref_vals, var_ref_idx); + +/* +* Avoid ring buffer recursion detection, as this event +* is being performed within another event. +*/ + buffer = trace_file->tr->array_buffer.buffer; +guard (ring_buffer_nest)(buffer); + + entry =trace_event_buffer_reserve (&fbuffer, trace_file, +sizeof (*entry) + fields_size); +if (!entry) +return ; + +write_synth_entry (event, entry, var_ref_vals, var_ref_idx);trace_event_buffer_commit (&fbuffer); } +#ifdef CONFIG_PERF_EVENTS +static void perf_event_raw_event_synth (void *__data, +u64 *var_ref_vals, +unsigned int *var_ref_idx) +{ +struct trace_event_call *call = __data; +struct synth_trace_event *entry; +struct hlist_head *perf_head; +struct synth_event *event; +struct pt_regs *regs; +int fields_size; +size_t size; +int context; + + event = call->data; + + perf_head =this_cpu_ptr (call->perf_events); + +if (!perf_head ||hlist_empty (perf_head)) +return ; + + fields_size =get_field_size (event, var_ref_vals, var_ref_idx); + + size =ALIGN (sizeof (*entry) + fields_size,8 ); + + entry =perf_trace_buf_alloc (size, ®s, &context); + +if (unlikely (!entry)) +return ; + +write_synth_entry (event, entry, var_ref_vals, var_ref_idx); + +perf_fetch_caller_regs (regs); + +perf_trace_buf_submit (entry, size, context, + call->event.type,1 , regs, + perf_head,NULL ); +} +#endif +static void free_synth_event_print_fmt (struct trace_event_call *call) {if (call) {
@@ -917,6 +981,9 @@ static int register_synth_event(struct synth_event *event) call->flags =TRACE_EVENT_FL_TRACEPOINT ; call->class->reg = synth_event_reg; call->class->probe = trace_event_raw_event_synth; +#ifdef CONFIG_PERF_EVENTS + call->class->perf_probe = perf_event_raw_event_synth; +#endif call->data = event; call->tp = event->tp;
Signature · 1 line
2.53.0
Re: [for-next][PATCH 10/15] tracing: Allow perf to read synthetic events
Quoted 7 lines · Steven Rostedt
From: Steven Rostedt <[email protected]>
Currently, perf can not enable synthetic events. When it does, it either causes a warning in the kernel or errors with "no such device".
Add the necessary code to allow perf to also attach to synthetic events.
Thanks so much for doing this work! I hoped to spend some time testing it, but there's never enough time. For the synthetic event I was wondering what values end up in the perf sample like 'period'? I can imagine this being the case and that, if you are doing something like a futex wait duration, having to interpret the raw data rather than just getting aggregation for free in perf report via the period. That's not wrong but I was just curious.
Thanks again,
Ian
Quoted 181 lines
Cc Masami Hiramatsu <[email protected]>Cc Mathieu Desnoyers <[email protected]>Cc Arnaldo Carvalho de Melo <[email protected]>Cc Jiri Olsa <[email protected]>Cc Peter Zijlstra <[email protected]>Reported-by Ian Rogers <[email protected]>Acked-by Namhyung Kim <[email protected]>Signed-off-by Steven Rostedt (Google) <[email protected]>--- kernel/trace/trace_events_synth.c | 121 +++++++++++++++++++++++------- 1 file changed, 94 insertions(+), 27 deletions(-)kernel/trace/trace_events_synth.c +94
-28@@ -499,28 +499,19 @@ static unsigned int trace_stack(struct synth_trace_event *entry,return len; } -static void trace_event_raw_event_synth (void *__data, -u64 *var_ref_vals, -unsigned int *var_ref_idx) +static __always_inline int get_field_size(struct synth_event *event, +u64 *var_ref_vals, +unsigned int *var_ref_idx) { -unsigned int i, n_u64, val_idx, len, data_size =0 ; -struct trace_event_file *trace_file = __data; -struct synth_trace_event *entry; -struct trace_event_buffer fbuffer; -struct trace_buffer *buffer; -struct synth_event *event; -int fields_size =0 ; - - event = trace_file->event_call->data; - -if (trace_trigger_soft_disabled (trace_file)) -return ; +int fields_size; fields_size = event->n_u64 *sizeof (u64); -for (i =0 ; i < event->n_dynamic_fields; i++) { +for (int i =0 ; i < event->n_dynamic_fields; i++) {unsigned int field_pos = event->dynamic_fields[i]->field_pos;char *str_val; +int val_idx; +int len; val_idx = var_ref_idx[field_pos]; str_val = (char *)(long )var_ref_vals[val_idx];@@ -535,18 +526,18 @@ static void trace_event_raw_event_synth(void *__data, fields_size += len; } +return fields_size; +} -/* -* Avoid ring buffer recursion detection, as this event -* is being performed within another event. -*/ - buffer = trace_file->tr->array_buffer.buffer; -guard (ring_buffer_nest)(buffer); - - entry =trace_event_buffer_reserve (&fbuffer, trace_file, -sizeof (*entry) + fields_size); -if (!entry) -return ; +static __always_inline void write_synth_entry(struct synth_event *event, +struct synth_trace_event *entry, +u64 *var_ref_vals, +unsigned int *var_ref_idx) +{ +int data_size =0 ; +int i, n_u64; +int val_idx; +int len;for (i =0 , n_u64 =0 ; i < event->n_fields; i++) { val_idx = var_ref_idx[i];@@ -587,10 +578,83 @@ static void trace_event_raw_event_synth(void *__data, n_u64++; } } +} + +static void trace_event_raw_event_synth (void *__data, +u64 *var_ref_vals, +unsigned int *var_ref_idx) +{ +struct trace_event_file *trace_file = __data; +struct synth_trace_event *entry; +struct trace_event_buffer fbuffer; +struct trace_buffer *buffer; +struct synth_event *event; +int fields_size; + + event = trace_file->event_call->data; + +if (trace_trigger_soft_disabled (trace_file)) +return ; + + fields_size =get_field_size (event, var_ref_vals, var_ref_idx); + +/* +* Avoid ring buffer recursion detection, as this event +* is being performed within another event. +*/ + buffer = trace_file->tr->array_buffer.buffer; +guard (ring_buffer_nest)(buffer); + + entry =trace_event_buffer_reserve (&fbuffer, trace_file, +sizeof (*entry) + fields_size); +if (!entry) +return ; + +write_synth_entry (event, entry, var_ref_vals, var_ref_idx);trace_event_buffer_commit (&fbuffer); } +#ifdef CONFIG_PERF_EVENTS +static void perf_event_raw_event_synth (void *__data, +u64 *var_ref_vals, +unsigned int *var_ref_idx) +{ +struct trace_event_call *call = __data; +struct synth_trace_event *entry; +struct hlist_head *perf_head; +struct synth_event *event; +struct pt_regs *regs; +int fields_size; +size_t size; +int context; + + event = call->data; + + perf_head =this_cpu_ptr (call->perf_events); + +if (!perf_head ||hlist_empty (perf_head)) +return ; + + fields_size =get_field_size (event, var_ref_vals, var_ref_idx); + + size =ALIGN (sizeof (*entry) + fields_size,8 ); + + entry =perf_trace_buf_alloc (size, ®s, &context); + +if (unlikely (!entry)) +return ; + +write_synth_entry (event, entry, var_ref_vals, var_ref_idx); + +perf_fetch_caller_regs (regs); + +perf_trace_buf_submit (entry, size, context, + call->event.type,1 , regs, + perf_head,NULL ); +} +#endif +static void free_synth_event_print_fmt (struct trace_event_call *call) {if (call) {@@ -917,6 +981,9 @@ static int register_synth_event(struct synth_event *event) call->flags =TRACE_EVENT_FL_TRACEPOINT ; call->class->reg = synth_event_reg; call->class->probe = trace_event_raw_event_synth; +#ifdef CONFIG_PERF_EVENTS + call->class->perf_probe = perf_event_raw_event_synth; +#endif call->data = event; call->tp = event->tp; --2.53.0
Re: [for-next][PATCH 10/15] tracing: Allow perf to read synthetic events
Quoted 11 lines · On Fri, 22 May 2026 08:19:36 -0700 Ian Rogers <[email protected]> wrote:
Quoted 7 lines · Steven Rostedt
From: Steven Rostedt <[email protected]>
Currently, perf can not enable synthetic events. When it does, it either causes a warning in the kernel or errors with "no such device".
Add the necessary code to allow perf to also attach to synthetic events.
Thanks so much for doing this work! I hoped to spend some time testing it, but there's never enough time. For the synthetic event I was
I totally understand not having time. Heck, I'm currently unemployed and I'm still having a hard time finding time!
Quoted 1 line
wondering what values end up in the perf sample like 'period'? I can
You mean to poll on the event?
Quoted 4 lines
imagine this being the case and that, if you are doing something like a futex wait duration, having to interpret the raw data rather than just getting aggregation for free in
perf reportvia the period. That's not wrong but I was just curious.
I guess I'm not quite sure what you mean by "the period". But then again, I don't use perf that much.
-- Steve
Re: [for-next][PATCH 10/15] tracing: Allow perf to read synthetic events
Hello,
Quoted 10 lines · Steven Rostedt
Quoted 7 lines · On Fri, 22 May 2026 08:19:36 -0700 Ian Rogers <[email protected]> wrote:
Quoted 6 lines · Steven Rostedt
From: Steven Rostedt <[email protected]>
Currently, perf can not enable synthetic events. When it does, it either causes a warning in the kernel or errors with "no such device".
Quoted 7 lines
Quoted 4 lines
Quoted 1 line
Add the necessary code to allow perf to also attach to synthetic events.
Thanks so much for doing this work! I hoped to spend some time testing it, but there's never enough time. For the synthetic event I was
I totally understand not having time. Heck, I'm currently unemployed and I'm still having a hard time finding time!
:)
Quoted 5 lines
Quoted 2 lines
wondering what values end up in the perf sample like 'period'? I can
You mean to poll on the event?
Quoted 7 lines
Quoted 4 lines
imagine this being the case and that, if you are doing something like a futex wait duration, having to interpret the raw data rather than just getting aggregation for free in
perf reportvia the period. That's not wrong but I was just curious.I guess I'm not quite sure what you mean by "the period". But then again, I don't use perf that much.
Oh, it's about the value of the event.
IIUC, the period of any tracepoints is the number of times it hits. Using a field of tracepoint instead needs interpretation of the event.
Thanks,
Namhyung
PATCH 11/15 tracing/branch: Use pr_warn() instead of printk(KERN_WARNING)
In reply to Steven RostedtFrom: Yu Peng <[email protected]>
Use pr_warn() instead of printk(KERN_WARNING ...) for the branch tracer warning messages.
Keep the message text unchanged. The change only removes the open-coded log level from these warnings.
--- kernel/trace/trace_branch.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
kernel/trace/trace_branch.c +3 -6
@@ -181,8 +181,7 @@ __init static int init_branch_tracer(void) ret =register_trace_event (&trace_branch_event);if (!ret) { -printk (KERN_WARNING "Warning: could not register " -"branch events\n" ); +pr_warn ("Warning: could not register branch events\n" );return 1 ; }return register_tracer (&branch_trace);
@@ -374,8 +373,7 @@ __init static int init_annotated_branch_stats(void) ret =register_stat_tracer (&annotated_branch_stats);if (ret) { -printk (KERN_WARNING "Warning: could not register " -"annotated branches stats\n" ); +pr_warn ("Warning: could not register annotated branches stats\n" );return ret; }return 0 ;
@@ -439,8 +437,7 @@ __init static int all_annotated_branch_stats(void) ret =register_stat_tracer (&all_branch_stats);if (ret) { -printk (KERN_WARNING "Warning: could not register " -"all branches stats\n" ); +pr_warn ("Warning: could not register all branches stats\n" );return ret; }return 0 ;
Signature · 1 line
2.53.0
PATCH 12/15 tracing: Use krealloc_array() for trace option array growth
In reply to Steven RostedtFrom: Yu Peng <[email protected]>
Use krealloc_array() when growing tr->topts instead of open-coding the size calculation in krealloc().
This makes the resize path use the helper intended for array allocations and avoids manual multiplication of the element count and element size.
--- kernel/trace/trace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/trace/trace.c +2 -2
@@ -7928,8 +7928,8 @@ create_trace_option_files(struct trace_array *tr, struct tracer *tracer,if (!topts)return 0 ; - tr_topts =krealloc (tr->topts,sizeof (*tr->topts) * (tr->nr_topts +1 ), -GFP_KERNEL ); + tr_topts =krealloc_array (tr->topts, tr->nr_topts +1 ,sizeof (*tr->topts), +GFP_KERNEL );if (!tr_topts) {kfree (topts);return -ENOMEM ;
Signature · 1 line
2.53.0
PATCH 13/15 tracing: Fix README path for synthetic_events
In reply to Steven RostedtFrom: Ao Sun <[email protected]>
The events/ prefix should be removed, since synthetic_events is now directly under the tracing root directory.
--- kernel/trace/trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/trace/trace.c +1 -1
@@ -4474,7 +4474,7 @@ static const char readme_msg[] = "\t snapshot() - snapshot the trace buffer\n\n"#endif #ifdef CONFIG_SYNTH_EVENTS -" events/synthetic_events\t- Create/append/remove/show synthetic events\n" +" synthetic_events\t- Create/append/remove/show synthetic events\n" "\t Write into this file to define/undefine new synthetic events.\n" "\t example: echo 'myevent u64 lat; char name[]; long[] stack' >> synthetic_events\n"#endif
Signature · 1 line
2.53.0
PATCH 14/15 tracing: Simplify pages allocation for tracing_map logic
In reply to Steven RostedtFrom: Rosen Penev <[email protected]>
Change to a flexible array member to allocate together with the array struct.
Simplifies code slightly by removing no longer correct null checks for pages and removing kfrees.
--- kernel/trace/tracing_map.c | 30 +++++++++++------------------- kernel/trace/tracing_map.h | 2 +- 2 files changed, 12 insertions(+), 20 deletions(-)
kernel/trace/tracing_map.c +11 -19
@@ -288,9 +288,6 @@ static void tracing_map_array_clear(struct tracing_map_array *a) {unsigned int i; -if (!a->pages) -return ; -for (i =0 ; i < a->n_pages; i++)memset (a->pages[i],0 ,PAGE_SIZE ); }
@@ -302,9 +299,6 @@ static void tracing_map_array_free(struct tracing_map_array *a)if (!a)return ; -if (!a->pages) - goto free; -for (i =0 ; i < a->n_pages; i++) {if (!a->pages[i])break ;
@@ -312,9 +306,6 @@ static void tracing_map_array_free(struct tracing_map_array *a)free_page ((unsigned long )a->pages[i]); } -kfree (a->pages); - - free:kfree (a); }
@@ -322,24 +313,25 @@ static struct tracing_map_array *tracing_map_array_alloc(unsigned int n_elts, unsigned int entry_size) {struct tracing_map_array *a; +unsigned int entry_size_shift; +unsigned int entries_per_page; +unsigned int n_pages;unsigned int i; - a =kzalloc_obj (*a); + entry_size_shift =fls (roundup_pow_of_two (entry_size) -1 ); + entries_per_page =PAGE_SIZE / (1 << entry_size_shift); + n_pages =max (1 , n_elts / entries_per_page); + + a =kzalloc_flex (*a, pages, n_pages);if (!a)return NULL ; - a->entry_size_shift =fls (roundup_pow_of_two (entry_size) -1 ); - a->entries_per_page =PAGE_SIZE / (1 << a->entry_size_shift); - a->n_pages = n_elts / a->entries_per_page; -if (!a->n_pages) - a->n_pages =1 ; + a->entry_size_shift = entry_size_shift; + a->entries_per_page = entries_per_page; + a->n_pages = n_pages; a->entry_shift =fls (a->entries_per_page) -1 ; a->entry_mask = (1 << a->entry_shift) -1 ; - a->pages =kcalloc (a->n_pages,sizeof (void *),GFP_KERNEL ); -if (!a->pages) - goto free; -for (i =0 ; i < a->n_pages; i++) { a->pages[i] = (void *)get_zeroed_page (GFP_KERNEL );if (!a->pages[i])
kernel/trace/tracing_map.h +1 -1
@@ -167,7 +167,7 @@ struct tracing_map_array {unsigned int entry_shift;unsigned int entry_mask;unsigned int n_pages; -void **pages; + void *pages[] __counted_by(n_pages); };#define TRACING_MAP_ARRAY_ELT (array, idx) \
Signature · 1 line
2.53.0
PATCH 15/15 tracing: Move trace_iterator_increment() into trace_find_next_entry_inc()
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
trace_iterator_increment() is only called from trace_find_next_entry_inc(). It's a small enough function that really doesn't need to be separated.
Move the code from trace_iterator_increment() into trace_find_next_entry_inc() and remove trace_iterator_increment().
--- kernel/trace/trace.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-)
kernel/trace/trace.c +8 -11
@@ -2338,15 +2338,6 @@ void trace_last_func_repeats(struct trace_array *tr,__buffer_unlock_commit (buffer, event); } -static void trace_iterator_increment (struct trace_iterator *iter) -{ -struct ring_buffer_iter *buf_iter =trace_buffer_iter (iter, iter->cpu); - - iter->idx++; -if (buf_iter) -ring_buffer_iter_advance (buf_iter); -} -static struct trace_entry *peek_next_entry (struct trace_iterator *iter,int cpu,u64 *ts,unsigned long *lost_events)
@@ -2676,11 +2667,17 @@ struct trace_entry *trace_find_next_entry(struct trace_iterator *iter,/* Find the next real entry, and increment the iterator to the next entry */ void *trace_find_next_entry_inc (struct trace_iterator *iter) { +struct ring_buffer_iter *buf_iter; + iter->ent =__find_next_entry (iter, &iter->cpu, &iter->lost_events, &iter->ts); -if (iter->ent) -trace_iterator_increment (iter); +if (iter->ent) { + iter->idx++; + buf_iter =trace_buffer_iter (iter, iter->cpu); +if (buf_iter) +ring_buffer_iter_advance (buf_iter); + }return iter->ent ? iter :NULL ; }
Signature · 1 line
2.53.0