Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Kan Liang and committed by
Arnaldo Carvalho de Melo
f9db0d0f d457c963

+28 -10
+2 -1
tools/perf/Documentation/perf-record.txt
··· 54 54 enabling time stamping. 0 for disabling time stamping. 55 55 The default is 1. 56 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 59 - 'stack-size': user stack size for dwarf mode 59 60 Note: If user explicitly sets options which conflict with the params, 60 61 the value set by the params will be overridden.
+2
tools/perf/builtin-annotate.c
··· 239 239 if (nr_samples > 0) { 240 240 total_nr_samples += nr_samples; 241 241 hists__collapse_resort(hists, NULL); 242 + /* Don't sort callchain */ 243 + perf_evsel__reset_sample_bit(pos, CALLCHAIN); 242 244 hists__output_resort(hists, NULL); 243 245 244 246 if (symbol_conf.event_group &&
+3
tools/perf/builtin-diff.c
··· 722 722 if (verbose || data__files_cnt > 2) 723 723 data__fprintf(); 724 724 725 + /* Don't sort callchain for perf diff */ 726 + perf_evsel__reset_sample_bit(evsel_base, CALLCHAIN); 727 + 725 728 hists__process(hists_base); 726 729 } 727 730 }
+4
tools/perf/tests/hists_cumulate.c
··· 279 279 280 280 symbol_conf.use_callchain = false; 281 281 symbol_conf.cumulate_callchain = false; 282 + perf_evsel__reset_sample_bit(evsel, CALLCHAIN); 282 283 283 284 setup_sorting(); 284 285 callchain_register_param(&callchain_param); ··· 426 425 427 426 symbol_conf.use_callchain = true; 428 427 symbol_conf.cumulate_callchain = false; 428 + perf_evsel__set_sample_bit(evsel, CALLCHAIN); 429 429 430 430 setup_sorting(); 431 431 callchain_register_param(&callchain_param); ··· 484 482 485 483 symbol_conf.use_callchain = false; 486 484 symbol_conf.cumulate_callchain = true; 485 + perf_evsel__reset_sample_bit(evsel, CALLCHAIN); 487 486 488 487 setup_sorting(); 489 488 callchain_register_param(&callchain_param); ··· 668 665 669 666 symbol_conf.use_callchain = true; 670 667 symbol_conf.cumulate_callchain = true; 668 + perf_evsel__set_sample_bit(evsel, CALLCHAIN); 671 669 672 670 setup_sorting(); 673 671 callchain_register_param(&callchain_param);
+11 -6
tools/perf/util/evsel.c
··· 651 651 652 652 /* parse callgraph parameters */ 653 653 if (callgraph_buf != NULL) { 654 - param.enabled = true; 655 - if (parse_callchain_record(callgraph_buf, &param)) { 656 - pr_err("per-event callgraph setting for %s failed. " 657 - "Apply callgraph global setting for it\n", 658 - evsel->name); 659 - return; 654 + if (!strcmp(callgraph_buf, "no")) { 655 + param.enabled = false; 656 + param.record_mode = CALLCHAIN_NONE; 657 + } else { 658 + param.enabled = true; 659 + if (parse_callchain_record(callgraph_buf, &param)) { 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 667 if (dump_size > 0) {
+6 -3
tools/perf/util/hist.c
··· 1109 1109 1110 1110 static void __hists__insert_output_entry(struct rb_root *entries, 1111 1111 struct hist_entry *he, 1112 - u64 min_callchain_hits) 1112 + u64 min_callchain_hits, 1113 + bool use_callchain) 1113 1114 { 1114 1115 struct rb_node **p = &entries->rb_node; 1115 1116 struct rb_node *parent = NULL; 1116 1117 struct hist_entry *iter; 1117 1118 1118 - if (symbol_conf.use_callchain) 1119 + if (use_callchain) 1119 1120 callchain_param.sort(&he->sorted_chain, he->callchain, 1120 1121 min_callchain_hits, &callchain_param); 1121 1122 ··· 1140 1139 struct rb_node *next; 1141 1140 struct hist_entry *n; 1142 1141 u64 min_callchain_hits; 1142 + struct perf_evsel *evsel = hists_to_evsel(hists); 1143 + bool use_callchain = evsel ? (evsel->attr.sample_type & PERF_SAMPLE_CALLCHAIN) : symbol_conf.use_callchain; 1143 1144 1144 1145 min_callchain_hits = hists->stats.total_period * (callchain_param.min_percent / 100); 1145 1146 ··· 1160 1157 n = rb_entry(next, struct hist_entry, rb_node_in); 1161 1158 next = rb_next(&n->rb_node_in); 1162 1159 1163 - __hists__insert_output_entry(&hists->entries, n, min_callchain_hits); 1160 + __hists__insert_output_entry(&hists->entries, n, min_callchain_hits, use_callchain); 1164 1161 hists__inc_stats(hists, n); 1165 1162 1166 1163 if (!n->filtered)