Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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.org


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 21cf6284
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -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
+21 −5
Original line number Diff line number Diff line
@@ -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,
+37 −3
Original line number Diff line number Diff line
@@ -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;
+1 −0
Original line number Diff line number Diff line
@@ -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,