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

Commit 993ac88d authored by Stephane Eranian's avatar Stephane Eranian Committed by Ingo Molnar
Browse files

perf report: Auto-detect branch stack sampling mode



This patch enhances perf report to auto-detect when the
perf.data file contains samples with branch stacks. That way it
is not necessary to use the -b option.

To force branch view mode to off, simply use --no-branch-stack.

Signed-off-by: default avatarStephane Eranian <eranian@google.com>
Cc: peterz@infradead.org
Cc: acme@redhat.com
Cc: asharma@fb.com
Cc: ravitillo@lbl.gov
Cc: vweaver1@eecs.utk.edu
Cc: khandual@linux.vnet.ibm.com
Cc: dsahern@gmail.com
Link: http://lkml.kernel.org/r/1331246868-19905-4-git-send-email-eranian@google.com


Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 330aa675
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -157,8 +157,11 @@ OPTIONS
--branch-stack::
	Use the addresses of sampled taken branches instead of the instruction
	address to build the histograms. To generate meaningful output, the
	perf.data file must have been obtained using perf record -b xxx where
	xxx is a branch filter option.
	perf.data file must have been obtained using perf record -b or
	perf record --branch-filter xxx where xxx is a branch filter option.
	perf report is able to auto-detect whether a perf.data file contains
	branch stacks and it will automatically switch to the branch view mode,
	unless --no-branch-stack is used.

SEE ALSO
--------
+34 −16
Original line number Diff line number Diff line
@@ -170,7 +170,7 @@ static int process_sample_event(struct perf_tool *tool,
	if (rep->cpu_list && !test_bit(sample->cpu, rep->cpu_bitmap))
		return 0;

	if (sort__branch_mode) {
	if (sort__branch_mode == 1) {
		if (perf_report__add_branch_hist_entry(tool, &al, sample,
						       evsel, machine)) {
			pr_debug("problem adding lbr entry, skipping event\n");
@@ -239,7 +239,7 @@ static int perf_report__setup_sample_type(struct perf_report *rep)
			}
	}

	if (sort__branch_mode) {
	if (sort__branch_mode == 1) {
		if (!(self->sample_type & PERF_SAMPLE_BRANCH_STACK)) {
			fprintf(stderr, "selected -b but no branch data."
					" Did you call perf record without"
@@ -306,7 +306,7 @@ static int __cmd_report(struct perf_report *rep)
{
	int ret = -EINVAL;
	u64 nr_samples;
	struct perf_session *session;
	struct perf_session *session = rep->session;
	struct perf_evsel *pos;
	struct map *kernel_map;
	struct kmap *kernel_kmap;
@@ -314,13 +314,6 @@ static int __cmd_report(struct perf_report *rep)

	signal(SIGINT, sig_handler);

	session = perf_session__new(rep->input_name, O_RDONLY,
				    rep->force, false, &rep->tool);
	if (session == NULL)
		return -ENOMEM;

	rep->session = session;

	if (rep->cpu_list) {
		ret = perf_session__cpu_bitmap(session, rep->cpu_list,
					       rep->cpu_bitmap);
@@ -487,9 +480,19 @@ parse_callchain_opt(const struct option *opt, const char *arg, int unset)
	return 0;
}

static int
parse_branch_mode(const struct option *opt __used, const char *str __used, int unset)
{
	sort__branch_mode = !unset;
	return 0;
}

int cmd_report(int argc, const char **argv, const char *prefix __used)
{
	struct perf_session *session;
	struct stat st;
	bool has_br_stack = false;
	int ret = -1;
	char callchain_default_opt[] = "fractal,0.5,callee";
	const char * const report_usage[] = {
		"perf report [<options>]",
@@ -578,8 +581,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
		   "Specify disassembler style (e.g. -M intel for intel syntax)"),
	OPT_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period,
		    "Show a column with the sum of periods"),
	OPT_BOOLEAN('b', "branch-stack", &sort__branch_mode,
		    "use branch records for histogram filling"),
	OPT_CALLBACK_NOOPT('b', "branch-stack", &sort__branch_mode, "",
		    "use branch records for histogram filling", parse_branch_mode),
	OPT_END()
	};

@@ -599,8 +602,20 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
		else
			report.input_name = "perf.data";
	}
	session = perf_session__new(report.input_name, O_RDONLY,
				    report.force, false, &report.tool);
	if (session == NULL)
		return -ENOMEM;

	report.session = session;

	has_br_stack = perf_header__has_feat(&session->header,
					     HEADER_BRANCH_STACK);

	if (sort__branch_mode) {
	if (sort__branch_mode == -1 && has_br_stack)
		sort__branch_mode = 1;

	if (sort__branch_mode == 1) {
		if (use_browser)
			fprintf(stderr, "Warning: TUI interface not supported"
					" in branch mode\n");
@@ -657,13 +672,13 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
	}

	if (symbol__init() < 0)
		return -1;
		goto error;

	setup_sorting(report_usage, options);

	if (parent_pattern != default_parent_pattern) {
		if (sort_dimension__add("parent") < 0)
			return -1;
			goto error;

		/*
		 * Only show the parent fields if we explicitly
@@ -685,5 +700,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
	sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list, "comm", stdout);
	sort_entry__setup_elide(&sort_sym, symbol_conf.sym_list, "symbol", stdout);

	return __cmd_report(&report);
	ret = __cmd_report(&report);
error:
	perf_session__delete(session);
	return ret;
}
+1 −1
Original line number Diff line number Diff line
@@ -8,7 +8,7 @@ const char default_sort_order[] = "comm,dso,symbol";
const char	*sort_order = default_sort_order;
int		sort__need_collapse = 0;
int		sort__has_parent = 0;
bool		sort__branch_mode;
int		sort__branch_mode = -1; /* -1 = means not set */

enum sort_type	sort__first_dimension;

+1 −1
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@ extern const char *parent_pattern;
extern const char default_sort_order[];
extern int sort__need_collapse;
extern int sort__has_parent;
extern bool sort__branch_mode;
extern int sort__branch_mode;
extern char *field_sep;
extern struct sort_entry sort_comm;
extern struct sort_entry sort_dso;