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 <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Mathieu Desnoyers <[email protected]> Cc: Andrew Morton <[email protected]> Cc: Vincent Donnefort <[email protected]> Cc: Joel Fernandes <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Vineeth Pillai <[email protected]> Cc: Beau Belgrave <[email protected]> Cc: Alexander Graf <[email protected]> Cc: Baoquan He <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: "Paul E. McKenney" <[email protected]> Cc: David Howells <[email protected]> Cc: Mike Rapoport <[email protected]> Cc: Dave Hansen <[email protected]> Cc: Tony Luck <[email protected]> Cc: Guenter Roeck <[email protected]> Cc: Ross Zwisler <[email protected]> Cc: Kees Cook <[email protected]> Cc: Alexander Aring <[email protected]> Cc: "Luis Claudio R. Goncalves" <[email protected]> Cc: Tomas Glozar <[email protected]> Cc: John Kacur <[email protected]> Cc: Clark Williams <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: "Jonathan Corbet" <[email protected]> Link: https://lore.kernel.org/[email protected] Signed-off-by: Steven Rostedt (Google) <[email protected]>
1 parent 9b7bdf6 commit ef2bd81

File tree

3 files changed

+48
-5
lines changed

3 files changed

+48
-5
lines changed

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)