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

perf tools: Set the maximum allowed stack from /proc/sys/kernel/perf_event_max_stack

There is an upper limit to what tooling considers a valid callchain,
and it was tied to the hardcoded value in the kernel,
PERF_MAX_STACK_DEPTH (127), now that this can be tuned via a sysctl,
make it read it and use that as the upper limit, falling back to
PERF_MAX_STACK_DEPTH for kernels where this sysctl isn't present.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Milian Wolff <milian.wolff@kdab.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/n/tip-yjqsd30nnkogvj5oyx9ghir9@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

+28 -18
+1 -1
tools/perf/Documentation/perf-report.txt
··· 248 248 Note that when using the --itrace option the synthesized callchain size 249 249 will override this value if the synthesized callchain size is bigger. 250 250 251 - Default: 127 251 + Default: /proc/sys/kernel/perf_event_max_stack when present, 127 otherwise. 252 252 253 253 -G:: 254 254 --inverted::
+1 -1
tools/perf/Documentation/perf-script.txt
··· 267 267 Note that when using the --itrace option the synthesized callchain size 268 268 will override this value if the synthesized callchain size is bigger. 269 269 270 - Default: 127 270 + Default: /proc/sys/kernel/perf_event_max_stack when present, 127 otherwise. 271 271 272 272 --ns:: 273 273 Use 9 decimal places when displaying time (i.e. show the nanoseconds)
+1 -1
tools/perf/Documentation/perf-top.txt
··· 177 177 between information loss and faster processing especially for 178 178 workloads that can have a very long callchain stack. 179 179 180 - Default: 127 180 + Default: /proc/sys/kernel/perf_event_max_stack when present, 127 otherwise. 181 181 182 182 --ignore-callees=<regex>:: 183 183 Ignore callees of the function(s) matching the given regex.
+1 -1
tools/perf/Documentation/perf-trace.txt
··· 143 143 Implies '--call-graph dwarf' when --call-graph not present on the 144 144 command line, on systems where DWARF unwinding was built in. 145 145 146 - Default: 127 146 + Default: /proc/sys/kernel/perf_event_max_stack when present, 127 otherwise. 147 147 148 148 --min-stack:: 149 149 Set the stack depth limit when parsing the callchain, anything
+2 -2
tools/perf/builtin-report.c
··· 691 691 .ordered_events = true, 692 692 .ordering_requires_timestamps = true, 693 693 }, 694 - .max_stack = PERF_MAX_STACK_DEPTH, 694 + .max_stack = sysctl_perf_event_max_stack, 695 695 .pretty_printing_style = "normal", 696 696 .socket_filter = -1, 697 697 }; ··· 744 744 OPT_INTEGER(0, "max-stack", &report.max_stack, 745 745 "Set the maximum stack depth when parsing the callchain, " 746 746 "anything beyond the specified depth will be ignored. " 747 - "Default: " __stringify(PERF_MAX_STACK_DEPTH)), 747 + "Default: kernel.perf_event_max_stack or " __stringify(PERF_MAX_STACK_DEPTH)), 748 748 OPT_BOOLEAN('G', "inverted", &report.inverted_callchain, 749 749 "alias for inverted call graph"), 750 750 OPT_CALLBACK(0, "ignore-callees", NULL, "regex",
+3 -1
tools/perf/builtin-script.c
··· 2031 2031 OPT_UINTEGER(0, "max-stack", &scripting_max_stack, 2032 2032 "Set the maximum stack depth when parsing the callchain, " 2033 2033 "anything beyond the specified depth will be ignored. " 2034 - "Default: " __stringify(PERF_MAX_STACK_DEPTH)), 2034 + "Default: kernel.perf_event_max_stack or " __stringify(PERF_MAX_STACK_DEPTH)), 2035 2035 OPT_BOOLEAN('I', "show-info", &show_full_info, 2036 2036 "display extended information from perf.data file"), 2037 2037 OPT_BOOLEAN('\0', "show-kernel-path", &symbol_conf.show_kernel_path, ··· 2066 2066 "perf script [<options>] <top-script> [script-args]", 2067 2067 NULL 2068 2068 }; 2069 + 2070 + scripting_max_stack = sysctl_perf_event_max_stack; 2069 2071 2070 2072 setup_scripting(); 2071 2073
+2 -2
tools/perf/builtin-top.c
··· 1103 1103 }, 1104 1104 .proc_map_timeout = 500, 1105 1105 }, 1106 - .max_stack = PERF_MAX_STACK_DEPTH, 1106 + .max_stack = sysctl_perf_event_max_stack, 1107 1107 .sym_pcnt_filter = 5, 1108 1108 }; 1109 1109 struct record_opts *opts = &top.record_opts; ··· 1171 1171 "Accumulate callchains of children and show total overhead as well"), 1172 1172 OPT_INTEGER(0, "max-stack", &top.max_stack, 1173 1173 "Set the maximum stack depth when parsing the callchain. " 1174 - "Default: " __stringify(PERF_MAX_STACK_DEPTH)), 1174 + "Default: kernel.perf_event_max_stack or " __stringify(PERF_MAX_STACK_DEPTH)), 1175 1175 OPT_CALLBACK(0, "ignore-callees", NULL, "regex", 1176 1176 "ignore callees of these functions in call graphs", 1177 1177 report_parse_ignore_callees_opt),
+2 -2
tools/perf/builtin-trace.c
··· 3106 3106 OPT_UINTEGER(0, "max-stack", &trace.max_stack, 3107 3107 "Set the maximum stack depth when parsing the callchain, " 3108 3108 "anything beyond the specified depth will be ignored. " 3109 - "Default: " __stringify(PERF_MAX_STACK_DEPTH)), 3109 + "Default: kernel.perf_event_max_stack or " __stringify(PERF_MAX_STACK_DEPTH)), 3110 3110 OPT_UINTEGER(0, "proc-map-timeout", &trace.opts.proc_map_timeout, 3111 3111 "per thread proc mmap processing timeout in ms"), 3112 3112 OPT_END() ··· 3150 3150 mmap_pages_user_set = false; 3151 3151 3152 3152 if (trace.max_stack == UINT_MAX) { 3153 - trace.max_stack = PERF_MAX_STACK_DEPTH; 3153 + trace.max_stack = sysctl_perf_event_max_stack; 3154 3154 max_stack_user_set = false; 3155 3155 } 3156 3156
+5
tools/perf/perf.c
··· 17 17 #include <subcmd/parse-options.h> 18 18 #include "util/bpf-loader.h" 19 19 #include "util/debug.h" 20 + #include <api/fs/fs.h> 20 21 #include <api/fs/tracing_path.h> 21 22 #include <pthread.h> 22 23 #include <stdlib.h> ··· 534 533 { 535 534 const char *cmd; 536 535 char sbuf[STRERR_BUFSIZE]; 536 + int value; 537 537 538 538 /* libsubcmd init */ 539 539 exec_cmd_init("perf", PREFIX, PERF_EXEC_PATH, EXEC_PATH_ENVIRONMENT); ··· 543 541 /* The page_size is placed in util object. */ 544 542 page_size = sysconf(_SC_PAGE_SIZE); 545 543 cacheline_size = sysconf(_SC_LEVEL1_DCACHE_LINESIZE); 544 + 545 + if (sysctl__read_int("kernel/perf_event_max_stack", &value) == 0) 546 + sysctl_perf_event_max_stack = value; 546 547 547 548 cmd = extract_argv0_path(argv[0]); 548 549 if (!cmd)
+1 -1
tools/perf/tests/hists_cumulate.c
··· 101 101 if (machine__resolve(machine, &al, &sample) < 0) 102 102 goto out; 103 103 104 - if (hist_entry_iter__add(&iter, &al, PERF_MAX_STACK_DEPTH, 104 + if (hist_entry_iter__add(&iter, &al, sysctl_perf_event_max_stack, 105 105 NULL) < 0) { 106 106 addr_location__put(&al); 107 107 goto out;
+1 -1
tools/perf/tests/hists_filter.c
··· 81 81 82 82 al.socket = fake_samples[i].socket; 83 83 if (hist_entry_iter__add(&iter, &al, 84 - PERF_MAX_STACK_DEPTH, NULL) < 0) { 84 + sysctl_perf_event_max_stack, NULL) < 0) { 85 85 addr_location__put(&al); 86 86 goto out; 87 87 }
+1 -1
tools/perf/tests/hists_output.c
··· 67 67 if (machine__resolve(machine, &al, &sample) < 0) 68 68 goto out; 69 69 70 - if (hist_entry_iter__add(&iter, &al, PERF_MAX_STACK_DEPTH, 70 + if (hist_entry_iter__add(&iter, &al, sysctl_perf_event_max_stack, 71 71 NULL) < 0) { 72 72 addr_location__put(&al); 73 73 goto out;
+3 -3
tools/perf/util/machine.c
··· 1764 1764 */ 1765 1765 int mix_chain_nr = i + 1 + lbr_nr + 1; 1766 1766 1767 - if (mix_chain_nr > PERF_MAX_STACK_DEPTH + PERF_MAX_BRANCH_DEPTH) { 1767 + if (mix_chain_nr > (int)sysctl_perf_event_max_stack + PERF_MAX_BRANCH_DEPTH) { 1768 1768 pr_warning("corrupted callchain. skipping...\n"); 1769 1769 return 0; 1770 1770 } ··· 1825 1825 * Based on DWARF debug information, some architectures skip 1826 1826 * a callchain entry saved by the kernel. 1827 1827 */ 1828 - if (chain->nr < PERF_MAX_STACK_DEPTH) 1828 + if (chain->nr < sysctl_perf_event_max_stack) 1829 1829 skip_idx = arch_skip_callchain_idx(thread, chain); 1830 1830 1831 1831 /* ··· 1886 1886 } 1887 1887 1888 1888 check_calls: 1889 - if (chain->nr > PERF_MAX_STACK_DEPTH && (int)chain->nr > max_stack) { 1889 + if (chain->nr > sysctl_perf_event_max_stack && (int)chain->nr > max_stack) { 1890 1890 pr_warning("corrupted callchain. skipping...\n"); 1891 1891 return 0; 1892 1892 }
+1 -1
tools/perf/util/scripting-engines/trace-event-perl.c
··· 265 265 266 266 if (thread__resolve_callchain(al->thread, &callchain_cursor, evsel, 267 267 sample, NULL, NULL, 268 - PERF_MAX_STACK_DEPTH) != 0) { 268 + sysctl_perf_event_max_stack) != 0) { 269 269 pr_err("Failed to resolve callchain. Skipping\n"); 270 270 goto exit; 271 271 }
+2
tools/perf/util/util.c
··· 33 33 unsigned int page_size; 34 34 int cacheline_size; 35 35 36 + unsigned int sysctl_perf_event_max_stack = PERF_MAX_STACK_DEPTH; 37 + 36 38 bool test_attr__enabled; 37 39 38 40 bool perf_host = true;
+1
tools/perf/util/util.h
··· 267 267 268 268 extern unsigned int page_size; 269 269 extern int cacheline_size; 270 + extern unsigned int sysctl_perf_event_max_stack; 270 271 271 272 struct parse_tag { 272 273 char tag;