Skip to content

Commit ef2bd81

Browse files
committed
tracing: Add option to set an instance to be the trace_printk destination
Add a option "trace_printk_dest" that will make the tracing instance the location that trace_printk() will go to. This is useful if the trace_printk or one of the top level tracers is too noisy and there's a need to separate the two. Then an instance can be created, the trace_printk can be set to go there instead, where it will not be lost in the noise of the top level tracer. Note, only one instance can be the destination of trace_printk at a time. If an instance sets this flag, the instance that had it set will have it cleared. There is always one instance that has this set. By default, that is the top instance. This flag cannot be cleared from the top instance. Doing so will result in an -EINVAL. The only way this flag can be cleared from the top instance is by another instance setting it. Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Vincent Donnefort <vdonnefort@google.com> Cc: Joel Fernandes <joel@joelfernandes.org> Cc: Ingo Molnar <mingo@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Vineeth Pillai <vineeth@bitbyteword.org> Cc: Beau Belgrave <beaub@linux.microsoft.com> Cc: Alexander Graf <graf@amazon.com> Cc: Baoquan He <bhe@redhat.com> Cc: Borislav Petkov <bp@alien8.de> Cc: "Paul E. McKenney" <paulmck@kernel.org> Cc: David Howells <dhowells@redhat.com> Cc: Mike Rapoport <rppt@kernel.org> Cc: Dave Hansen <dave.hansen@linux.intel.com> Cc: Tony Luck <tony.luck@intel.com> Cc: Guenter Roeck <linux@roeck-us.net> Cc: Ross Zwisler <zwisler@google.com> Cc: Kees Cook <keescook@chromium.org> Cc: Alexander Aring <aahringo@redhat.com> Cc: "Luis Claudio R. Goncalves" <lgoncalv@redhat.com> Cc: Tomas Glozar <tglozar@redhat.com> Cc: John Kacur <jkacur@redhat.com> Cc: Clark Williams <williams@redhat.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: "Jonathan Corbet" <corbet@lwn.net> Link: https://lore.kernel.org/20240823014019.545459018@goodmis.org Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
1 parent 9b7bdf6 commit ef2bd81

3 files changed

Lines changed: 48 additions & 5 deletions

File tree

Documentation/trace/ftrace.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,6 +1186,18 @@ Here are the available options:
11861186
trace_printk
11871187
Can disable trace_printk() from writing into the buffer.
11881188

1189+
trace_printk_dest
1190+
Set to have trace_printk() and similar internal tracing functions
1191+
write into this instance. Note, only one trace instance can have
1192+
this set. By setting this flag, it clears the trace_printk_dest flag
1193+
of the instance that had it set previously. By default, the top
1194+
level trace has this set, and will get it set again if another
1195+
instance has it set then clears it.
1196+
1197+
This flag cannot be cleared by the top level instance, as it is the
1198+
default instance. The only way the top level instance has this flag
1199+
cleared, is by it being set in another instance.
1200+
11891201
annotate
11901202
It is sometimes confusing when the CPU buffers are full
11911203
and one CPU buffer had a lot of events recently, thus

kernel/trace/trace.c

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -482,15 +482,15 @@ EXPORT_SYMBOL_GPL(unregister_ftrace_export);
482482
TRACE_ITER_ANNOTATE | TRACE_ITER_CONTEXT_INFO | \
483483
TRACE_ITER_RECORD_CMD | TRACE_ITER_OVERWRITE | \
484484
TRACE_ITER_IRQ_INFO | TRACE_ITER_MARKERS | \
485-
TRACE_ITER_HASH_PTR)
485+
TRACE_ITER_HASH_PTR | TRACE_ITER_TRACE_PRINTK)
486486

487487
/* trace_options that are only supported by global_trace */
488488
#define TOP_LEVEL_TRACE_FLAGS (TRACE_ITER_PRINTK | \
489489
TRACE_ITER_PRINTK_MSGONLY | TRACE_ITER_RECORD_CMD)
490490

