@@ -191,6 +191,9 @@ static bool snapshot_at_boot;
191191static char boot_instance_info [COMMAND_LINE_SIZE ] __initdata ;
192192static int boot_instance_index ;
193193
194+ static char boot_snapshot_info [COMMAND_LINE_SIZE ] __initdata ;
195+ static int boot_snapshot_index ;
196+
194197static int __init set_cmdline_ftrace (char * str )
195198{
196199 strlcpy (bootup_tracer_buf , str , MAX_TRACER_SIZE );
@@ -227,9 +230,22 @@ __setup("traceoff_on_warning", stop_trace_on_warning);
227230
228231static int __init boot_alloc_snapshot (char * str )
229232{
230- allocate_snapshot = true;
231- /* We also need the main ring buffer expanded */
232- ring_buffer_expanded = true;
233+ char * slot = boot_snapshot_info + boot_snapshot_index ;
234+ int left = sizeof (boot_snapshot_info ) - boot_snapshot_index ;
235+ int ret ;
236+
237+ if (str [0 ] == '=' ) {
238+ str ++ ;
239+ if (strlen (str ) >= left )
240+ return -1 ;
241+
242+ ret = snprintf (slot , left , "%s\t" , str );
243+ boot_snapshot_index += ret ;
244+ } else {
245+ allocate_snapshot = true;
246+ /* We also need the main ring buffer expanded */
247+ ring_buffer_expanded = true;
248+ }
233249 return 1 ;
234250}
235251__setup ("alloc_snapshot" , boot_alloc_snapshot );
@@ -9254,10 +9270,6 @@ static int allocate_trace_buffers(struct trace_array *tr, int size)
92549270 }
92559271 tr -> allocated_snapshot = allocate_snapshot ;
92569272
9257- /*
9258- * Only the top level trace array gets its snapshot allocated
9259- * from the kernel command line.
9260- */
92619273 allocate_snapshot = false;
92629274#endif
92639275
@@ -10173,6 +10185,47 @@ ssize_t trace_parse_run_command(struct file *file, const char __user *buffer,
1017310185 return ret ;
1017410186}
1017510187
10188+ #ifdef CONFIG_TRACER_MAX_TRACE
10189+ __init static bool tr_needs_alloc_snapshot (const char * name )
10190+ {
10191+ char * test ;
10192+ int len = strlen (name );
10193+ bool ret ;
10194+
10195+ if (!boot_snapshot_index )
10196+ return false;
10197+
10198+ if (strncmp (name , boot_snapshot_info , len ) == 0 &&
10199+ boot_snapshot_info [len ] == '\t' )
10200+ return true;
10201+
10202+ test = kmalloc (strlen (name ) + 3 , GFP_KERNEL );
10203+ if (!test )
10204+ return false;
10205+
10206+ sprintf (test , "\t%s\t" , name );
10207+ ret = strstr (boot_snapshot_info , test ) == NULL ;
10208+ kfree (test );
10209+ return ret ;
10210+ }
10211+
10212+ __init static void do_allocate_snapshot (const char * name )
10213+ {
10214+ if (!tr_needs_alloc_snapshot (name ))
10215+ return ;
10216+
10217+ /*
10218+ * When allocate_snapshot is set, the next call to
10219+ * allocate_trace_buffers() (called by trace_array_get_by_name())
10220+ * will allocate the snapshot buffer. That will alse clear
10221+ * this flag.
10222+ */
10223+ allocate_snapshot = true;
10224+ }
10225+ #else
10226+ static inline void do_allocate_snapshot (const char * name ) { }
10227+ #endif
10228+
1017610229__init static void enable_instances (void )
1017710230{
1017810231 struct trace_array * tr ;
@@ -10188,6 +10241,9 @@ __init static void enable_instances(void)
1018810241
1018910242 tok = strsep (& curr_str , "," );
1019010243
10244+ if (IS_ENABLED (CONFIG_TRACER_MAX_TRACE ))
10245+ do_allocate_snapshot (tok );
10246+
1019110247 tr = trace_array_get_by_name (tok );
1019210248 if (!tr ) {
1019310249 pr_warn ("Failed to create instance buffer %s\n" , curr_str );
@@ -10335,10 +10391,19 @@ __init static int tracer_alloc_buffers(void)
1033510391
1033610392void __init ftrace_boot_snapshot (void )
1033710393{
10394+ struct trace_array * tr ;
10395+
1033810396 if (snapshot_at_boot ) {
1033910397 tracing_snapshot ();
1034010398 internal_trace_puts ("** Boot snapshot taken **\n" );
1034110399 }
10400+
10401+ list_for_each_entry (tr , & ftrace_trace_arrays , list ) {
10402+ if (tr == & global_trace )
10403+ continue ;
10404+ trace_array_puts (tr , "** Boot snapshot taken **\n" );
10405+ tracing_snapshot_instance (tr );
10406+ }
1034210407}
1034310408
1034410409void __init early_trace_init (void )
0 commit comments