27
27
#include "util/cap.h"
28
28
#include "util/config.h"
29
29
#include "util/units.h"
30
+ #include "util/parse-sublevel-options.h"
30
31
31
32
#define DEFAULT_TRACER "function_graph"
32
33
@@ -42,6 +43,7 @@ struct perf_ftrace {
42
43
int graph_depth ;
43
44
unsigned long percpu_buffer_size ;
44
45
bool inherit ;
46
+ int func_stack_trace ;
45
47
};
46
48
47
49
struct filter_entry {
@@ -202,6 +204,7 @@ static void reset_tracing_filters(void);
202
204
static void reset_tracing_options (struct perf_ftrace * ftrace __maybe_unused )
203
205
{
204
206
write_tracing_option_file ("function-fork" , "0" );
207
+ write_tracing_option_file ("func_stack_trace" , "0" );
205
208
}
206
209
207
210
static int reset_tracing_files (struct perf_ftrace * ftrace __maybe_unused )
@@ -278,6 +281,17 @@ static int set_tracing_cpu(struct perf_ftrace *ftrace)
278
281
return set_tracing_cpumask (cpumap );
279
282
}
280
283
284
+ static int set_tracing_func_stack_trace (struct perf_ftrace * ftrace )
285
+ {
286
+ if (!ftrace -> func_stack_trace )
287
+ return 0 ;
288
+
289
+ if (write_tracing_option_file ("func_stack_trace" , "1" ) < 0 )
290
+ return -1 ;
291
+
292
+ return 0 ;
293
+ }
294
+
281
295
static int reset_tracing_cpu (void )
282
296
{
283
297
struct perf_cpu_map * cpumap = perf_cpu_map__new (NULL );
@@ -426,6 +440,11 @@ static int __cmd_ftrace(struct perf_ftrace *ftrace, int argc, const char **argv)
426
440
goto out_reset ;
427
441
}
428
442
443
+ if (set_tracing_func_stack_trace (ftrace ) < 0 ) {
444
+ pr_err ("failed to set tracing option func_stack_trace\n" );
445
+ goto out_reset ;
446
+ }
447
+
429
448
if (set_tracing_filters (ftrace ) < 0 ) {
430
449
pr_err ("failed to set tracing filters\n" );
431
450
goto out_reset ;
@@ -598,6 +617,26 @@ static int parse_buffer_size(const struct option *opt,
598
617
return -1 ;
599
618
}
600
619
620
+ static int parse_func_tracer_opts (const struct option * opt ,
621
+ const char * str , int unset )
622
+ {
623
+ int ret ;
624
+ struct perf_ftrace * ftrace = (struct perf_ftrace * ) opt -> value ;
625
+ struct sublevel_option func_tracer_opts [] = {
626
+ { .name = "call-graph" , .value_ptr = & ftrace -> func_stack_trace },
627
+ { .name = NULL , }
628
+ };
629
+
630
+ if (unset )
631
+ return 0 ;
632
+
633
+ ret = perf_parse_sublevel_options (str , func_tracer_opts );
634
+ if (ret )
635
+ return ret ;
636
+
637
+ return 0 ;
638
+ }
639
+
601
640
static void select_tracer (struct perf_ftrace * ftrace )
602
641
{
603
642
bool graph = !list_empty (& ftrace -> graph_funcs ) ||
@@ -645,6 +684,9 @@ int cmd_ftrace(int argc, const char **argv)
645
684
parse_filter_func ),
646
685
OPT_CALLBACK ('N' , "notrace-funcs" , & ftrace .notrace , "func" ,
647
686
"do not trace given functions" , parse_filter_func ),
687
+ OPT_CALLBACK (0 , "func-opts" , & ftrace , "options" ,
688
+ "function tracer options, available options: call-graph" ,
689
+ parse_func_tracer_opts ),
648
690
OPT_CALLBACK ('G' , "graph-funcs" , & ftrace .graph_funcs , "func" ,
649
691
"trace given functions using function_graph tracer" ,
650
692
parse_filter_func ),
0 commit comments