Skip to content

Commit ddb8ea9

Browse files
committed
tracing: Allow trace_printk() to go to other instance buffers
Currently, trace_printk() just goes to the top level ring buffer. But there may be times that it should go to one of the instances created by the kernel command line. Add a new trace_instance flag: traceprintk (also can use "printk" or "trace_printk" as people tend to forget the actual flag name). trace_instance=foo^traceprintk Will assign the trace_printk to this buffer at boot up. 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 b6fc31b commit ddb8ea9

File tree

2 files changed

+45
-15
lines changed

2 files changed

+45
-15
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6744,11 +6744,17 @@
67446744
event, and all events under the "initcall" system.
67456745

67466746
Flags can be added to the instance to modify its behavior when it is
6747-
created. The flags are separated by '^'. Currently there's only one flag
6748-
defined, and that's "traceoff", to have the tracing instance tracing
6749-
disabled after it is created.
6747+
created. The flags are separated by '^'.
67506748

6751-
trace_instance=foo^traceoff,sched,irq
6749+
The available flags are:
6750+
6751+
traceoff - Have the tracing instance tracing disabled after it is created.
6752+
traceprintk - Have trace_printk() write into this trace instance
6753+
(note, "printk" and "trace_printk" can also be used)
6754+
Currently, traceprintk flag cannot be used for memory
6755+
mapped ring buffers as described below.
6756+
6757+
trace_instance=foo^traceoff^traceprintk,sched,irq
67526758

67536759
The flags must come before the defined events.
67546760

kernel/trace/trace.c

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,8 @@ static struct trace_array global_trace = {
500500
.trace_flags = TRACE_DEFAULT_FLAGS,
501501
};
502502

