@@ -130,9 +130,12 @@ cpumask_var_t __read_mostly tracing_buffer_mask;
130
130
* /proc/sys/kernel/ftrace_dump_on_oops
131
131
* Set 1 if you want to dump buffers of all CPUs
132
132
* Set 2 if you want to dump the buffer of the CPU that triggered oops
133
+ * Set instance name if you want to dump the specific trace instance
134
+ * Multiple instance dump is also supported, and instances are seperated
135
+ * by commas.
133
136
*/
134
-
135
- enum ftrace_dump_mode ftrace_dump_on_oops ;
137
+ /* Set to string format zero to disable by default */
138
+ char ftrace_dump_on_oops [ MAX_TRACER_SIZE ] = "0" ;
136
139
137
140
/* When set, tracing will stop when a WARN*() is hit */
138
141
int __disable_trace_on_warning ;
@@ -178,7 +181,6 @@ static void ftrace_trace_userstack(struct trace_array *tr,
178
181
struct trace_buffer * buffer ,
179
182
unsigned int trace_ctx );
180
183
181
- #define MAX_TRACER_SIZE 100
182
184
static char bootup_tracer_buf [MAX_TRACER_SIZE ] __initdata ;
183
185
static char * default_bootup_tracer ;
184
186
@@ -201,19 +203,33 @@ static int __init set_cmdline_ftrace(char *str)
201
203
}
202
204
__setup ("ftrace=" , set_cmdline_ftrace );
203
205
206
+ int ftrace_dump_on_oops_enabled (void )
207
+ {
208
+ if (!strcmp ("0" , ftrace_dump_on_oops ))
209
+ return 0 ;
210
+ else
211
+ return 1 ;
212
+ }
213
+
204
214
static int __init set_ftrace_dump_on_oops (char * str )
205
215
{
206
- if (* str ++ != '=' || ! * str || ! strcmp ( "1" , str ) ) {
207
- ftrace_dump_on_oops = DUMP_ALL ;
216
+ if (! * str ) {
217
+ strscpy ( ftrace_dump_on_oops , "1" , MAX_TRACER_SIZE ) ;
208
218
return 1 ;
209
219
}
210
220
211
- if (!strcmp ("orig_cpu" , str ) || !strcmp ("2" , str )) {
212
- ftrace_dump_on_oops = DUMP_ORIG ;
213
- return 1 ;
214
- }
221
+ if (* str == ',' ) {
222
+ strscpy (ftrace_dump_on_oops , "1" , MAX_TRACER_SIZE );
223
+ strscpy (ftrace_dump_on_oops + 1 , str , MAX_TRACER_SIZE - 1 );
224
+ return 1 ;
225
+ }
226
+
227
+ if (* str ++ == '=' ) {
228
+ strscpy (ftrace_dump_on_oops , str , MAX_TRACER_SIZE );
229
+ return 1 ;
230
+ }
215
231
216
- return 0 ;
232
+ return 0 ;
217
233
}
218
234
__setup ("ftrace_dump_on_oops" , set_ftrace_dump_on_oops );
219
235
@@ -9832,14 +9848,14 @@ static struct notifier_block trace_die_notifier = {
9832
9848
static int trace_die_panic_handler (struct notifier_block * self ,
9833
9849
unsigned long ev , void * unused )
9834
9850
{
9835
- if (!ftrace_dump_on_oops )
9851
+ if (!ftrace_dump_on_oops_enabled () )
9836
9852
return NOTIFY_DONE ;
9837
9853
9838
9854
/* The die notifier requires DIE_OOPS to trigger */
9839
9855
if (self == & trace_die_notifier && ev != DIE_OOPS )
9840
9856
return NOTIFY_DONE ;
9841
9857
9842
- ftrace_dump (ftrace_dump_on_oops );
9858
+ ftrace_dump (DUMP_PARAM );
9843
9859
9844
9860
return NOTIFY_DONE ;
9845
9861
}
@@ -9880,12 +9896,12 @@ trace_printk_seq(struct trace_seq *s)
9880
9896
trace_seq_init (s );
9881
9897
}
9882
9898
9883
- void trace_init_global_iter (struct trace_iterator * iter )
9899
+ static void trace_init_iter (struct trace_iterator * iter , struct trace_array * tr )
9884
9900
{
9885
- iter -> tr = & global_trace ;
9901
+ iter -> tr = tr ;
9886
9902
iter -> trace = iter -> tr -> current_trace ;
9887
9903
iter -> cpu_file = RING_BUFFER_ALL_CPUS ;
9888
- iter -> array_buffer = & global_trace . array_buffer ;
9904
+ iter -> array_buffer = & tr -> array_buffer ;
9889
9905
9890
9906
if (iter -> trace && iter -> trace -> open )
9891
9907
iter -> trace -> open (iter );
@@ -9905,22 +9921,19 @@ void trace_init_global_iter(struct trace_iterator *iter)
9905
9921
iter -> fmt_size = STATIC_FMT_BUF_SIZE ;
9906
9922
}
9907
9923
9908
- void ftrace_dump (enum ftrace_dump_mode oops_dump_mode )
9924
+ void trace_init_global_iter (struct trace_iterator * iter )
9925
+ {
9926
+ trace_init_iter (iter , & global_trace );
9927
+ }
9928
+
9929
+ static void ftrace_dump_one (struct trace_array * tr , enum ftrace_dump_mode dump_mode )
9909
9930
{
9910
9931
/* use static because iter can be a bit big for the stack */
9911
9932
static struct trace_iterator iter ;
9912
- static atomic_t dump_running ;
9913
- struct trace_array * tr = & global_trace ;
9914
9933
unsigned int old_userobj ;
9915
9934
unsigned long flags ;
9916
9935
int cnt = 0 , cpu ;
9917
9936
9918
- /* Only allow one dump user at a time. */
9919
- if (atomic_inc_return (& dump_running ) != 1 ) {
9920
- atomic_dec (& dump_running );
9921
- return ;
9922
- }
9923
-
9924
9937
/*
9925
9938
* Always turn off tracing when we dump.
9926
9939
* We don't need to show trace output of what happens
@@ -9929,12 +9942,12 @@ void ftrace_dump(enum ftrace_dump_mode oops_dump_mode)
9929
9942
* If the user does a sysrq-z, then they can re-enable
9930
9943
* tracing with echo 1 > tracing_on.
9931
9944
*/
9932
- tracing_off ( );
9945
+ tracer_tracing_off ( tr );
9933
9946
9934
9947
local_irq_save (flags );
9935
9948
9936
9949
/* Simulate the iterator */
9937
- trace_init_global_iter (& iter );
9950
+ trace_init_iter (& iter , tr );
9938
9951
9939
9952
for_each_tracing_cpu (cpu ) {
9940
9953
atomic_inc (& per_cpu_ptr (iter .array_buffer -> data , cpu )-> disabled );
@@ -9945,21 +9958,15 @@ void ftrace_dump(enum ftrace_dump_mode oops_dump_mode)
9945
9958
/* don't look at user memory in panic mode */
9946
9959
tr -> trace_flags &= ~TRACE_ITER_SYM_USEROBJ ;
9947
9960
9948
- switch (oops_dump_mode ) {
9949
- case DUMP_ALL :
9950
- iter .cpu_file = RING_BUFFER_ALL_CPUS ;
9951
- break ;
9952
- case DUMP_ORIG :
9961
+ if (dump_mode == DUMP_ORIG )
9953
9962
iter .cpu_file = raw_smp_processor_id ();
9954
- break ;
9955
- case DUMP_NONE :
9956
- goto out_enable ;
9957
- default :
9958
- printk (KERN_TRACE "Bad dumping mode, switching to all CPUs dump\n" );
9963
+ else
9959
9964
iter .cpu_file = RING_BUFFER_ALL_CPUS ;
9960
- }
9961
9965
9962
- printk (KERN_TRACE "Dumping ftrace buffer:\n" );
9966
+ if (tr == & global_trace )
9967
+ printk (KERN_TRACE "Dumping ftrace buffer:\n" );
9968
+ else
9969
+ printk (KERN_TRACE "Dumping ftrace instance %s buffer:\n" , tr -> name );
9963
9970
9964
9971
/* Did function tracer already get disabled? */
9965
9972
if (ftrace_is_dead ()) {
@@ -10001,15 +10008,84 @@ void ftrace_dump(enum ftrace_dump_mode oops_dump_mode)
10001
10008
else
10002
10009
printk (KERN_TRACE "---------------------------------\n" );
10003
10010
10004
- out_enable :
10005
10011
tr -> trace_flags |= old_userobj ;
10006
10012
10007
10013
for_each_tracing_cpu (cpu ) {
10008
10014
atomic_dec (& per_cpu_ptr (iter .array_buffer -> data , cpu )-> disabled );
10009
10015
}
10010
- atomic_dec (& dump_running );
10011
10016
local_irq_restore (flags );
10012
10017
}
10018
+
10019
+ static void ftrace_dump_by_param (void )
10020
+ {
10021
+ bool first_param = true;
10022
+ char dump_param [MAX_TRACER_SIZE ];
10023
+ char * buf , * token , * inst_name ;
10024
+ struct trace_array * tr ;
10025
+
10026
+ strscpy (dump_param , ftrace_dump_on_oops , MAX_TRACER_SIZE );
10027
+ buf = dump_param ;
10028
+
10029
+ while ((token = strsep (& buf , "," )) != NULL ) {
10030
+ if (first_param ) {
10031
+ first_param = false;
10032
+ if (!strcmp ("0" , token ))
10033
+ continue ;
10034
+ else if (!strcmp ("1" , token )) {
10035
+ ftrace_dump_one (& global_trace , DUMP_ALL );
10036
+ continue ;
10037
+ }
10038
+ else if (!strcmp ("2" , token ) ||
10039
+ !strcmp ("orig_cpu" , token )) {
10040
+ ftrace_dump_one (& global_trace , DUMP_ORIG );
10041
+ continue ;
10042
+ }
10043
+ }
10044
+
10045
+ inst_name = strsep (& token , "=" );
10046
+ tr = trace_array_find (inst_name );
10047
+ if (!tr ) {
10048
+ printk (KERN_TRACE "Instance %s not found\n" , inst_name );
10049
+ continue ;
10050
+ }
10051
+
10052
+ if (token && (!strcmp ("2" , token ) ||
10053
+ !strcmp ("orig_cpu" , token )))
10054
+ ftrace_dump_one (tr , DUMP_ORIG );
10055
+ else
10056
+ ftrace_dump_one (tr , DUMP_ALL );
10057
+ }
10058
+ }
10059
+
10060
+ void ftrace_dump (enum ftrace_dump_mode oops_dump_mode )
10061
+ {
10062
+ static atomic_t dump_running ;
10063
+
10064
+ /* Only allow one dump user at a time. */
10065
+ if (atomic_inc_return (& dump_running ) != 1 ) {
10066
+ atomic_dec (& dump_running );
10067
+ return ;
10068
+ }
10069
+
10070
+ switch (oops_dump_mode ) {
10071
+ case DUMP_ALL :
10072
+ ftrace_dump_one (& global_trace , DUMP_ALL );
10073
+ break ;
10074
+ case DUMP_ORIG :
10075
+ ftrace_dump_one (& global_trace , DUMP_ORIG );
10076
+ break ;
10077
+ case DUMP_PARAM :
10078
+ ftrace_dump_by_param ();
10079
+ break ;
10080
+ case DUMP_NONE :
10081
+ break ;
10082
+ default :
10083
+ printk (KERN_TRACE "Bad dumping mode, switching to all CPUs dump\n" );
10084
+ ftrace_dump_one (& global_trace , DUMP_ALL );
10085
+ }
10086
+
10087
+ atomic_dec (& dump_running );
10088
+ }
10013
10089
EXPORT_SYMBOL_GPL (ftrace_dump );
10014
10090
10015
10091
#define WRITE_BUFSIZE 4096
0 commit comments