diff options
author | Kan Liang <kan.liang@intel.com> | 2015-08-11 06:30:48 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2015-08-12 12:20:28 -0400 |
commit | f9db0d0f1b2cf030083c83d3ed3a4bbae6bdc8b7 (patch) | |
tree | 2410822fb5ac31249097a221c8502ac2889ea100 /tools/perf | |
parent | d457c96392bb418bd998f3ccf93e0e4c958fcd0f (diff) |
perf callchain: Allow disabling call graphs per event
This patch introduce "call-graph=no" to disable per-event callgraph.
Here is an example.
perf record -e 'cpu/cpu-cycles,call-graph=fp/,cpu/instructions,call-graph=no/' sleep 1
perf report --stdio
# To display the perf.data header info, please use
--header/--header-only options.
#
#
# Total Lost Samples: 0
#
# Samples: 6 of event 'cpu/cpu-cycles,call-graph=fp/'
# Event count (approx.): 774218
#
# Children Self Command Shared Object Symbol
# ........ ........ ....... ................ ........................................
#
61.94% 0.00% sleep [kernel.vmlinux] [k] entry_SYSCALL_64_fastpath
|
---entry_SYSCALL_64_fastpath
|
|--97.30%-- __brk
|
--2.70%-- mmap64
_dl_check_map_versions
_dl_check_all_versions
61.94% 0.00% sleep [kernel.vmlinux] [k] perf_event_mmap
|
---perf_event_mmap
|
|--97.30%-- do_brk
| sys_brk
| entry_SYSCALL_64_fastpath
| __brk
|
--2.70%-- mmap_region
do_mmap_pgoff
vm_mmap_pgoff
sys_mmap_pgoff
sys_mmap
entry_SYSCALL_64_fastpath
mmap64
_dl_check_map_versions
_dl_check_all_versions
......
# Samples: 6 of event 'cpu/instructions,call-graph=no/'
# Event count (approx.): 359692
#
# Children Self Command Shared Object Symbol
# ........ ........ ....... ................ .................................
#
89.03% 0.00% sleep [unknown] [.] 0xffff6598ffff6598
89.03% 0.00% sleep ld-2.17.so [.] _dl_resolve_conflicts
89.03% 0.00% sleep [kernel.vmlinux] [k] page_fault
Signed-off-by: Kan Liang <kan.liang@intel.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: http://lkml.kernel.org/r/1439289050-40510-2-git-send-email-kan.liang@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r-- | tools/perf/Documentation/perf-record.txt | 3 | ||||
-rw-r--r-- | tools/perf/builtin-annotate.c | 2 | ||||
-rw-r--r-- | tools/perf/builtin-diff.c | 3 | ||||
-rw-r--r-- | tools/perf/tests/hists_cumulate.c | 4 | ||||
-rw-r--r-- | tools/perf/util/evsel.c | 17 | ||||
-rw-r--r-- | tools/perf/util/hist.c | 9 |
6 files changed, 28 insertions, 10 deletions
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index 7f82dec2b541..347a27322ed8 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt | |||
@@ -54,7 +54,8 @@ OPTIONS | |||
54 | enabling time stamping. 0 for disabling time stamping. | 54 | enabling time stamping. 0 for disabling time stamping. |
55 | The default is 1. | 55 | The default is 1. |
56 | - 'call-graph': Disable/enable callgraph. Acceptable str are "fp" for | 56 | - 'call-graph': Disable/enable callgraph. Acceptable str are "fp" for |
57 | FP mode, "dwarf" for DWARF mode, "lbr" for LBR mode. | 57 | FP mode, "dwarf" for DWARF mode, "lbr" for LBR mode and |
58 | "no" for disable callgraph. | ||
58 | - 'stack-size': user stack size for dwarf mode | 59 | - 'stack-size': user stack size for dwarf mode |
59 | Note: If user explicitly sets options which conflict with the params, | 60 | Note: If user explicitly sets options which conflict with the params, |
60 | the value set by the params will be overridden. | 61 | the value set by the params will be overridden. |
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 467a23b14e2f..a32a64ef08e2 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
@@ -239,6 +239,8 @@ static int __cmd_annotate(struct perf_annotate *ann) | |||
239 | if (nr_samples > 0) { | 239 | if (nr_samples > 0) { |
240 | total_nr_samples += nr_samples; | 240 | total_nr_samples += nr_samples; |
241 | hists__collapse_resort(hists, NULL); | 241 | hists__collapse_resort(hists, NULL); |
242 | /* Don't sort callchain */ | ||
243 | perf_evsel__reset_sample_bit(pos, CALLCHAIN); | ||
242 | hists__output_resort(hists, NULL); | 244 | hists__output_resort(hists, NULL); |
243 | 245 | ||
244 | if (symbol_conf.event_group && | 246 | if (symbol_conf.event_group && |
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index daaa7dca9c3b..0b180a885ba3 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c | |||
@@ -722,6 +722,9 @@ static void data_process(void) | |||
722 | if (verbose || data__files_cnt > 2) | 722 | if (verbose || data__files_cnt > 2) |
723 | data__fprintf(); | 723 | data__fprintf(); |
724 | 724 | ||
725 | /* Don't sort callchain for perf diff */ | ||
726 | perf_evsel__reset_sample_bit(evsel_base, CALLCHAIN); | ||
727 | |||
725 | hists__process(hists_base); | 728 | hists__process(hists_base); |
726 | } | 729 | } |
727 | } | 730 | } |
diff --git a/tools/perf/tests/hists_cumulate.c b/tools/perf/tests/hists_cumulate.c index 7d82c8be5e36..7ed737019de7 100644 --- a/tools/perf/tests/hists_cumulate.c +++ b/tools/perf/tests/hists_cumulate.c | |||
@@ -279,6 +279,7 @@ static int test1(struct perf_evsel *evsel, struct machine *machine) | |||
279 | 279 | ||
280 | symbol_conf.use_callchain = false; | 280 | symbol_conf.use_callchain = false; |
281 | symbol_conf.cumulate_callchain = false; | 281 | symbol_conf.cumulate_callchain = false; |
282 | perf_evsel__reset_sample_bit(evsel, CALLCHAIN); | ||
282 | 283 | ||
283 | setup_sorting(); | 284 | setup_sorting(); |
284 | callchain_register_param(&callchain_param); | 285 | callchain_register_param(&callchain_param); |
@@ -425,6 +426,7 @@ static int test2(struct perf_evsel *evsel, struct machine *machine) | |||
425 | 426 | ||
426 | symbol_conf.use_callchain = true; | 427 | symbol_conf.use_callchain = true; |
427 | symbol_conf.cumulate_callchain = false; | 428 | symbol_conf.cumulate_callchain = false; |
429 | perf_evsel__set_sample_bit(evsel, CALLCHAIN); | ||
428 | 430 | ||
429 | setup_sorting(); | 431 | setup_sorting(); |
430 | callchain_register_param(&callchain_param); | 432 | callchain_register_param(&callchain_param); |
@@ -482,6 +484,7 @@ static int test3(struct perf_evsel *evsel, struct machine *machine) | |||
482 | 484 | ||
483 | symbol_conf.use_callchain = false; | 485 | symbol_conf.use_callchain = false; |
484 | symbol_conf.cumulate_callchain = true; | 486 | symbol_conf.cumulate_callchain = true; |
487 | perf_evsel__reset_sample_bit(evsel, CALLCHAIN); | ||
485 | 488 | ||
486 | setup_sorting(); | 489 | setup_sorting(); |
487 | callchain_register_param(&callchain_param); | 490 | callchain_register_param(&callchain_param); |
@@ -665,6 +668,7 @@ static int test4(struct perf_evsel *evsel, struct machine *machine) | |||
665 | 668 | ||
666 | symbol_conf.use_callchain = true; | 669 | symbol_conf.use_callchain = true; |
667 | symbol_conf.cumulate_callchain = true; | 670 | symbol_conf.cumulate_callchain = true; |
671 | perf_evsel__set_sample_bit(evsel, CALLCHAIN); | ||
668 | 672 | ||
669 | setup_sorting(); | 673 | setup_sorting(); |
670 | callchain_register_param(&callchain_param); | 674 | callchain_register_param(&callchain_param); |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 6647925d5f28..b096ef7a240c 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -651,12 +651,17 @@ static void apply_config_terms(struct perf_evsel *evsel, | |||
651 | 651 | ||
652 | /* parse callgraph parameters */ | 652 | /* parse callgraph parameters */ |
653 | if (callgraph_buf != NULL) { | 653 | if (callgraph_buf != NULL) { |
654 | param.enabled = true; | 654 | if (!strcmp(callgraph_buf, "no")) { |
655 | if (parse_callchain_record(callgraph_buf, ¶m)) { | 655 | param.enabled = false; |
656 | pr_err("per-event callgraph setting for %s failed. " | 656 | param.record_mode = CALLCHAIN_NONE; |
657 | "Apply callgraph global setting for it\n", | 657 | } else { |
658 | evsel->name); | 658 | param.enabled = true; |
659 | return; | 659 | if (parse_callchain_record(callgraph_buf, ¶m)) { |
660 | pr_err("per-event callgraph setting for %s failed. " | ||
661 | "Apply callgraph global setting for it\n", | ||
662 | evsel->name); | ||
663 | return; | ||
664 | } | ||
660 | } | 665 | } |
661 | } | 666 | } |
662 | if (dump_size > 0) { | 667 | if (dump_size > 0) { |
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 6bccfae334b1..1cd785b5b56e 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
@@ -1109,13 +1109,14 @@ void hists__inc_stats(struct hists *hists, struct hist_entry *h) | |||
1109 | 1109 | ||
1110 | static void __hists__insert_output_entry(struct rb_root *entries, | 1110 | static void __hists__insert_output_entry(struct rb_root *entries, |
1111 | struct hist_entry *he, | 1111 | struct hist_entry *he, |
1112 | u64 min_callchain_hits) | 1112 | u64 min_callchain_hits, |
1113 | bool use_callchain) | ||
1113 | { | 1114 | { |
1114 | struct rb_node **p = &entries->rb_node; | 1115 | struct rb_node **p = &entries->rb_node; |
1115 | struct rb_node *parent = NULL; | 1116 | struct rb_node *parent = NULL; |
1116 | struct hist_entry *iter; | 1117 | struct hist_entry *iter; |
1117 | 1118 | ||
1118 | if (symbol_conf.use_callchain) | 1119 | if (use_callchain) |
1119 | callchain_param.sort(&he->sorted_chain, he->callchain, | 1120 | callchain_param.sort(&he->sorted_chain, he->callchain, |
1120 | min_callchain_hits, &callchain_param); | 1121 | min_callchain_hits, &callchain_param); |
1121 | 1122 | ||
@@ -1139,6 +1140,8 @@ void hists__output_resort(struct hists *hists, struct ui_progress *prog) | |||
1139 | struct rb_node *next; | 1140 | struct rb_node *next; |
1140 | struct hist_entry *n; | 1141 | struct hist_entry *n; |
1141 | u64 min_callchain_hits; | 1142 | u64 min_callchain_hits; |
1143 | struct perf_evsel *evsel = hists_to_evsel(hists); | ||
1144 | bool use_callchain = evsel ? (evsel->attr.sample_type & PERF_SAMPLE_CALLCHAIN) : symbol_conf.use_callchain; | ||
1142 | 1145 | ||
1143 | min_callchain_hits = hists->stats.total_period * (callchain_param.min_percent / 100); | 1146 | min_callchain_hits = hists->stats.total_period * (callchain_param.min_percent / 100); |
1144 | 1147 | ||
@@ -1157,7 +1160,7 @@ void hists__output_resort(struct hists *hists, struct ui_progress *prog) | |||
1157 | n = rb_entry(next, struct hist_entry, rb_node_in); | 1160 | n = rb_entry(next, struct hist_entry, rb_node_in); |
1158 | next = rb_next(&n->rb_node_in); | 1161 | next = rb_next(&n->rb_node_in); |
1159 | 1162 | ||
1160 | __hists__insert_output_entry(&hists->entries, n, min_callchain_hits); | 1163 | __hists__insert_output_entry(&hists->entries, n, min_callchain_hits, use_callchain); |
1161 | hists__inc_stats(hists, n); | 1164 | hists__inc_stats(hists, n); |
1162 | 1165 | ||
1163 | if (!n->filtered) | 1166 | if (!n->filtered) |