diff options
author | Stephane Eranian <eranian@google.com> | 2012-03-08 17:47:47 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2012-03-09 02:26:08 -0500 |
commit | 993ac88d5892629fbe1f8a54857f9947f49f0d96 (patch) | |
tree | 27f23cc95a72be350781803530e09b1535b719e7 /tools/perf/builtin-report.c | |
parent | 330aa675b4f92a422cb6d3acbbfd16a628017520 (diff) |
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@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: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/builtin-report.c')
-rw-r--r-- | tools/perf/builtin-report.c | 50 |
1 files changed, 34 insertions, 16 deletions
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 528789f6c702..66e852376a05 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, | |||
170 | if (rep->cpu_list && !test_bit(sample->cpu, rep->cpu_bitmap)) | 170 | if (rep->cpu_list && !test_bit(sample->cpu, rep->cpu_bitmap)) |
171 | return 0; | 171 | return 0; |
172 | 172 | ||
173 | if (sort__branch_mode) { | 173 | if (sort__branch_mode == 1) { |
174 | if (perf_report__add_branch_hist_entry(tool, &al, sample, | 174 | if (perf_report__add_branch_hist_entry(tool, &al, sample, |
175 | evsel, machine)) { | 175 | evsel, machine)) { |
176 | pr_debug("problem adding lbr entry, skipping event\n"); | 176 | pr_debug("problem adding lbr entry, skipping event\n"); |
@@ -239,7 +239,7 @@ static int perf_report__setup_sample_type(struct perf_report *rep) | |||
239 | } | 239 | } |
240 | } | 240 | } |
241 | 241 | ||
242 | if (sort__branch_mode) { | 242 | if (sort__branch_mode == 1) { |
243 | if (!(self->sample_type & PERF_SAMPLE_BRANCH_STACK)) { | 243 | if (!(self->sample_type & PERF_SAMPLE_BRANCH_STACK)) { |
244 | fprintf(stderr, "selected -b but no branch data." | 244 | fprintf(stderr, "selected -b but no branch data." |
245 | " Did you call perf record without" | 245 | " Did you call perf record without" |
@@ -306,7 +306,7 @@ static int __cmd_report(struct perf_report *rep) | |||
306 | { | 306 | { |
307 | int ret = -EINVAL; | 307 | int ret = -EINVAL; |
308 | u64 nr_samples; | 308 | u64 nr_samples; |
309 | struct perf_session *session; | 309 | struct perf_session *session = rep->session; |
310 | struct perf_evsel *pos; | 310 | struct perf_evsel *pos; |
311 | struct map *kernel_map; | 311 | struct map *kernel_map; |
312 | struct kmap *kernel_kmap; | 312 | struct kmap *kernel_kmap; |
@@ -314,13 +314,6 @@ static int __cmd_report(struct perf_report *rep) | |||
314 | 314 | ||
315 | signal(SIGINT, sig_handler); | 315 | signal(SIGINT, sig_handler); |
316 | 316 | ||
317 | session = perf_session__new(rep->input_name, O_RDONLY, | ||
318 | rep->force, false, &rep->tool); | ||
319 | if (session == NULL) | ||
320 | return -ENOMEM; | ||
321 | |||
322 | rep->session = session; | ||
323 | |||
324 | if (rep->cpu_list) { | 317 | if (rep->cpu_list) { |
325 | ret = perf_session__cpu_bitmap(session, rep->cpu_list, | 318 | ret = perf_session__cpu_bitmap(session, rep->cpu_list, |
326 | rep->cpu_bitmap); | 319 | rep->cpu_bitmap); |
@@ -487,9 +480,19 @@ setup: | |||
487 | return 0; | 480 | return 0; |
488 | } | 481 | } |
489 | 482 | ||
483 | static int | ||
484 | parse_branch_mode(const struct option *opt __used, const char *str __used, int unset) | ||
485 | { | ||
486 | sort__branch_mode = !unset; | ||
487 | return 0; | ||
488 | } | ||
489 | |||
490 | int cmd_report(int argc, const char **argv, const char *prefix __used) | 490 | int cmd_report(int argc, const char **argv, const char *prefix __used) |
491 | { | 491 | { |
492 | struct perf_session *session; | ||
492 | struct stat st; | 493 | struct stat st; |
494 | bool has_br_stack = false; | ||
495 | int ret = -1; | ||
493 | char callchain_default_opt[] = "fractal,0.5,callee"; | 496 | char callchain_default_opt[] = "fractal,0.5,callee"; |
494 | const char * const report_usage[] = { | 497 | const char * const report_usage[] = { |
495 | "perf report [<options>]", | 498 | "perf report [<options>]", |
@@ -578,8 +581,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __used) | |||
578 | "Specify disassembler style (e.g. -M intel for intel syntax)"), | 581 | "Specify disassembler style (e.g. -M intel for intel syntax)"), |
579 | OPT_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period, | 582 | OPT_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period, |
580 | "Show a column with the sum of periods"), | 583 | "Show a column with the sum of periods"), |
581 | OPT_BOOLEAN('b', "branch-stack", &sort__branch_mode, | 584 | OPT_CALLBACK_NOOPT('b', "branch-stack", &sort__branch_mode, "", |
582 | "use branch records for histogram filling"), | 585 | "use branch records for histogram filling", parse_branch_mode), |
583 | OPT_END() | 586 | OPT_END() |
584 | }; | 587 | }; |
585 | 588 | ||
@@ -599,8 +602,20 @@ int cmd_report(int argc, const char **argv, const char *prefix __used) | |||
599 | else | 602 | else |
600 | report.input_name = "perf.data"; | 603 | report.input_name = "perf.data"; |
601 | } | 604 | } |
605 | session = perf_session__new(report.input_name, O_RDONLY, | ||
606 | report.force, false, &report.tool); | ||
607 | if (session == NULL) | ||
608 | return -ENOMEM; | ||
609 | |||
610 | report.session = session; | ||
611 | |||
612 | has_br_stack = perf_header__has_feat(&session->header, | ||
613 | HEADER_BRANCH_STACK); | ||
602 | 614 | ||
603 | if (sort__branch_mode) { | 615 | if (sort__branch_mode == -1 && has_br_stack) |
616 | sort__branch_mode = 1; | ||
617 | |||
618 | if (sort__branch_mode == 1) { | ||
604 | if (use_browser) | 619 | if (use_browser) |
605 | fprintf(stderr, "Warning: TUI interface not supported" | 620 | fprintf(stderr, "Warning: TUI interface not supported" |
606 | " in branch mode\n"); | 621 | " in branch mode\n"); |
@@ -657,13 +672,13 @@ int cmd_report(int argc, const char **argv, const char *prefix __used) | |||
657 | } | 672 | } |
658 | 673 | ||
659 | if (symbol__init() < 0) | 674 | if (symbol__init() < 0) |
660 | return -1; | 675 | goto error; |
661 | 676 | ||
662 | setup_sorting(report_usage, options); | 677 | setup_sorting(report_usage, options); |
663 | 678 | ||
664 | if (parent_pattern != default_parent_pattern) { | 679 | if (parent_pattern != default_parent_pattern) { |
665 | if (sort_dimension__add("parent") < 0) | 680 | if (sort_dimension__add("parent") < 0) |
666 | return -1; | 681 | goto error; |
667 | 682 | ||
668 | /* | 683 | /* |
669 | * Only show the parent fields if we explicitly | 684 | * Only show the parent fields if we explicitly |
@@ -685,5 +700,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __used) | |||
685 | sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list, "comm", stdout); | 700 | sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list, "comm", stdout); |
686 | sort_entry__setup_elide(&sort_sym, symbol_conf.sym_list, "symbol", stdout); | 701 | sort_entry__setup_elide(&sort_sym, symbol_conf.sym_list, "symbol", stdout); |
687 | 702 | ||
688 | return __cmd_report(&report); | 703 | ret = __cmd_report(&report); |
704 | error: | ||
705 | perf_session__delete(session); | ||
706 | return ret; | ||
689 | } | 707 | } |