503+
static struct trace_array *printk_trace = &global_trace;
504+
503505
void trace_set_ring_buffer_expanded(struct trace_array *tr)
504506
{
505507
if (!tr)
@@ -1117,7 +1119,7 @@ EXPORT_SYMBOL_GPL(__trace_array_puts);
11171119
*/
11181120
int __trace_puts(unsigned long ip, const char *str, int size)
11191121
{
1120-
return __trace_array_puts(&global_trace, ip, str, size);
1122+
return __trace_array_puts(printk_trace, ip, str, size);
11211123
}
11221124
EXPORT_SYMBOL_GPL(__trace_puts);
11231125

@@ -1128,21 +1130,22 @@ EXPORT_SYMBOL_GPL(__trace_puts);
11281130
*/
11291131
int __trace_bputs(unsigned long ip, const char *str)
11301132
{
1133+
struct trace_array *tr = printk_trace;
11311134
struct ring_buffer_event *event;
11321135
struct trace_buffer *buffer;
11331136
struct bputs_entry *entry;
11341137
unsigned int trace_ctx;
11351138
int size = sizeof(struct bputs_entry);
11361139
int ret = 0;
11371140

1138-
if (!(global_trace.trace_flags & TRACE_ITER_PRINTK))
1141+
if (!(tr->trace_flags & TRACE_ITER_PRINTK))
11391142
return 0;
11401143

11411144
if (unlikely(tracing_selftest_running || tracing_disabled))
11421145
return 0;
11431146

11441147
trace_ctx = tracing_gen_ctx();
1145-
buffer = global_trace.array_buffer.buffer;
1148+
buffer = tr->array_buffer.buffer;
11461149

11471150
ring_buffer_nest_start(buffer);
11481151
event = __trace_buffer_lock_reserve(buffer, TRACE_BPUTS, size,
@@ -1155,7 +1158,7 @@ int __trace_bputs(unsigned long ip, const char *str)
11551158
entry->str = str;
11561159

11571160
__buffer_unlock_commit(buffer, event);
1158-
ftrace_trace_stack(&global_trace, buffer, trace_ctx, 4, NULL);
1161+
ftrace_trace_stack(tr, buffer, trace_ctx, 4, NULL);
11591162

11601163
ret = 1;
11611164
out:
@@ -3025,7 +3028,7 @@ void trace_dump_stack(int skip)
30253028
/* Skip 1 to skip this function. */
30263029
skip++;
30273030
#endif
3028-
__ftrace_trace_stack(global_trace.array_buffer.buffer,
3031+
__ftrace_trace_stack(printk_trace->array_buffer.buffer,
30293032
tracing_gen_ctx(), skip, NULL);
30303033
}
30313034
EXPORT_SYMBOL_GPL(trace_dump_stack);
@@ -3244,7 +3247,7 @@ int trace_vbprintk(unsigned long ip, const char *fmt, va_list args)
32443247
struct trace_event_call *call = &event_bprint;
32453248
struct ring_buffer_event *event;
32463249
struct trace_buffer *buffer;
3247-
struct trace_array *tr = &global_trace;
3250+
struct trace_array *tr = printk_trace;
32483251
struct bprint_entry *entry;
32493252
unsigned int trace_ctx;
32503253
char *tbuffer;
@@ -3342,7 +3345,7 @@ __trace_array_vprintk(struct trace_buffer *buffer,
33423345
memcpy(&entry->buf, tbuffer, len + 1);
33433346
if (!call_filter_check_discard(call, entry, buffer, event)) {
33443347
__buffer_unlock_commit(buffer, event);
3345-
ftrace_trace_stack(&global_trace, buffer, trace_ctx, 6, NULL);
3348+
ftrace_trace_stack(printk_trace, buffer, trace_ctx, 6, NULL);
33463349
}
33473350

33483351
out:
@@ -3438,7 +3441,7 @@ int trace_array_printk_buf(struct trace_buffer *buffer,
34383441
int ret;
34393442
va_list ap;
34403443

3441-
if (!(global_trace.trace_flags & TRACE_ITER_PRINTK))
3444+
if (!(printk_trace->trace_flags & TRACE_ITER_PRINTK))
34423445
return 0;
34433446

34443447
va_start(ap, fmt);
@@ -3450,7 +3453,7 @@ int trace_array_printk_buf(struct trace_buffer *buffer,
34503453
__printf(2, 0)
34513454
int trace_vprintk(unsigned long ip, const char *fmt, va_list args)
34523455
{
3453-
return trace_array_vprintk(&global_trace, ip, fmt, args);
3456+
return trace_array_vprintk(printk_trace, ip, fmt, args);
34543457
}
34553458
EXPORT_SYMBOL_GPL(trace_vprintk);
34563459

@@ -9666,6 +9669,9 @@ static int __remove_instance(struct trace_array *tr)
96669669
set_tracer_flag(tr, 1 << i, 0);
96679670
}
96689671

9672+
if (printk_trace == tr)
9673+
printk_trace = &global_trace;
9674+
96699675
tracing_set_nop(tr);
96709676
clear_ftrace_function_probes(tr);
96719677
event_trace_del_tracer(tr);
@@ -10468,6 +10474,7 @@ __init static void enable_instances(void)
1046810474
phys_addr_t start = 0;
1046910475
phys_addr_t size = 0;
1047010476
unsigned long addr = 0;
10477+
bool traceprintk = false;
1047110478
bool traceoff = false;
1047210479
char *flag_delim;
1047310480
char *addr_delim;
@@ -10489,11 +10496,16 @@ __init static void enable_instances(void)
1048910496
char *flag;
1049010497

1049110498
while ((flag = strsep(&flag_delim, "^"))) {
10492-
if (strcmp(flag, "traceoff") == 0)
10499+
if (strcmp(flag, "traceoff") == 0) {
1049310500
traceoff = true;
10494-
else
10501+
} else if ((strcmp(flag, "printk") == 0) ||
10502+
(strcmp(flag, "traceprintk") == 0) ||
10503+
(strcmp(flag, "trace_printk") == 0)) {
10504+
traceprintk = true;
10505+
} else {
1049510506
pr_info("Tracing: Invalid instance flag '%s' for %s\n",
1049610507
flag, name);
10508+
}
1049710509
}
1049810510
}
1049910511

@@ -10548,6 +10560,18 @@ __init static void enable_instances(void)
1054810560
if (traceoff)
1054910561
tracer_tracing_off(tr);
1055010562

10563+
if (traceprintk) {
10564+
/*
10565+
* The binary format of traceprintk can cause a crash if used
10566+
* by a buffer from another boot. Do not allow it for the
10567+
* memory mapped ring buffers.
10568+
*/
10569+
if (start)
10570+
pr_warn("Tracing: WARNING: memory mapped ring buffers cannot be used for trace_printk\n");
10571+
else
10572+
printk_trace = tr;
10573+
}
10574+
1055110575
/* Only allow non mapped buffers to be deleted */
1055210576
if (!start)
1055310577
trace_array_put(tr);

0 commit comments

Comments
 (0)