Commit a2c10d39 authored by Namhyung Kim's avatar Namhyung Kim Committed by Arnaldo Carvalho de Melo

perf top: Support call-graph display options also

Currently 'perf top --call-graph' option is same as 'perf record'.  But
'perf top' also need to receive display options in 'perf report'.  To do
that, change parse_callchain_report_opt() to allow record options too.

Now perf top can receive display options like below:

  $ perf top --call-graph
    Error: option `call-graph' requires a value

   Usage: perf top [<options>]

        --call-graph
          <mode[,dump_size],output_type,min_percent[,print_limit],call_order[,branch]>
                     setup and enables call-graph (stack chain/backtrace)
                     recording: fp dwarf lbr, output_type (graph, flat,
		     fractal, or none), min percent threshold, optional
		     print limit, callchain order, key (function or
		     address), add branches

  $ perf top --call-graph callee,graph,fp
Signed-off-by: default avatarNamhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Chandler Carruth <chandlerc@gmail.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1445495330-25416-2-git-send-email-namhyung@kernel.orgSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 21cf6284
...@@ -160,9 +160,10 @@ Default is to monitor all CPUS. ...@@ -160,9 +160,10 @@ Default is to monitor all CPUS.
-g:: -g::
Enables call-graph (stack chain/backtrace) recording. Enables call-graph (stack chain/backtrace) recording.
--call-graph:: --call-graph [mode,type,min[,limit],order[,key][,branch]]::
Setup and enable call-graph (stack chain/backtrace) recording, Setup and enable call-graph (stack chain/backtrace) recording,
implies -g. implies -g. See `--call-graph` section in perf-record and
perf-report man pages for details.
--children:: --children::
Accumulate callchain of children to parent entry so that then can Accumulate callchain of children to parent entry so that then can
......
...@@ -1053,8 +1053,22 @@ callchain_opt(const struct option *opt, const char *arg, int unset) ...@@ -1053,8 +1053,22 @@ callchain_opt(const struct option *opt, const char *arg, int unset)
static int static int
parse_callchain_opt(const struct option *opt, const char *arg, int unset) parse_callchain_opt(const struct option *opt, const char *arg, int unset)
{ {
symbol_conf.use_callchain = true; struct record_opts *record = (struct record_opts *)opt->value;
return record_parse_callchain_opt(opt, arg, unset);
record->callgraph_set = true;
callchain_param.enabled = !unset;
callchain_param.record_mode = CALLCHAIN_FP;
/*
* --no-call-graph
*/
if (unset) {
symbol_conf.use_callchain = false;
callchain_param.record_mode = CALLCHAIN_NONE;
return 0;
}
return parse_callchain_top_opt(arg);
} }
static int perf_top_config(const char *var, const char *value, void *cb) static int perf_top_config(const char *var, const char *value, void *cb)
...@@ -1079,6 +1093,8 @@ parse_percent_limit(const struct option *opt, const char *arg, ...@@ -1079,6 +1093,8 @@ parse_percent_limit(const struct option *opt, const char *arg,
return 0; return 0;
} }
const char top_callchain_help[] = CALLCHAIN_RECORD_HELP ", " CALLCHAIN_REPORT_HELP;
int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
{ {
char errbuf[BUFSIZ]; char errbuf[BUFSIZ];
...@@ -1154,11 +1170,11 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -1154,11 +1170,11 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples, OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples,
"Show a column with the number of samples"), "Show a column with the number of samples"),
OPT_CALLBACK_NOOPT('g', NULL, &top.record_opts, OPT_CALLBACK_NOOPT('g', NULL, &top.record_opts,
NULL, "enables call-graph recording", NULL, "enables call-graph recording and display",
&callchain_opt), &callchain_opt),
OPT_CALLBACK(0, "call-graph", &top.record_opts, OPT_CALLBACK(0, "call-graph", &top.record_opts,
"mode[,dump_size]", record_callchain_help, "mode[,dump_size],output_type,min_percent[,print_limit],call_order[,branch]",
&parse_callchain_opt), top_callchain_help, &parse_callchain_opt),
OPT_BOOLEAN(0, "children", &symbol_conf.cumulate_callchain, OPT_BOOLEAN(0, "children", &symbol_conf.cumulate_callchain,
"Accumulate callchains of children and show total overhead as well"), "Accumulate callchains of children and show total overhead as well"),
OPT_INTEGER(0, "max-stack", &top.max_stack, OPT_INTEGER(0, "max-stack", &top.max_stack,
......
...@@ -77,12 +77,14 @@ static int parse_callchain_sort_key(const char *value) ...@@ -77,12 +77,14 @@ static int parse_callchain_sort_key(const char *value)
return -1; return -1;
} }
int static int
parse_callchain_report_opt(const char *arg) __parse_callchain_report_opt(const char *arg, bool allow_record_opt)
{ {
char *tok; char *tok;
char *endptr; char *endptr;
bool minpcnt_set = false; bool minpcnt_set = false;
bool record_opt_set = false;
bool try_stack_size = false;
symbol_conf.use_callchain = true; symbol_conf.use_callchain = true;
...@@ -100,6 +102,28 @@ parse_callchain_report_opt(const char *arg) ...@@ -100,6 +102,28 @@ parse_callchain_report_opt(const char *arg)
!parse_callchain_order(tok) || !parse_callchain_order(tok) ||
!parse_callchain_sort_key(tok)) { !parse_callchain_sort_key(tok)) {
/* parsing ok - move on to the next */ /* parsing ok - move on to the next */
try_stack_size = false;
goto next;
} else if (allow_record_opt && !record_opt_set) {
if (parse_callchain_record(tok, &callchain_param))
goto try_numbers;
/* assume that number followed by 'dwarf' is stack size */
if (callchain_param.record_mode == CALLCHAIN_DWARF)
try_stack_size = true;
record_opt_set = true;
goto next;
}
try_numbers:
if (try_stack_size) {
unsigned long size = 0;
if (get_stack_size(tok, &size) < 0)
return -1;
callchain_param.dump_size = size;
try_stack_size = false;
} else if (!minpcnt_set) { } else if (!minpcnt_set) {
/* try to get the min percent */ /* try to get the min percent */
callchain_param.min_percent = strtod(tok, &endptr); callchain_param.min_percent = strtod(tok, &endptr);
...@@ -112,7 +136,7 @@ parse_callchain_report_opt(const char *arg) ...@@ -112,7 +136,7 @@ parse_callchain_report_opt(const char *arg)
if (tok == endptr) if (tok == endptr)
return -1; return -1;
} }
next:
arg = NULL; arg = NULL;
} }
...@@ -123,6 +147,16 @@ parse_callchain_report_opt(const char *arg) ...@@ -123,6 +147,16 @@ parse_callchain_report_opt(const char *arg)
return 0; return 0;
} }
int parse_callchain_report_opt(const char *arg)
{
return __parse_callchain_report_opt(arg, false);
}
int parse_callchain_top_opt(const char *arg)
{
return __parse_callchain_report_opt(arg, true);
}
int perf_callchain_config(const char *var, const char *value) int perf_callchain_config(const char *var, const char *value)
{ {
char *endptr; char *endptr;
......
...@@ -192,6 +192,7 @@ extern const char record_callchain_help[]; ...@@ -192,6 +192,7 @@ extern const char record_callchain_help[];
extern int parse_callchain_record(const char *arg, struct callchain_param *param); extern int parse_callchain_record(const char *arg, struct callchain_param *param);
int parse_callchain_record_opt(const char *arg, struct callchain_param *param); int parse_callchain_record_opt(const char *arg, struct callchain_param *param);
int parse_callchain_report_opt(const char *arg); int parse_callchain_report_opt(const char *arg);
int parse_callchain_top_opt(const char *arg);
int perf_callchain_config(const char *var, const char *value); int perf_callchain_config(const char *var, const char *value);
static inline void callchain_cursor_snapshot(struct callchain_cursor *dest, static inline void callchain_cursor_snapshot(struct callchain_cursor *dest,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment