tracing: Add snapshot at end of kernel boot up
authorSteven Rostedt (Google) <rostedt@goodmis.org>
Fri, 11 Mar 2022 02:37:09 +0000 (21:37 -0500)
committerSteven Rostedt (Google) <rostedt@goodmis.org>
Fri, 11 Mar 2022 16:49:24 +0000 (11:49 -0500)
Add ftrace_boot_snapshot kernel parameter that will take a snapshot at the
end of boot up just before switching over to user space (it happens during
the kernel freeing of init memory).

This is useful when there's interesting data that can be collected from
kernel start up, but gets overridden by user space start up code. With
this option, the ring buffer content from the boot up traces gets saved in
the snapshot at the end of boot up. This trace can be read from:

 /sys/kernel/tracing/snapshot

Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Documentation/admin-guide/kernel-parameters.txt
include/linux/ftrace.h
kernel/trace/ftrace.c
kernel/trace/trace.c

index f5a27f067db9ed97da621036f111f881d3aa3561..f6b7ee64ace8d2cf5b201ec08d166e5b9169aa88 100644 (file)
                        as early as possible in order to facilitate early
                        boot debugging.
 
+       ftrace_boot_snapshot
+                       [FTRACE] On boot up, a snapshot will be taken of the
+                       ftrace ring buffer that can be read at:
+                       /sys/kernel/tracing/snapshot.
+                       This is useful if you need tracing information from kernel
+                       boot up that is likely to be overridden by user space
+                       start up functionality.
+
        ftrace_dump_on_oops[=orig_cpu]
                        [FTRACE] will dump the trace buffers on oops.
                        If no parameter is passed, ftrace will dump
index 9999e29187deadf111a89dff81af37301eb1d492..37b619185ec9585ac9fc54970d436c7e3af93a0c 100644 (file)
 #define ARCH_SUPPORTS_FTRACE_OPS 0
 #endif
 
+#ifdef CONFIG_TRACING
+extern void ftrace_boot_snapshot(void);
+#else
+static inline void ftrace_boot_snapshot(void) { }
+#endif
+
 #ifdef CONFIG_FUNCTION_TRACER
 struct ftrace_ops;
 struct ftrace_regs;
@@ -215,7 +221,10 @@ struct ftrace_ops_hash {
 void ftrace_free_init_mem(void);
 void ftrace_free_mem(struct module *mod, void *start, void *end);
 #else
-static inline void ftrace_free_init_mem(void) { }
+static inline void ftrace_free_init_mem(void)
+{
+       ftrace_boot_snapshot();
+}
 static inline void ftrace_free_mem(struct module *mod, void *start, void *end) { }
 #endif
 
index f9feb197b2daaf348622665924795a3ae88e4fda..4e29bd1cf151adbf5ea83ba163ef9fafeb45519d 100644 (file)
@@ -7096,6 +7096,8 @@ void __init ftrace_free_init_mem(void)
        void *start = (void *)(&__init_begin);
        void *end = (void *)(&__init_end);
 
+       ftrace_boot_snapshot();
+
        ftrace_free_mem(NULL, start, end);
 }
 
index 7c85ce9ffdc3908cffaf0b35b1484ea908361f54..eaf7d30ca6f10553339df58bb78b31c975e50a04 100644 (file)
@@ -185,6 +185,7 @@ static char bootup_tracer_buf[MAX_TRACER_SIZE] __initdata;
 static char *default_bootup_tracer;
 
 static bool allocate_snapshot;
+static bool snapshot_at_boot;
 
 static int __init set_cmdline_ftrace(char *str)
 {
@@ -230,6 +231,15 @@ static int __init boot_alloc_snapshot(char *str)
 __setup("alloc_snapshot", boot_alloc_snapshot);
 
 
+static int __init boot_snapshot(char *str)
+{
+       snapshot_at_boot = true;
+       boot_alloc_snapshot(str);
+       return 1;
+}
+__setup("ftrace_boot_snapshot", boot_snapshot);
+
+
 static char trace_boot_options_buf[MAX_TRACER_SIZE] __initdata;
 
 static int __init set_trace_boot_options(char *str)
@@ -10149,6 +10159,14 @@ out:
        return ret;
 }
 
+void __init ftrace_boot_snapshot(void)
+{
+       if (snapshot_at_boot) {
+               tracing_snapshot();
+               internal_trace_puts("** Boot snapshot taken **\n");
+       }
+}
+
 void __init early_trace_init(void)
 {
        if (tracepoint_printk) {