Skip to content

Commit

Permalink
Merge tag 'trace-v6.15' of git://git.kernel.org/pub/scm/linux/kernel/…
Browse files Browse the repository at this point in the history
…git/trace/linux-trace

Pull tracing updates from Steven Rostedt:

 - Add option traceoff_after_boot

   In order to debug kernel boot, it sometimes is helpful to enable
   tracing via the kernel command line. Unfortunately, by the time the
   login prompt appears, the trace is overwritten by the init process
   and other user space start up applications.

   Adding a "traceoff_after_boot" will disable tracing when the kernel
   passes control to init which will allow developers to be able to see
   the traces that occurred during boot.

 - Clean up the mmflags macros that display the GFP flags in trace
   events

   The macros to print the GFP flags for trace events had a bit of
   duplication. The code was restructured to remove duplication and in
   the process it also adds some flags that were missed before.

 - Removed some dead code and scripts/draw_functrace.py

   draw_functrace.py hasn't worked in years and as nobody complained
   about it, remove it.

 - Constify struct event_trigger_ops

   The event_trigger_ops is just a structure that has function pointers
   that are assigned when the variables are created. These variables
   should all be constants.

 - Other minor clean ups and fixes

* tag 'trace-v6.15' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace:
  tracing: Replace strncpy with memcpy for fixed-length substring copy
  tracing: Fix synth event printk format for str fields
  tracing: Do not use PERF enums when perf is not defined
  tracing: Ensure module defining synth event cannot be unloaded while tracing
  tracing: fix return value in __ftrace_event_enable_disable for TRACE_REG_UNREGISTER
  tracing/osnoise: Fix possible recursive locking for cpus_read_lock()
  tracing: Align synth event print fmt
  tracing: gfp: vsprintf: Do not print "none" when using %pGg printf format
  tracepoint: Print the function symbol when tracepoint_debug is set
  tracing: Constify struct event_trigger_ops
  scripts/tracing: Remove scripts/tracing/draw_functrace.py
  tracing: Update MAINTAINERS file to include tracepoint.c
  tracing/user_events: Slightly simplify user_seq_show()
  tracing/user_events: Don't use %pK through printk
  tracing: gfp: Remove duplication of recording GFP flags
  tracing: Remove orphaned event_trace_printk
  ring-buffer: Fix typo in comment about header page pointer
  tracing: Add traceoff_after_boot option
  • Loading branch information
Linus Torvalds committed Mar 27, 2025
2 parents 88221ac + e0344f9 commit 744fab2
Show file tree
Hide file tree
Showing 16 changed files with 108 additions and 225 deletions.
9 changes: 9 additions & 0 deletions Documentation/admin-guide/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7289,6 +7289,15 @@
See also "Event triggers" in Documentation/trace/events.rst


traceoff_after_boot
[FTRACE] Sometimes tracing is used to debug issues
during the boot process. Since the trace buffer has a
limited amount of storage, it may be prudent to
disable tracing after the boot is finished, otherwise
the critical information may be overwritten. With this
option, the main tracing buffer will be turned off at
the end of the boot process.

traceoff_on_warning
[FTRACE] enable this option to disable tracing when a
warning is hit. This turns off "tracing_on". Tracing can
Expand Down
1 change: 1 addition & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -24233,6 +24233,7 @@ F: fs/tracefs/
F: include/linux/trace*.h
F: include/trace/
F: kernel/trace/
F: kernel/tracepoint.c
F: scripts/tracing/
F: tools/testing/selftests/ftrace/

