@@ -191,6 +191,9 @@ static bool snapshot_at_boot;
191
191
static char boot_instance_info [COMMAND_LINE_SIZE ] __initdata ;
192
192
static int boot_instance_index ;
193
193
194
+ static char boot_snapshot_info [COMMAND_LINE_SIZE ] __initdata ;
195
+ static int boot_snapshot_index ;
196
+
194
197
static int __init set_cmdline_ftrace (char * str )
195
198
{
196
199
strlcpy (bootup_tracer_buf , str , MAX_TRACER_SIZE );
@@ -227,9 +230,22 @@ __setup("traceoff_on_warning", stop_trace_on_warning);
227
230
228
231
static int __init boot_alloc_snapshot (char * str )
229
232
{
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
+ }
233
249
return 1 ;
234
250
}
235
251
__setup ("alloc_snapshot" , boot_alloc_snapshot );
@@ -9254,10 +9270,6 @@ static int allocate_trace_buffers(struct trace_array *tr, int size)
9254
9270
}
9255
9271
tr -> allocated_snapshot = allocate_snapshot ;
9256
9272
9257
- /*
9258
- * Only the top level trace array gets its snapshot allocated
9259
- * from the kernel command line.
9260
- */
9261
9273
allocate_snapshot = false;
9262
9274
#endif
9263
9275
@@ -10173,6 +10185,47 @@ ssize_t trace_parse_run_command(struct file *file, const char __user *buffer,
10173
10185
return ret ;
10174
10186
}
10175
10187
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
+
10176
10229
__init static void enable_instances (void )
10177
10230
{
10178
10231
struct trace_array * tr ;
@@ -10188,6 +10241,9 @@ __init static void enable_instances(void)
10188
10241
10189
10242
tok = strsep (& curr_str , "," );
10190
10243
10244
+ if (IS_ENABLED (CONFIG_TRACER_MAX_TRACE ))
10245
+ do_allocate_snapshot (tok );
10246
+
10191
10247
tr = trace_array_get_by_name (tok );
10192
10248
if (!tr ) {
10193
10249
pr_warn ("Failed to create instance buffer %s\n" , curr_str );
@@ -10335,10 +10391,19 @@ __init static int tracer_alloc_buffers(void)
10335
10391
10336
10392
void __init ftrace_boot_snapshot (void )
10337
10393
{
10394
+ struct trace_array * tr ;
10395
+
10338
10396
if (snapshot_at_boot ) {
10339
10397
tracing_snapshot ();
10340
10398
internal_trace_puts ("** Boot snapshot taken **\n" );
10341
10399
}
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
+ }
10342
10407
}
10343
10408
10344
10409
void __init early_trace_init (void )
0 commit comments