[tip:perf/hw-branch-sampling] perf report: Auto-detect branch stack sampling mode

From: tip-bot for Stephane Eranian
Date: Fri Mar 09 2012 - 08:35:26 EST


Commit-ID: 993ac88d5892629fbe1f8a54857f9947f49f0d96
Gitweb: http://git.kernel.org/tip/993ac88d5892629fbe1f8a54857f9947f49f0d96
Author: Stephane Eranian <eranian@xxxxxxxxxx>
AuthorDate: Thu, 8 Mar 2012 23:47:47 +0100
Committer: Ingo Molnar <mingo@xxxxxxx>
CommitDate: Fri, 9 Mar 2012 08:26:08 +0100

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: Stephane Eranian <eranian@xxxxxxxxxx>
Cc: peterz@xxxxxxxxxxxxx
Cc: acme@xxxxxxxxxx
Cc: asharma@xxxxxx
Cc: ravitillo@xxxxxxx
Cc: vweaver1@xxxxxxxxxxxx
Cc: khandual@xxxxxxxxxxxxxxxxxx
Cc: dsahern@xxxxxxxxx
Link: http://lkml.kernel.org/r/1331246868-19905-4-git-send-email-eranian@xxxxxxxxxx
Signed-off-by: Ingo Molnar <mingo@xxxxxxx>
---
tools/perf/Documentation/perf-report.txt | 7 +++-
tools/perf/builtin-report.c | 50 ++++++++++++++++++++---------
tools/perf/util/sort.c | 2 +-
tools/perf/util/sort.h | 2 +-
4 files changed, 41 insertions(+), 20 deletions(-)

diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt
index 19b9092..87feeee 100644
--- a/tools/perf/Documentation/perf-report.txt
+++ b/tools/perf/Documentation/perf-report.txt
@@ -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
--------
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 528789f..66e8523 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -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 @@ setup:
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;
}
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 2739ed1..88dbcf6 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -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;

diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 7aa72a0..8505b9b 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -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;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/