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: Namhyung 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.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
21cf62847d
commit
a2c10d39af
@ -160,9 +160,10 @@ Default is to monitor all CPUS.
|
||||
-g::
|
||||
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,
|
||||
implies -g.
|
||||
implies -g. See `--call-graph` section in perf-record and
|
||||
perf-report man pages for details.
|
||||
|
||||
--children::
|
||||
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)
|
||||
static int
|
||||
parse_callchain_opt(const struct option *opt, const char *arg, int unset)
|
||||
{
|
||||
symbol_conf.use_callchain = true;
|
||||
return record_parse_callchain_opt(opt, arg, unset);
|
||||
struct record_opts *record = (struct record_opts *)opt->value;
|
||||
|
||||
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)
|
||||
@ -1079,6 +1093,8 @@ parse_percent_limit(const struct option *opt, const char *arg,
|
||||
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)
|
||||
{
|
||||
char errbuf[BUFSIZ];
|
||||
@ -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,
|
||||
"Show a column with the number of samples"),
|
||||
OPT_CALLBACK_NOOPT('g', NULL, &top.record_opts,
|
||||
NULL, "enables call-graph recording",
|
||||
NULL, "enables call-graph recording and display",
|
||||
&callchain_opt),
|
||||
OPT_CALLBACK(0, "call-graph", &top.record_opts,
|
||||
"mode[,dump_size]", record_callchain_help,
|
||||
&parse_callchain_opt),
|
||||
"mode[,dump_size],output_type,min_percent[,print_limit],call_order[,branch]",
|
||||
top_callchain_help, &parse_callchain_opt),
|
||||
OPT_BOOLEAN(0, "children", &symbol_conf.cumulate_callchain,
|
||||
"Accumulate callchains of children and show total overhead as well"),
|
||||
OPT_INTEGER(0, "max-stack", &top.max_stack,
|
||||
|
@ -77,12 +77,14 @@ static int parse_callchain_sort_key(const char *value)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
parse_callchain_report_opt(const char *arg)
|
||||
static int
|
||||
__parse_callchain_report_opt(const char *arg, bool allow_record_opt)
|
||||
{
|
||||
char *tok;
|
||||
char *endptr;
|
||||
bool minpcnt_set = false;
|
||||
bool record_opt_set = false;
|
||||
bool try_stack_size = false;
|
||||
|
||||
symbol_conf.use_callchain = true;
|
||||
|
||||
@ -100,6 +102,28 @@ parse_callchain_report_opt(const char *arg)
|
||||
!parse_callchain_order(tok) ||
|
||||
!parse_callchain_sort_key(tok)) {
|
||||
/* 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) {
|
||||
/* try to get the min percent */
|
||||
callchain_param.min_percent = strtod(tok, &endptr);
|
||||
@ -112,7 +136,7 @@ parse_callchain_report_opt(const char *arg)
|
||||
if (tok == endptr)
|
||||
return -1;
|
||||
}
|
||||
|
||||
next:
|
||||
arg = NULL;
|
||||
}
|
||||
|
||||
@ -123,6 +147,16 @@ parse_callchain_report_opt(const char *arg)
|
||||
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)
|
||||
{
|
||||
char *endptr;
|
||||
|
@ -192,6 +192,7 @@ extern const char record_callchain_help[];
|
||||
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_report_opt(const char *arg);
|
||||
int parse_callchain_top_opt(const char *arg);
|
||||
int perf_callchain_config(const char *var, const char *value);
|
||||
|
||||
static inline void callchain_cursor_snapshot(struct callchain_cursor *dest,
|
||||
|
Loading…
Reference in New Issue
Block a user