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>
This commit is contained in:
parent
9b7bdf6f6e
commit
ef2bd81d0c
@ -1186,6 +1186,18 @@ Here are the available options:
|
||||
trace_printk
|
||||
Can disable trace_printk() from writing into the buffer.
|
||||
|
||||
trace_printk_dest
|
||||
Set to have trace_printk() and similar internal tracing functions
|
||||
write into this instance. Note, only one trace instance can have
|
||||
this set. By setting this flag, it clears the trace_printk_dest flag
|
||||
of the instance that had it set previously. By default, the top
|
||||
level trace has this set, and will get it set again if another
|
||||
instance has it set then clears it.
|
||||
|
||||
This flag cannot be cleared by the top level instance, as it is the
|
||||
default instance. The only way the top level instance has this flag
|
||||
cleared, is by it being set in another instance.
|
||||
|
||||
annotate
|
||||
It is sometimes confusing when the CPU buffers are full
|
||||
and one CPU buffer had a lot of events recently, thus
|
||||
|
@ -482,7 +482,7 @@ EXPORT_SYMBOL_GPL(unregister_ftrace_export);
|
||||
TRACE_ITER_ANNOTATE | TRACE_ITER_CONTEXT_INFO | \
|
||||
TRACE_ITER_RECORD_CMD | TRACE_ITER_OVERWRITE | \
|
||||
TRACE_ITER_IRQ_INFO | TRACE_ITER_MARKERS | \
|
||||
TRACE_ITER_HASH_PTR)
|
||||
TRACE_ITER_HASH_PTR | TRACE_ITER_TRACE_PRINTK)
|
||||
|
||||
/* trace_options that are only supported by global_trace */
|
||||
#define TOP_LEVEL_TRACE_FLAGS (TRACE_ITER_PRINTK | \
|
||||
@ -490,7 +490,7 @@ EXPORT_SYMBOL_GPL(unregister_ftrace_export);
|
||||
|
||||
/* trace_flags that are default zero for instances */
|
||||
#define ZEROED_TRACE_FLAGS \
|
||||
(TRACE_ITER_EVENT_FORK | TRACE_ITER_FUNC_FORK)
|
||||
(TRACE_ITER_EVENT_FORK | TRACE_ITER_FUNC_FORK | TRACE_ITER_TRACE_PRINTK)
|
||||
|
||||
/*
|
||||
* 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)
|
||||
return !(tr->flags & TRACE_ARRAY_FL_BOOT);
|
||||
}
|
||||
|
||||
static void update_printk_trace(struct trace_array *tr)
|
||||
{
|
||||
if (printk_trace == tr)
|
||||
return;
|
||||
|
||||
printk_trace->trace_flags &= ~TRACE_ITER_TRACE_PRINTK;
|
||||
printk_trace = tr;
|
||||
tr->trace_flags |= TRACE_ITER_TRACE_PRINTK;
|
||||
}
|
||||
|
||||
void trace_set_ring_buffer_expanded(struct trace_array *tr)
|
||||
{
|
||||
if (!tr)
|
||||
@ -5300,7 +5310,8 @@ int trace_keep_overwrite(struct tracer *tracer, u32 mask, int set)
|
||||
int set_tracer_flag(struct trace_array *tr, unsigned int mask, int enabled)
|
||||
{
|
||||
if ((mask == TRACE_ITER_RECORD_TGID) ||
|
||||
(mask == TRACE_ITER_RECORD_CMD))
|
||||
(mask == TRACE_ITER_RECORD_CMD) ||
|
||||
(mask == TRACE_ITER_TRACE_PRINTK))
|
||||
lockdep_assert_held(&event_mutex);
|
||||
|
||||
/* do nothing if flag is already set */
|
||||
@ -5312,6 +5323,25 @@ int set_tracer_flag(struct trace_array *tr, unsigned int mask, int enabled)
|
||||
if (tr->current_trace->flag_changed(tr, mask, !!enabled))
|
||||
return -EINVAL;
|
||||
|
||||
if (mask == TRACE_ITER_TRACE_PRINTK) {
|
||||
if (enabled) {
|
||||
update_printk_trace(tr);
|
||||
} else {
|
||||
/*
|
||||
* The global_trace cannot clear this.
|
||||
* It's flag only gets cleared if another instance sets it.
|
||||
*/
|
||||
if (printk_trace == &global_trace)
|
||||
return -EINVAL;
|
||||
/*
|
||||
* An instance must always have it set.
|
||||
* by default, that's the global_trace instane.
|
||||
*/
|
||||
if (printk_trace == tr)
|
||||
update_printk_trace(&global_trace);
|
||||
}
|
||||
}
|
||||
|
||||
if (enabled)
|
||||
tr->trace_flags |= mask;
|
||||
else
|
||||
@ -9687,7 +9717,7 @@ static int __remove_instance(struct trace_array *tr)
|
||||
}
|
||||
|
||||
if (printk_trace == tr)
|
||||
printk_trace = &global_trace;
|
||||
update_printk_trace(&global_trace);
|
||||
|
||||
tracing_set_nop(tr);
|
||||
clear_ftrace_function_probes(tr);
|
||||
@ -10578,7 +10608,7 @@ __init static void enable_instances(void)
|
||||
tracer_tracing_off(tr);
|
||||
|
||||
if (traceprintk)
|
||||
printk_trace = tr;
|
||||
update_printk_trace(tr);
|
||||
|
||||
/*
|
||||
* If start is set, then this is a mapped buffer, and
|
||||
|
@ -1321,6 +1321,7 @@ extern int trace_get_user(struct trace_parser *parser, const char __user *ubuf,
|
||||
C(IRQ_INFO, "irq-info"), \
|
||||
C(MARKERS, "markers"), \
|
||||
C(EVENT_FORK, "event-fork"), \
|
||||
C(TRACE_PRINTK, "trace_printk_dest"), \
|
||||
C(PAUSE_ON_TRACE, "pause-on-trace"), \
|
||||
C(HASH_PTR, "hash-ptr"), /* Print hashed pointer */ \
|
||||
FUNCTION_FLAGS \
|
||||
|
Loading…
Reference in New Issue
Block a user