perf ftrace: Select function/function_graph tracer automatically
authorChangbin Du <changbin.du@gmail.com>
Sat, 8 Aug 2020 02:31:24 +0000 (10:31 +0800)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Fri, 14 Aug 2020 11:36:31 +0000 (08:36 -0300)
The '-g/-G' options have already implied function_graph tracer should be
used instead of function tracer. So we don't need extra option
'--tracer' in this case.

This patch changes the behavior as below:

  - If '-g' or '-G' option is on, then function_graph tracer is used.
  - If '-T' or '-N' option is on, then function tracer is used.
  - The function_graph has priority over function tracer.
  - The option '--tracer' only take effect if neither -g/-G nor -T/-N
    is specified.

Here are some examples.

This will start tracing all functions using default tracer:

  $ sudo perf ftrace

This will trace all functions using function graph tracer:

  $ sudo perf ftrace -G '*'

This will trace function vfs_read using function graph tracer:

  $ sudo perf ftrace -G vfs_read

This will trace function vfs_read using function tracer:

  $ sudo perf ftrace -T vfs_read

Committer notes:

Using '-h -G' will tell what that option is about, so to further clarify
the above examples:

  # perf ftrace -h -G

    -G, --graph-funcs <func> Set graph filter on given functions

  # perf ftrace -h -g

    -g, --nograph-funcs <func> Set nograph filter on given functions

  # perf ftrace -h -T

    -T, --trace-funcs <func> trace given functions only

  # perf ftrace -h -N

    -N, --notrace-funcs <func> do not trace given functions

  #

Signed-off-by: Changbin Du <changbin.du@gmail.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Steven Rostedt (VMware) <rostedt@goodmis.org>
Link: http://lore.kernel.org/lkml/20200808023141.14227-2-changbin.du@gmail.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/Documentation/perf-config.txt
tools/perf/Documentation/perf-ftrace.txt
tools/perf/builtin-ftrace.c

index c7d3df5798e261b2201920de03e2347ce1058e64..76408d986aed765a890831d926b4be9084f91e97 100644 (file)
@@ -614,8 +614,9 @@ trace.*::
 
 ftrace.*::
        ftrace.tracer::
-               Can be used to select the default tracer. Possible values are
-               'function' and 'function_graph'.
+               Can be used to select the default tracer when neither -G nor
+               -F option is not specified. Possible values are 'function' and
+               'function_graph'.
 
 llvm.*::
        llvm.clang-path::
index b80c84307dc9ec2771afd0dbce168b301d85edf7..821d4d334a096803b80938a2dc0f65ca7b67358a 100644 (file)
@@ -24,7 +24,8 @@ OPTIONS
 
 -t::
 --tracer=::
-       Tracer to use: function_graph or function.
+       Tracer to use when neither -G nor -F option is not
+       specified: function_graph or function.
 
 -v::
 --verbose=::
@@ -50,33 +51,35 @@ OPTIONS
 
 -T::
 --trace-funcs=::
-       Only trace functions given by the argument.  Multiple functions
-       can be given by using this option more than once.  The function
-       argument also can be a glob pattern.  It will be passed to
-       'set_ftrace_filter' in tracefs.
+       Select function tracer and set function filter on the given
+       function (or a glob pattern). Multiple functions can be given
+       by using this option more than once. The function argument also
+       can be a glob pattern. It will be passed to 'set_ftrace_filter'
+       in tracefs.
 
 -N::
 --notrace-funcs=::
-       Do not trace functions given by the argument.  Like -T option,
-       this can be used more than once to specify multiple functions
-       (or glob patterns).  It will be passed to 'set_ftrace_notrace'
-       in tracefs.
+       Select function tracer and do not trace functions given by the
+       argument.  Like -T option, this can be used more than once to
+       specify multiple functions (or glob patterns).  It will be
+       passed to 'set_ftrace_notrace' in tracefs.
 
 -G::
 --graph-funcs=::
-       Set graph filter on the given function (or a glob pattern).
-       This is useful for the function_graph tracer only and enables
-       tracing for functions executed from the given function.
-       This can be used more than once to specify multiple functions.
-       It will be passed to 'set_graph_function' in tracefs.
+       Select function_graph tracer and set graph filter on the given
+       function (or a glob pattern). This is useful to trace for
+       functions executed from the given function. This can be used more
+       than once to specify multiple functions. It will be passed to
+       'set_graph_function' in tracefs.
 
 -g::
 --nograph-funcs=::
-       Set graph notrace filter on the given function (or a glob pattern).
-       Like -G option, this is useful for the function_graph tracer only
-       and disables tracing for function executed from the given function.
-       This can be used more than once to specify multiple functions.
-       It will be passed to 'set_graph_notrace' in tracefs.
+       Select function_graph tracer and set graph notrace filter on the
+       given function (or a glob pattern). Like -G option, this is useful
+       for the function_graph tracer only and disables tracing for function
+       executed from the given function. This can be used more than once to
+       specify multiple functions. It will be passed to 'set_graph_notrace'
+       in tracefs.
 
 -D::
 --graph-depth=::
index 2bfc1b0db536325d5f6e92cffa73eeecd13d7c58..048a11192b59205372f4b32f34184c78c9770781 100644 (file)
@@ -455,6 +455,23 @@ static void delete_filter_func(struct list_head *head)
        }
 }
 
+static void select_tracer(struct perf_ftrace *ftrace)
+{
+       bool graph = !list_empty(&ftrace->graph_funcs) ||
+                    !list_empty(&ftrace->nograph_funcs);
+       bool func = !list_empty(&ftrace->filters) ||
+                   !list_empty(&ftrace->notrace);
+
+       /* The function_graph has priority over function tracer. */
+       if (graph)
+               ftrace->tracer = "function_graph";
+       else if (func)
+               ftrace->tracer = "function";
+       /* Otherwise, the default tracer is used. */
+
+       pr_debug("%s tracer is used\n", ftrace->tracer);
+}
+
 int cmd_ftrace(int argc, const char **argv)
 {
        int ret;
@@ -479,11 +496,13 @@ int cmd_ftrace(int argc, const char **argv)
        OPT_STRING('C', "cpu", &ftrace.target.cpu_list, "cpu",
                    "list of cpus to monitor"),
        OPT_CALLBACK('T', "trace-funcs", &ftrace.filters, "func",
-                    "trace given functions only", parse_filter_func),
+                    "trace given functions using function tracer",
+                    parse_filter_func),
        OPT_CALLBACK('N', "notrace-funcs", &ftrace.notrace, "func",
                     "do not trace given functions", parse_filter_func),
        OPT_CALLBACK('G', "graph-funcs", &ftrace.graph_funcs, "func",
-                    "Set graph filter on given functions", parse_filter_func),
+                    "trace given functions using function_graph tracer",
+                    parse_filter_func),
        OPT_CALLBACK('g', "nograph-funcs", &ftrace.nograph_funcs, "func",
                     "Set nograph filter on given functions", parse_filter_func),
        OPT_INTEGER('D', "graph-depth", &ftrace.graph_depth,
@@ -505,6 +524,8 @@ int cmd_ftrace(int argc, const char **argv)
        if (!argc && target__none(&ftrace.target))
                ftrace.target.system_wide = true;
 
+       select_tracer(&ftrace);
+
        ret = target__validate(&ftrace.target);
        if (ret) {
                char errbuf[512];