Expand Down
18 changes: 0 additions & 18 deletions include/linux/trace_events.h
Original file line number Diff line number Diff line change
Expand Up @@ -859,24 +859,6 @@ int ftrace_set_clr_event(struct trace_array *tr, char *buf, int set);
int trace_set_clr_event(const char *system, const char *event, int set);
int trace_array_set_clr_event(struct trace_array *tr, const char *system,
const char *event, bool enable);
/*
* The double __builtin_constant_p is because gcc will give us an error
* if we try to allocate the static variable to fmt if it is not a
* constant. Even with the outer if statement optimizing out.
*/
#define event_trace_printk(ip, fmt, args...) \
do { \
__trace_printk_check_format(fmt, ##args); \
tracing_record_cmdline(current); \
if (__builtin_constant_p(fmt)) { \
static const char *trace_printk_fmt \
__section("__trace_printk_fmt") = \
__builtin_constant_p(fmt) ? fmt : NULL; \
\
__trace_bprintk(ip, trace_printk_fmt, ##args); \
} else \
__trace_printk(ip, fmt, ##args); \
} while (0)

#ifdef CONFIG_PERF_EVENTS
struct perf_event;
Expand Down
41 changes: 10 additions & 31 deletions include/trace/events/mmflags.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,13 @@ TRACE_DEFINE_ENUM(___GFP_LAST_BIT);

#define gfpflag_string(flag) {(__force unsigned long)flag, #flag}

/*
* For the values that match the bits, use the TRACE_GFP_FLAGS
* which will allow any updates to be included automatically.
*/
#undef TRACE_GFP_EM
#define TRACE_GFP_EM(a) gfpflag_string(__GFP_##a),

#define __def_gfpflag_names \
gfpflag_string(GFP_TRANSHUGE), \
gfpflag_string(GFP_TRANSHUGE_LIGHT), \
Expand All @@ -91,41 +98,13 @@ TRACE_DEFINE_ENUM(___GFP_LAST_BIT);
gfpflag_string(GFP_NOIO), \
gfpflag_string(GFP_NOWAIT), \
gfpflag_string(GFP_DMA), \
gfpflag_string(__GFP_HIGHMEM), \
gfpflag_string(GFP_DMA32), \
gfpflag_string(__GFP_HIGH), \
gfpflag_string(__GFP_IO), \
gfpflag_string(__GFP_FS), \
gfpflag_string(__GFP_NOWARN), \
gfpflag_string(__GFP_RETRY_MAYFAIL), \
gfpflag_string(__GFP_NOFAIL), \
gfpflag_string(__GFP_NORETRY), \
gfpflag_string(__GFP_COMP), \
gfpflag_string(__GFP_ZERO), \
gfpflag_string(__GFP_NOMEMALLOC), \
gfpflag_string(__GFP_MEMALLOC), \
gfpflag_string(__GFP_HARDWALL), \
gfpflag_string(__GFP_THISNODE), \
gfpflag_string(__GFP_RECLAIMABLE), \
gfpflag_string(__GFP_MOVABLE), \
gfpflag_string(__GFP_ACCOUNT), \
gfpflag_string(__GFP_WRITE), \
gfpflag_string(__GFP_RECLAIM), \
gfpflag_string(__GFP_DIRECT_RECLAIM), \
gfpflag_string(__GFP_KSWAPD_RECLAIM), \
gfpflag_string(__GFP_ZEROTAGS)

#ifdef CONFIG_KASAN_HW_TAGS
#define __def_gfpflag_names_kasan , \
gfpflag_string(__GFP_SKIP_ZERO), \
gfpflag_string(__GFP_SKIP_KASAN)
#else
#define __def_gfpflag_names_kasan
#endif
TRACE_GFP_FLAGS \
{ 0, NULL }

#define show_gfp_flags(flags) \
(flags) ? __print_flags(flags, "|", \
__def_gfpflag_names __def_gfpflag_names_kasan \
(flags) ? __print_flags(flags, "|", __def_gfpflag_names \
) : "none"

#ifdef CONFIG_MMU
Expand Down
2 changes: 1 addition & 1 deletion kernel/trace/ring_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -5318,7 +5318,7 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
* moving it. The page before the header page has the
* flag bit '1' set if it is pointing to the page we want.
* but if the writer is in the process of moving it
* than it will be '2' or already moved '0'.
* then it will be '2' or already moved '0'.
*/

ret = rb_head_page_replace(reader, cpu_buffer->reader_page);
Expand Down
11 changes: 11 additions & 0 deletions kernel/trace/trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ void __init disable_tracing_selftest(const char *reason)
static struct trace_iterator *tracepoint_print_iter;
int tracepoint_printk;
static bool tracepoint_printk_stop_on_boot __initdata;
static bool traceoff_after_boot __initdata;
static DEFINE_STATIC_KEY_FALSE(tracepoint_printk_key);

/* For tracers that don't implement custom flags */
Expand Down Expand Up @@ -330,6 +331,13 @@ static int __init set_tracepoint_printk_stop(char *str)
}
__setup("tp_printk_stop_on_boot", set_tracepoint_printk_stop);

static int __init set_traceoff_after_boot(char *str)
{
traceoff_after_boot = true;
return 1;
}
__setup("traceoff_after_boot", set_traceoff_after_boot);

unsigned long long ns2usecs(u64 nsec)
{
nsec += 500;
Expand Down Expand Up @@ -10709,6 +10717,9 @@ __init static int late_trace_init(void)
tracepoint_printk = 0;
}

if (traceoff_after_boot)
tracing_off();

tracing_set_default_clock();
clear_boot_tracer();
return 0;
Expand Down
4 changes: 2 additions & 2 deletions kernel/trace/trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -1717,7 +1717,7 @@ struct event_trigger_data {
unsigned long count;
int ref;
int flags;
struct event_trigger_ops *ops;
const struct event_trigger_ops *ops;
struct event_command *cmd_ops;
struct event_filter __rcu *filter;
char *filter_str;
Expand Down Expand Up @@ -1962,7 +1962,7 @@ struct event_command {
int (*set_filter)(char *filter_str,
struct event_trigger_data *data,
struct trace_event_file *file);
struct event_trigger_ops *(*get_trigger_ops)(char *cmd, char *param);
const struct event_trigger_ops *(*get_trigger_ops)(char *cmd, char *param);
};

/**
Expand Down
6 changes: 3 additions & 3 deletions kernel/trace/trace_eprobe.c
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ static void eprobe_trigger_func(struct event_trigger_data *data,
__eprobe_trace_func(edata, rec);
}

static struct event_trigger_ops eprobe_trigger_ops = {
static const struct event_trigger_ops eprobe_trigger_ops = {
.trigger = eprobe_trigger_func,
.print = eprobe_trigger_print,
.init = eprobe_trigger_init,
Expand Down Expand Up @@ -507,8 +507,8 @@ static void eprobe_trigger_unreg_func(char *glob,

}

static struct event_trigger_ops *eprobe_trigger_get_ops(char *cmd,
char *param)
static const struct event_trigger_ops *eprobe_trigger_get_ops(char *cmd,
char *param)
{
return &eprobe_trigger_ops;
}
Expand Down
4 changes: 3 additions & 1 deletion kernel/trace/trace_events.c
Original file line number Diff line number Diff line change
Expand Up @@ -790,7 +790,9 @@ static int __ftrace_event_enable_disable(struct trace_event_file *file,
clear_bit(EVENT_FILE_FL_RECORDED_TGID_BIT, &file->flags);
}

call->class->reg(call, TRACE_REG_UNREGISTER, file);
ret = call->class->reg(call, TRACE_REG_UNREGISTER, file);

WARN_ON_ONCE(ret);
}
/* If in SOFT_MODE, just set the SOFT_DISABLE_BIT, else clear it */
if (file->flags & EVENT_FILE_FL_SOFT_MODE)
Expand Down
20 changes: 10 additions & 10 deletions kernel/trace/trace_events_hist.c
Original file line number Diff line number Diff line change
Expand Up @@ -6203,7 +6203,7 @@ static void event_hist_trigger_free(struct event_trigger_data *data)
}
}

static struct event_trigger_ops event_hist_trigger_ops = {
static const struct event_trigger_ops event_hist_trigger_ops = {
.trigger = event_hist_trigger,
.print = event_hist_trigger_print,
.init = event_hist_trigger_init,
Expand Down Expand Up @@ -6235,15 +6235,15 @@ static void event_hist_trigger_named_free(struct event_trigger_data *data)
}
}

static struct event_trigger_ops event_hist_trigger_named_ops = {
static const struct event_trigger_ops event_hist_trigger_named_ops = {
.trigger = event_hist_trigger,
.print = event_hist_trigger_print,
.init = event_hist_trigger_named_init,
.free = event_hist_trigger_named_free,
};

static struct event_trigger_ops *event_hist_get_trigger_ops(char *cmd,
char *param)
static const struct event_trigger_ops *event_hist_get_trigger_ops(char *cmd,
char *param)
{
return &event_hist_trigger_ops;
}
Expand Down Expand Up @@ -6838,38 +6838,38 @@ hist_enable_count_trigger(struct event_trigger_data *data,
hist_enable_trigger(data, buffer, rec, event);
}

static struct event_trigger_ops hist_enable_trigger_ops = {
static const struct event_trigger_ops hist_enable_trigger_ops = {
.trigger = hist_enable_trigger,
.print = event_enable_trigger_print,
.init = event_trigger_init,
.free = event_enable_trigger_free,
};

static struct event_trigger_ops hist_enable_count_trigger_ops = {
static const struct event_trigger_ops hist_enable_count_trigger_ops = {
.trigger = hist_enable_count_trigger,
.print = event_enable_trigger_print,
.init = event_trigger_init,
.free = event_enable_trigger_free,
};

static struct event_trigger_ops hist_disable_trigger_ops = {
static const struct event_trigger_ops hist_disable_trigger_ops = {
.trigger = hist_enable_trigger,
.print = event_enable_trigger_print,
.init = event_trigger_init,
.free = event_enable_trigger_free,
};

static struct event_trigger_ops hist_disable_count_trigger_ops = {
static const struct event_trigger_ops hist_disable_count_trigger_ops = {
.trigger = hist_enable_count_trigger,
.print = event_enable_trigger_print,
.init = event_trigger_init,
.free = event_enable_trigger_free,
};

static struct event_trigger_ops *
static const struct event_trigger_ops *
hist_enable_get_trigger_ops(char *cmd, char *param)
{
struct event_trigger_ops *ops;
const struct event_trigger_ops *ops;
bool enable;

enable = (strcmp(cmd, ENABLE_HIST_STR) == 0);
Expand Down
40 changes: 36 additions & 4 deletions kernel/trace/trace_events_synth.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ static int synth_field_string_size(char *type)
if (len == 0)
return 0; /* variable-length string */

strncpy(buf, start, len);
memcpy(buf, start, len);
buf[len] = '\0';

err = kstrtouint(buf, 0, &size);
Expand Down Expand Up @@ -305,7 +305,7 @@ static const char *synth_field_fmt(char *type)
else if (strcmp(type, "gfp_t") == 0)
fmt = "%x";
else if (synth_field_is_string(type))
fmt = "%.*s";
fmt = "%s";
else if (synth_field_is_stack(type))
fmt = "%s";

Expand Down Expand Up @@ -612,7 +612,7 @@ static int __set_synth_event_print_fmt(struct synth_event *event,
fmt = synth_field_fmt(event->fields[i]->type);
pos += snprintf(buf + pos, LEN_OR_ZERO, "%s=%s%s",
event->fields[i]->name, fmt,
i == event->n_fields - 1 ? "" : ", ");
i == event->n_fields - 1 ? "" : " ");
}
pos += snprintf(buf + pos, LEN_OR_ZERO, "\"");

Expand Down Expand Up @@ -852,6 +852,38 @@ static struct trace_event_fields synth_event_fields_array[] = {
{}
};

static int synth_event_reg(struct trace_event_call *call,
enum trace_reg type, void *data)
{
struct synth_event *event = container_of(call, struct synth_event, call);

switch (type) {
#ifdef CONFIG_PERF_EVENTS
case TRACE_REG_PERF_REGISTER:
#endif
case TRACE_REG_REGISTER:
if (!try_module_get(event->mod))
return -EBUSY;
break;
default:
break;
}

int ret = trace_event_reg(call, type, data);

switch (type) {
#ifdef CONFIG_PERF_EVENTS
case TRACE_REG_PERF_UNREGISTER:
#endif
case TRACE_REG_UNREGISTER:
module_put(event->mod);
break;
default:
break;
}
return ret;
}

static int register_synth_event(struct synth_event *event)
{
struct trace_event_call *call = &event->call;
Expand Down Expand Up @@ -881,7 +913,7 @@ static int register_synth_event(struct synth_event *event)
goto out;
}
call->flags = TRACE_EVENT_FL_TRACEPOINT;
call->class->reg = trace_event_reg;
call->class->reg = synth_event_reg;
call->class->probe = trace_event_raw_event_synth;
call->data = event;
call->tp = event->tp;
Expand Down
Loading

0 comments on commit 744fab2

Please sign in to comment.