491491
/* trace_flags that are default zero for instances */
492492
#define ZEROED_TRACE_FLAGS \
493-
(TRACE_ITER_EVENT_FORK | TRACE_ITER_FUNC_FORK)
493+
(TRACE_ITER_EVENT_FORK | TRACE_ITER_FUNC_FORK | TRACE_ITER_TRACE_PRINTK)
494494

495495
/*
496496
* The global_trace is the descriptor that holds the top-level tracing
@@ -513,6 +513,16 @@ static __always_inline bool printk_binsafe(struct trace_array *tr)
513513
return !(tr->flags & TRACE_ARRAY_FL_BOOT);
514514
}
515515

516+
static void update_printk_trace(struct trace_array *tr)
517+
{
518+
if (printk_trace == tr)
519+
return;
520+
521+
printk_trace->trace_flags &= ~TRACE_ITER_TRACE_PRINTK;
522+
printk_trace = tr;
523+
tr->trace_flags |= TRACE_ITER_TRACE_PRINTK;
524+
}
525+
516526
void trace_set_ring_buffer_expanded(struct trace_array *tr)
517527
{
518528
if (!tr)
@@ -5300,7 +5310,8 @@ int trace_keep_overwrite(struct tracer *tracer, u32 mask, int set)
53005310
int set_tracer_flag(struct trace_array *tr, unsigned int mask, int enabled)
53015311
{
53025312
if ((mask == TRACE_ITER_RECORD_TGID) ||
5303-
(mask == TRACE_ITER_RECORD_CMD))
5313+
(mask == TRACE_ITER_RECORD_CMD) ||
5314+
(mask == TRACE_ITER_TRACE_PRINTK))
53045315
lockdep_assert_held(&event_mutex);
53055316

53065317
/* do nothing if flag is already set */
@@ -5312,6 +5323,25 @@ int set_tracer_flag(struct trace_array *tr, unsigned int mask, int enabled)
53125323
if (tr->current_trace->flag_changed(tr, mask, !!enabled))
53135324
return -EINVAL;
53145325

5326+
if (mask == TRACE_ITER_TRACE_PRINTK) {
5327+
if (enabled) {
5328+
update_printk_trace(tr);
5329+
} else {
5330+
/*
5331+
* The global_trace cannot clear this.
5332+
* It's flag only gets cleared if another instance sets it.
5333+
*/
5334+
if (printk_trace == &global_trace)
5335+
return -EINVAL;
5336+
/*
5337+
* An instance must always have it set.
5338+
* by default, that's the global_trace instane.
5339+
*/
5340+
if (printk_trace == tr)
5341+
update_printk_trace(&global_trace);
5342+
}
5343+
}
5344+
53155345
if (enabled)
53165346
tr->trace_flags |= mask;
53175347
else
@@ -9687,7 +9717,7 @@ static int __remove_instance(struct trace_array *tr)
96879717
}
96889718

96899719
if (printk_trace == tr)
9690-
printk_trace = &global_trace;
9720+
update_printk_trace(&global_trace);
96919721

96929722
tracing_set_nop(tr);
96939723
clear_ftrace_function_probes(tr);
@@ -10578,7 +10608,7 @@ __init static void enable_instances(void)
1057810608
tracer_tracing_off(tr);
1057910609

1058010610
if (traceprintk)
10581-
printk_trace = tr;
10611+
update_printk_trace(tr);
1058210612

1058310613
/*
1058410614
* If start is set, then this is a mapped buffer, and

kernel/trace/trace.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1321,6 +1321,7 @@ extern int trace_get_user(struct trace_parser *parser, const char __user *ubuf,
13211321
C(IRQ_INFO, "irq-info"), \
13221322
C(MARKERS, "markers"), \
13231323
C(EVENT_FORK, "event-fork"), \
1324+
C(TRACE_PRINTK, "trace_printk_dest"), \
13241325
C(PAUSE_ON_TRACE, "pause-on-trace"), \
13251326
C(HASH_PTR, "hash-ptr"), /* Print hashed pointer */ \
13261327
FUNCTION_FLAGS \

0 commit comments

Comments
 (0)