diff options
author | Ingo Molnar <mingo@kernel.org> | 2015-10-23 04:25:57 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2015-10-23 04:25:57 -0400 |
commit | 80fcd45ee05b4ef05e61d37a5ffb70a67095a9f6 (patch) | |
tree | eee276fd27aeae2e92e2aff91cb4a3af87a792fa /tools/perf | |
parent | 4ba792e303e278052bb0ee60cce15d6d7dc15c7c (diff) | |
parent | f06cff7c59b6b252d667435d7baad48687b41002 (diff) |
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:
User visible changes:
- The default for callchains is back to 'callee' when --children is not used.
(Namhyung Kim)
- Move the 'use_offset' option to the right place where the annotate code
expects it to be to be able to properly handle it. (Namhyung Kim)
- Don't die when an unknown 'annotate' option is found in the perf config
file (usually ~/.perfconfig), just warn the user. (Arnaldo Carvalho de Melo)
Infrastructure changes:
- Support %ps/%pS in libtraceevent. (Scott Wood)
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf')
-rw-r--r-- | tools/perf/Documentation/perf-record.txt | 9 | ||||
-rw-r--r-- | tools/perf/Documentation/perf-report.txt | 38 | ||||
-rw-r--r-- | tools/perf/Documentation/perf-top.txt | 5 | ||||
-rw-r--r-- | tools/perf/builtin-record.c | 11 | ||||
-rw-r--r-- | tools/perf/builtin-report.c | 17 | ||||
-rw-r--r-- | tools/perf/builtin-top.c | 30 | ||||
-rw-r--r-- | tools/perf/ui/browsers/annotate.c | 8 | ||||
-rw-r--r-- | tools/perf/ui/tui/setup.c | 8 | ||||
-rw-r--r-- | tools/perf/util/callchain.c | 42 | ||||
-rw-r--r-- | tools/perf/util/callchain.h | 26 | ||||
-rw-r--r-- | tools/perf/util/util.c | 2 |
11 files changed, 149 insertions, 47 deletions
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index b027d28658f2..7ff6a9d0ea0d 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt | |||
@@ -144,7 +144,7 @@ OPTIONS | |||
144 | 144 | ||
145 | --call-graph:: | 145 | --call-graph:: |
146 | Setup and enable call-graph (stack chain/backtrace) recording, | 146 | Setup and enable call-graph (stack chain/backtrace) recording, |
147 | implies -g. | 147 | implies -g. Default is "fp". |
148 | 148 | ||
149 | Allows specifying "fp" (frame pointer) or "dwarf" | 149 | Allows specifying "fp" (frame pointer) or "dwarf" |
150 | (DWARF's CFI - Call Frame Information) or "lbr" | 150 | (DWARF's CFI - Call Frame Information) or "lbr" |
@@ -154,13 +154,18 @@ OPTIONS | |||
154 | In some systems, where binaries are build with gcc | 154 | In some systems, where binaries are build with gcc |
155 | --fomit-frame-pointer, using the "fp" method will produce bogus | 155 | --fomit-frame-pointer, using the "fp" method will produce bogus |
156 | call graphs, using "dwarf", if available (perf tools linked to | 156 | call graphs, using "dwarf", if available (perf tools linked to |
157 | the libunwind library) should be used instead. | 157 | the libunwind or libdw library) should be used instead. |
158 | Using the "lbr" method doesn't require any compiler options. It | 158 | Using the "lbr" method doesn't require any compiler options. It |
159 | will produce call graphs from the hardware LBR registers. The | 159 | will produce call graphs from the hardware LBR registers. The |
160 | main limition is that it is only available on new Intel | 160 | main limition is that it is only available on new Intel |
161 | platforms, such as Haswell. It can only get user call chain. It | 161 | platforms, such as Haswell. It can only get user call chain. It |
162 | doesn't work with branch stack sampling at the same time. | 162 | doesn't work with branch stack sampling at the same time. |
163 | 163 | ||
164 | When "dwarf" recording is used, perf also records (user) stack dump | ||
165 | when sampled. Default size of the stack dump is 8192 (bytes). | ||
166 | User can change the size by passing the size after comma like | ||
167 | "--call-graph dwarf,4096". | ||
168 | |||
164 | -q:: | 169 | -q:: |
165 | --quiet:: | 170 | --quiet:: |
166 | Don't print any message, useful for scripting. | 171 | Don't print any message, useful for scripting. |
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index e4fdeeb51123..ab1fd64e3627 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt | |||
@@ -169,30 +169,40 @@ OPTIONS | |||
169 | --dump-raw-trace:: | 169 | --dump-raw-trace:: |
170 | Dump raw trace in ASCII. | 170 | Dump raw trace in ASCII. |
171 | 171 | ||
172 | -g [type,min[,limit],order[,key][,branch]]:: | 172 | -g:: |
173 | --call-graph:: | 173 | --call-graph=<print_type,threshold[,print_limit],order,sort_key,branch>:: |
174 | Display call chains using type, min percent threshold, optional print | 174 | Display call chains using type, min percent threshold, print limit, |
175 | limit and order. | 175 | call order, sort key and branch. Note that ordering of parameters is not |
176 | type can be either: | 176 | fixed so any parement can be given in an arbitraty order. One exception |
177 | is the print_limit which should be preceded by threshold. | ||
178 | |||
179 | print_type can be either: | ||
177 | - flat: single column, linear exposure of call chains. | 180 | - flat: single column, linear exposure of call chains. |
178 | - graph: use a graph tree, displaying absolute overhead rates. | 181 | - graph: use a graph tree, displaying absolute overhead rates. (default) |
179 | - fractal: like graph, but displays relative rates. Each branch of | 182 | - fractal: like graph, but displays relative rates. Each branch of |
180 | the tree is considered as a new profiled object. + | 183 | the tree is considered as a new profiled object. |
184 | - none: disable call chain display. | ||
185 | |||
186 | threshold is a percentage value which specifies a minimum percent to be | ||
187 | included in the output call graph. Default is 0.5 (%). | ||
188 | |||
189 | print_limit is only applied when stdio interface is used. It's to limit | ||
190 | number of call graph entries in a single hist entry. Note that it needs | ||
191 | to be given after threshold (but not necessarily consecutive). | ||
192 | Default is 0 (unlimited). | ||
181 | 193 | ||
182 | order can be either: | 194 | order can be either: |
183 | - callee: callee based call graph. | 195 | - callee: callee based call graph. |
184 | - caller: inverted caller based call graph. | 196 | - caller: inverted caller based call graph. |
197 | Default is 'caller' when --children is used, otherwise 'callee'. | ||
185 | 198 | ||
186 | key can be: | 199 | sort_key can be: |
187 | - function: compare on functions | 200 | - function: compare on functions (default) |
188 | - address: compare on individual code addresses | 201 | - address: compare on individual code addresses |
189 | 202 | ||
190 | branch can be: | 203 | branch can be: |
191 | - branch: include last branch information in callgraph | 204 | - branch: include last branch information in callgraph when available. |
192 | when available. Usually more convenient to use --branch-history | 205 | Usually more convenient to use --branch-history for this. |
193 | for this. | ||
194 | |||
195 | Default: graph,0.5,caller | ||
196 | 206 | ||
197 | --children:: | 207 | --children:: |
198 | Accumulate callchain of children to parent entry so that then can | 208 | Accumulate callchain of children to parent entry so that then can |
diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt index f6a23eb294e7..556cec09bf50 100644 --- a/tools/perf/Documentation/perf-top.txt +++ b/tools/perf/Documentation/perf-top.txt | |||
@@ -160,9 +160,10 @@ Default is to monitor all CPUS. | |||
160 | -g:: | 160 | -g:: |
161 | Enables call-graph (stack chain/backtrace) recording. | 161 | Enables call-graph (stack chain/backtrace) recording. |
162 | 162 | ||
163 | --call-graph:: | 163 | --call-graph [mode,type,min[,limit],order[,key][,branch]]:: |
164 | Setup and enable call-graph (stack chain/backtrace) recording, | 164 | Setup and enable call-graph (stack chain/backtrace) recording, |
165 | implies -g. | 165 | implies -g. See `--call-graph` section in perf-record and |
166 | perf-report man pages for details. | ||
166 | 167 | ||
167 | --children:: | 168 | --children:: |
168 | Accumulate callchain of children to parent entry so that then can | 169 | Accumulate callchain of children to parent entry so that then can |
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 24ace2f318c1..2740d7a82ae8 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -1010,13 +1010,8 @@ static struct record record = { | |||
1010 | }, | 1010 | }, |
1011 | }; | 1011 | }; |
1012 | 1012 | ||
1013 | #define CALLCHAIN_HELP "setup and enables call-graph (stack chain/backtrace) recording: " | 1013 | const char record_callchain_help[] = CALLCHAIN_RECORD_HELP |
1014 | 1014 | "\n\t\t\t\tDefault: fp"; | |
1015 | #ifdef HAVE_DWARF_UNWIND_SUPPORT | ||
1016 | const char record_callchain_help[] = CALLCHAIN_HELP "fp dwarf lbr"; | ||
1017 | #else | ||
1018 | const char record_callchain_help[] = CALLCHAIN_HELP "fp lbr"; | ||
1019 | #endif | ||
1020 | 1015 | ||
1021 | /* | 1016 | /* |
1022 | * XXX Will stay a global variable till we fix builtin-script.c to stop messing | 1017 | * XXX Will stay a global variable till we fix builtin-script.c to stop messing |
@@ -1064,7 +1059,7 @@ struct option __record_options[] = { | |||
1064 | NULL, "enables call-graph recording" , | 1059 | NULL, "enables call-graph recording" , |
1065 | &record_callchain_opt), | 1060 | &record_callchain_opt), |
1066 | OPT_CALLBACK(0, "call-graph", &record.opts, | 1061 | OPT_CALLBACK(0, "call-graph", &record.opts, |
1067 | "mode[,dump_size]", record_callchain_help, | 1062 | "record_mode[,record_size]", record_callchain_help, |
1068 | &record_parse_callchain_opt), | 1063 | &record_parse_callchain_opt), |
1069 | OPT_INCR('v', "verbose", &verbose, | 1064 | OPT_INCR('v', "verbose", &verbose, |
1070 | "be more verbose (show counter open errors, etc)"), | 1065 | "be more verbose (show counter open errors, etc)"), |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 3b23b25d1589..50dd4d3d8667 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -625,6 +625,12 @@ parse_percent_limit(const struct option *opt, const char *str, | |||
625 | return 0; | 625 | return 0; |
626 | } | 626 | } |
627 | 627 | ||
628 | #define CALLCHAIN_DEFAULT_OPT "graph,0.5,caller,function" | ||
629 | |||
630 | const char report_callchain_help[] = "Display call graph (stack chain/backtrace):\n\n" | ||
631 | CALLCHAIN_REPORT_HELP | ||
632 | "\n\t\t\t\tDefault: " CALLCHAIN_DEFAULT_OPT; | ||
633 | |||
628 | int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) | 634 | int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) |
629 | { | 635 | { |
630 | struct perf_session *session; | 636 | struct perf_session *session; |
@@ -633,7 +639,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) | |||
633 | bool has_br_stack = false; | 639 | bool has_br_stack = false; |
634 | int branch_mode = -1; | 640 | int branch_mode = -1; |
635 | bool branch_call_mode = false; | 641 | bool branch_call_mode = false; |
636 | char callchain_default_opt[] = "graph,0.5,caller"; | 642 | char callchain_default_opt[] = CALLCHAIN_DEFAULT_OPT; |
637 | const char * const report_usage[] = { | 643 | const char * const report_usage[] = { |
638 | "perf report [<options>]", | 644 | "perf report [<options>]", |
639 | NULL | 645 | NULL |
@@ -699,9 +705,10 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) | |||
699 | "regex filter to identify parent, see: '--sort parent'"), | 705 | "regex filter to identify parent, see: '--sort parent'"), |
700 | OPT_BOOLEAN('x', "exclude-other", &symbol_conf.exclude_other, | 706 | OPT_BOOLEAN('x', "exclude-other", &symbol_conf.exclude_other, |
701 | "Only display entries with parent-match"), | 707 | "Only display entries with parent-match"), |
702 | OPT_CALLBACK_DEFAULT('g', "call-graph", &report, "output_type,min_percent[,print_limit],call_order[,branch]", | 708 | OPT_CALLBACK_DEFAULT('g', "call-graph", &report, |
703 | "Display callchains using output_type (graph, flat, fractal, or none) , min percent threshold, optional print limit, callchain order, key (function or address), add branches. " | 709 | "print_type,threshold[,print_limit],order,sort_key[,branch]", |
704 | "Default: graph,0.5,caller", &report_parse_callchain_opt, callchain_default_opt), | 710 | report_callchain_help, &report_parse_callchain_opt, |
711 | callchain_default_opt), | ||
705 | OPT_BOOLEAN(0, "children", &symbol_conf.cumulate_callchain, | 712 | OPT_BOOLEAN(0, "children", &symbol_conf.cumulate_callchain, |
706 | "Accumulate callchains of children and show total overhead as well"), | 713 | "Accumulate callchains of children and show total overhead as well"), |
707 | OPT_INTEGER(0, "max-stack", &report.max_stack, | 714 | OPT_INTEGER(0, "max-stack", &report.max_stack, |
@@ -808,6 +815,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) | |||
808 | 815 | ||
809 | if (report.inverted_callchain) | 816 | if (report.inverted_callchain) |
810 | callchain_param.order = ORDER_CALLER; | 817 | callchain_param.order = ORDER_CALLER; |
818 | if (symbol_conf.cumulate_callchain && !callchain_param.order_set) | ||
819 | callchain_param.order = ORDER_CALLER; | ||
811 | 820 | ||
812 | if (itrace_synth_opts.callchain && | 821 | if (itrace_synth_opts.callchain && |
813 | (int)itrace_synth_opts.callchain_sz > report.max_stack) | 822 | (int)itrace_synth_opts.callchain_sz > report.max_stack) |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 6f641fd68296..7e2e72e6d9d1 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -1053,8 +1053,22 @@ callchain_opt(const struct option *opt, const char *arg, int unset) | |||
1053 | static int | 1053 | static int |
1054 | parse_callchain_opt(const struct option *opt, const char *arg, int unset) | 1054 | parse_callchain_opt(const struct option *opt, const char *arg, int unset) |
1055 | { | 1055 | { |
1056 | symbol_conf.use_callchain = true; | 1056 | struct record_opts *record = (struct record_opts *)opt->value; |
1057 | return record_parse_callchain_opt(opt, arg, unset); | 1057 | |
1058 | record->callgraph_set = true; | ||
1059 | callchain_param.enabled = !unset; | ||
1060 | callchain_param.record_mode = CALLCHAIN_FP; | ||
1061 | |||
1062 | /* | ||
1063 | * --no-call-graph | ||
1064 | */ | ||
1065 | if (unset) { | ||
1066 | symbol_conf.use_callchain = false; | ||
1067 | callchain_param.record_mode = CALLCHAIN_NONE; | ||
1068 | return 0; | ||
1069 | } | ||
1070 | |||
1071 | return parse_callchain_top_opt(arg); | ||
1058 | } | 1072 | } |
1059 | 1073 | ||
1060 | static int perf_top_config(const char *var, const char *value, void *cb) | 1074 | static int perf_top_config(const char *var, const char *value, void *cb) |
@@ -1079,6 +1093,9 @@ parse_percent_limit(const struct option *opt, const char *arg, | |||
1079 | return 0; | 1093 | return 0; |
1080 | } | 1094 | } |
1081 | 1095 | ||
1096 | const char top_callchain_help[] = CALLCHAIN_RECORD_HELP CALLCHAIN_REPORT_HELP | ||
1097 | "\n\t\t\t\tDefault: fp,graph,0.5,caller,function"; | ||
1098 | |||
1082 | int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) | 1099 | int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) |
1083 | { | 1100 | { |
1084 | char errbuf[BUFSIZ]; | 1101 | char errbuf[BUFSIZ]; |
@@ -1154,11 +1171,11 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) | |||
1154 | OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples, | 1171 | OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples, |
1155 | "Show a column with the number of samples"), | 1172 | "Show a column with the number of samples"), |
1156 | OPT_CALLBACK_NOOPT('g', NULL, &top.record_opts, | 1173 | OPT_CALLBACK_NOOPT('g', NULL, &top.record_opts, |
1157 | NULL, "enables call-graph recording", | 1174 | NULL, "enables call-graph recording and display", |
1158 | &callchain_opt), | 1175 | &callchain_opt), |
1159 | OPT_CALLBACK(0, "call-graph", &top.record_opts, | 1176 | OPT_CALLBACK(0, "call-graph", &top.record_opts, |
1160 | "mode[,dump_size]", record_callchain_help, | 1177 | "record_mode[,record_size],print_type,threshold[,print_limit],order,sort_key[,branch]", |
1161 | &parse_callchain_opt), | 1178 | top_callchain_help, &parse_callchain_opt), |
1162 | OPT_BOOLEAN(0, "children", &symbol_conf.cumulate_callchain, | 1179 | OPT_BOOLEAN(0, "children", &symbol_conf.cumulate_callchain, |
1163 | "Accumulate callchains of children and show total overhead as well"), | 1180 | "Accumulate callchains of children and show total overhead as well"), |
1164 | OPT_INTEGER(0, "max-stack", &top.max_stack, | 1181 | OPT_INTEGER(0, "max-stack", &top.max_stack, |
@@ -1288,6 +1305,9 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) | |||
1288 | perf_hpp__cancel_cumulate(); | 1305 | perf_hpp__cancel_cumulate(); |
1289 | } | 1306 | } |
1290 | 1307 | ||
1308 | if (symbol_conf.cumulate_callchain && !callchain_param.order_set) | ||
1309 | callchain_param.order = ORDER_CALLER; | ||
1310 | |||
1291 | symbol_conf.priv_size = sizeof(struct annotation); | 1311 | symbol_conf.priv_size = sizeof(struct annotation); |
1292 | 1312 | ||
1293 | symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL); | 1313 | symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL); |
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index bec0b62d8e38..d4d7cc27252f 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c | |||
@@ -1125,8 +1125,8 @@ static struct annotate_config { | |||
1125 | ANNOTATE_CFG(jump_arrows), | 1125 | ANNOTATE_CFG(jump_arrows), |
1126 | ANNOTATE_CFG(show_linenr), | 1126 | ANNOTATE_CFG(show_linenr), |
1127 | ANNOTATE_CFG(show_nr_jumps), | 1127 | ANNOTATE_CFG(show_nr_jumps), |
1128 | ANNOTATE_CFG(use_offset), | ||
1129 | ANNOTATE_CFG(show_total_period), | 1128 | ANNOTATE_CFG(show_total_period), |
1129 | ANNOTATE_CFG(use_offset), | ||
1130 | }; | 1130 | }; |
1131 | 1131 | ||
1132 | #undef ANNOTATE_CFG | 1132 | #undef ANNOTATE_CFG |
@@ -1152,9 +1152,9 @@ static int annotate__config(const char *var, const char *value, | |||
1152 | sizeof(struct annotate_config), annotate_config__cmp); | 1152 | sizeof(struct annotate_config), annotate_config__cmp); |
1153 | 1153 | ||
1154 | if (cfg == NULL) | 1154 | if (cfg == NULL) |
1155 | return -1; | 1155 | ui__warning("%s variable unknown, ignoring...", var); |
1156 | 1156 | else | |
1157 | *cfg->value = perf_config_bool(name, value); | 1157 | *cfg->value = perf_config_bool(name, value); |
1158 | return 0; | 1158 | return 0; |
1159 | } | 1159 | } |
1160 | 1160 | ||
diff --git a/tools/perf/ui/tui/setup.c b/tools/perf/ui/tui/setup.c index 60d1f29b4b50..7dfeba0a91f3 100644 --- a/tools/perf/ui/tui/setup.c +++ b/tools/perf/ui/tui/setup.c | |||
@@ -141,10 +141,6 @@ int ui__init(void) | |||
141 | 141 | ||
142 | SLkp_define_keysym((char *)"^(kB)", SL_KEY_UNTAB); | 142 | SLkp_define_keysym((char *)"^(kB)", SL_KEY_UNTAB); |
143 | 143 | ||
144 | ui_helpline__init(); | ||
145 | ui_browser__init(); | ||
146 | tui_progress__init(); | ||
147 | |||
148 | signal(SIGSEGV, ui__signal_backtrace); | 144 | signal(SIGSEGV, ui__signal_backtrace); |
149 | signal(SIGFPE, ui__signal_backtrace); | 145 | signal(SIGFPE, ui__signal_backtrace); |
150 | signal(SIGINT, ui__signal); | 146 | signal(SIGINT, ui__signal); |
@@ -153,6 +149,10 @@ int ui__init(void) | |||
153 | 149 | ||
154 | perf_error__register(&perf_tui_eops); | 150 | perf_error__register(&perf_tui_eops); |
155 | 151 | ||
152 | ui_helpline__init(); | ||
153 | ui_browser__init(); | ||
154 | tui_progress__init(); | ||
155 | |||
156 | hist_browser__init_hpp(); | 156 | hist_browser__init_hpp(); |
157 | out: | 157 | out: |
158 | return err; | 158 | return err; |
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 773fe13ce627..735ad48e1858 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c | |||
@@ -51,10 +51,12 @@ static int parse_callchain_order(const char *value) | |||
51 | { | 51 | { |
52 | if (!strncmp(value, "caller", strlen(value))) { | 52 | if (!strncmp(value, "caller", strlen(value))) { |
53 | callchain_param.order = ORDER_CALLER; | 53 | callchain_param.order = ORDER_CALLER; |
54 | callchain_param.order_set = true; | ||
54 | return 0; | 55 | return 0; |
55 | } | 56 | } |
56 | if (!strncmp(value, "callee", strlen(value))) { | 57 | if (!strncmp(value, "callee", strlen(value))) { |
57 | callchain_param.order = ORDER_CALLEE; | 58 | callchain_param.order = ORDER_CALLEE; |
59 | callchain_param.order_set = true; | ||
58 | return 0; | 60 | return 0; |
59 | } | 61 | } |
60 | return -1; | 62 | return -1; |
@@ -77,12 +79,14 @@ static int parse_callchain_sort_key(const char *value) | |||
77 | return -1; | 79 | return -1; |
78 | } | 80 | } |
79 | 81 | ||
80 | int | 82 | static int |
81 | parse_callchain_report_opt(const char *arg) | 83 | __parse_callchain_report_opt(const char *arg, bool allow_record_opt) |
82 | { | 84 | { |
83 | char *tok; | 85 | char *tok; |
84 | char *endptr; | 86 | char *endptr; |
85 | bool minpcnt_set = false; | 87 | bool minpcnt_set = false; |
88 | bool record_opt_set = false; | ||
89 | bool try_stack_size = false; | ||
86 | 90 | ||
87 | symbol_conf.use_callchain = true; | 91 | symbol_conf.use_callchain = true; |
88 | 92 | ||
@@ -100,6 +104,28 @@ parse_callchain_report_opt(const char *arg) | |||
100 | !parse_callchain_order(tok) || | 104 | !parse_callchain_order(tok) || |
101 | !parse_callchain_sort_key(tok)) { | 105 | !parse_callchain_sort_key(tok)) { |
102 | /* parsing ok - move on to the next */ | 106 | /* parsing ok - move on to the next */ |
107 | try_stack_size = false; | ||
108 | goto next; | ||
109 | } else if (allow_record_opt && !record_opt_set) { | ||
110 | if (parse_callchain_record(tok, &callchain_param)) | ||
111 | goto try_numbers; | ||
112 | |||
113 | /* assume that number followed by 'dwarf' is stack size */ | ||
114 | if (callchain_param.record_mode == CALLCHAIN_DWARF) | ||
115 | try_stack_size = true; | ||
116 | |||
117 | record_opt_set = true; | ||
118 | goto next; | ||
119 | } | ||
120 | |||
121 | try_numbers: | ||
122 | if (try_stack_size) { | ||
123 | unsigned long size = 0; | ||
124 | |||
125 | if (get_stack_size(tok, &size) < 0) | ||
126 | return -1; | ||
127 | callchain_param.dump_size = size; | ||
128 | try_stack_size = false; | ||
103 | } else if (!minpcnt_set) { | 129 | } else if (!minpcnt_set) { |
104 | /* try to get the min percent */ | 130 | /* try to get the min percent */ |
105 | callchain_param.min_percent = strtod(tok, &endptr); | 131 | callchain_param.min_percent = strtod(tok, &endptr); |
@@ -112,7 +138,7 @@ parse_callchain_report_opt(const char *arg) | |||
112 | if (tok == endptr) | 138 | if (tok == endptr) |
113 | return -1; | 139 | return -1; |
114 | } | 140 | } |
115 | 141 | next: | |
116 | arg = NULL; | 142 | arg = NULL; |
117 | } | 143 | } |
118 | 144 | ||
@@ -123,6 +149,16 @@ parse_callchain_report_opt(const char *arg) | |||
123 | return 0; | 149 | return 0; |
124 | } | 150 | } |
125 | 151 | ||
152 | int parse_callchain_report_opt(const char *arg) | ||
153 | { | ||
154 | return __parse_callchain_report_opt(arg, false); | ||
155 | } | ||
156 | |||
157 | int parse_callchain_top_opt(const char *arg) | ||
158 | { | ||
159 | return __parse_callchain_report_opt(arg, true); | ||
160 | } | ||
161 | |||
126 | int perf_callchain_config(const char *var, const char *value) | 162 | int perf_callchain_config(const char *var, const char *value) |
127 | { | 163 | { |
128 | char *endptr; | 164 | char *endptr; |
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index acee2b3cd801..fce8161e54db 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h | |||
@@ -7,6 +7,30 @@ | |||
7 | #include "event.h" | 7 | #include "event.h" |
8 | #include "symbol.h" | 8 | #include "symbol.h" |
9 | 9 | ||
10 | #define HELP_PAD "\t\t\t\t" | ||
11 | |||
12 | #define CALLCHAIN_HELP "setup and enables call-graph (stack chain/backtrace):\n\n" | ||
13 | |||
14 | #ifdef HAVE_DWARF_UNWIND_SUPPORT | ||
15 | # define RECORD_MODE_HELP HELP_PAD "record_mode:\tcall graph recording mode (fp|dwarf|lbr)\n" | ||
16 | #else | ||
17 | # define RECORD_MODE_HELP HELP_PAD "record_mode:\tcall graph recording mode (fp|lbr)\n" | ||
18 | #endif | ||
19 | |||
20 | #define RECORD_SIZE_HELP \ | ||
21 | HELP_PAD "record_size:\tif record_mode is 'dwarf', max size of stack recording (<bytes>)\n" \ | ||
22 | HELP_PAD "\t\tdefault: 8192 (bytes)\n" | ||
23 | |||
24 | #define CALLCHAIN_RECORD_HELP CALLCHAIN_HELP RECORD_MODE_HELP RECORD_SIZE_HELP | ||
25 | |||
26 | #define CALLCHAIN_REPORT_HELP \ | ||
27 | HELP_PAD "print_type:\tcall graph printing style (graph|flat|fractal|none)\n" \ | ||
28 | HELP_PAD "threshold:\tminimum call graph inclusion threshold (<percent>)\n" \ | ||
29 | HELP_PAD "print_limit:\tmaximum number of call graph entry (<number>)\n" \ | ||
30 | HELP_PAD "order:\t\tcall graph order (caller|callee)\n" \ | ||
31 | HELP_PAD "sort_key:\tcall graph sort key (function|address)\n" \ | ||
32 | HELP_PAD "branch:\t\tinclude last branch info to call graph (branch)\n" | ||
33 | |||
10 | enum perf_call_graph_mode { | 34 | enum perf_call_graph_mode { |
11 | CALLCHAIN_NONE, | 35 | CALLCHAIN_NONE, |
12 | CALLCHAIN_FP, | 36 | CALLCHAIN_FP, |
@@ -63,6 +87,7 @@ struct callchain_param { | |||
63 | double min_percent; | 87 | double min_percent; |
64 | sort_chain_func_t sort; | 88 | sort_chain_func_t sort; |
65 | enum chain_order order; | 89 | enum chain_order order; |
90 | bool order_set; | ||
66 | enum chain_key key; | 91 | enum chain_key key; |
67 | bool branch_callstack; | 92 | bool branch_callstack; |
68 | }; | 93 | }; |
@@ -180,6 +205,7 @@ extern const char record_callchain_help[]; | |||
180 | extern int parse_callchain_record(const char *arg, struct callchain_param *param); | 205 | extern int parse_callchain_record(const char *arg, struct callchain_param *param); |
181 | int parse_callchain_record_opt(const char *arg, struct callchain_param *param); | 206 | int parse_callchain_record_opt(const char *arg, struct callchain_param *param); |
182 | int parse_callchain_report_opt(const char *arg); | 207 | int parse_callchain_report_opt(const char *arg); |
208 | int parse_callchain_top_opt(const char *arg); | ||
183 | int perf_callchain_config(const char *var, const char *value); | 209 | int perf_callchain_config(const char *var, const char *value); |
184 | 210 | ||
185 | static inline void callchain_cursor_snapshot(struct callchain_cursor *dest, | 211 | static inline void callchain_cursor_snapshot(struct callchain_cursor *dest, |
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index c1bf9ff210b0..cd12c25e4ea4 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c | |||
@@ -19,7 +19,7 @@ | |||
19 | struct callchain_param callchain_param = { | 19 | struct callchain_param callchain_param = { |
20 | .mode = CHAIN_GRAPH_ABS, | 20 | .mode = CHAIN_GRAPH_ABS, |
21 | .min_percent = 0.5, | 21 | .min_percent = 0.5, |
22 | .order = ORDER_CALLER, | 22 | .order = ORDER_CALLEE, |
23 | .key = CCKEY_FUNCTION | 23 | .key = CCKEY_FUNCTION |
24 | }; | 24 | }; |
25 | 25 | ||