aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/Documentation/perf-top.txt5
-rw-r--r--tools/perf/builtin-top.c26
-rw-r--r--tools/perf/util/callchain.c40
-rw-r--r--tools/perf/util/callchain.h1
4 files changed, 62 insertions, 10 deletions
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-top.c b/tools/perf/builtin-top.c
index 6f641fd68296..1de381d3f29f 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)
1053static int 1053static int
1054parse_callchain_opt(const struct option *opt, const char *arg, int unset) 1054parse_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
1060static int perf_top_config(const char *var, const char *value, void *cb) 1074static int perf_top_config(const char *var, const char *value, void *cb)
@@ -1079,6 +1093,8 @@ parse_percent_limit(const struct option *opt, const char *arg,
1079 return 0; 1093 return 0;
1080} 1094}
1081 1095
1096const char top_callchain_help[] = CALLCHAIN_RECORD_HELP ", " CALLCHAIN_REPORT_HELP;
1097
1082int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) 1098int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
1083{ 1099{
1084 char errbuf[BUFSIZ]; 1100 char errbuf[BUFSIZ];
@@ -1154,11 +1170,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, 1170 OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples,
1155 "Show a column with the number of samples"), 1171 "Show a column with the number of samples"),
1156 OPT_CALLBACK_NOOPT('g', NULL, &top.record_opts, 1172 OPT_CALLBACK_NOOPT('g', NULL, &top.record_opts,
1157 NULL, "enables call-graph recording", 1173 NULL, "enables call-graph recording and display",
1158 &callchain_opt), 1174 &callchain_opt),
1159 OPT_CALLBACK(0, "call-graph", &top.record_opts, 1175 OPT_CALLBACK(0, "call-graph", &top.record_opts,
1160 "mode[,dump_size]", record_callchain_help, 1176 "mode[,dump_size],output_type,min_percent[,print_limit],call_order[,branch]",
1161 &parse_callchain_opt), 1177 top_callchain_help, &parse_callchain_opt),
1162 OPT_BOOLEAN(0, "children", &symbol_conf.cumulate_callchain, 1178 OPT_BOOLEAN(0, "children", &symbol_conf.cumulate_callchain,
1163 "Accumulate callchains of children and show total overhead as well"), 1179 "Accumulate callchains of children and show total overhead as well"),
1164 OPT_INTEGER(0, "max-stack", &top.max_stack, 1180 OPT_INTEGER(0, "max-stack", &top.max_stack,
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index 773fe13ce627..842be32899ee 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -77,12 +77,14 @@ static int parse_callchain_sort_key(const char *value)
77 return -1; 77 return -1;
78} 78}
79 79
80int 80static int
81parse_callchain_report_opt(const char *arg) 81__parse_callchain_report_opt(const char *arg, bool allow_record_opt)
82{ 82{
83 char *tok; 83 char *tok;
84 char *endptr; 84 char *endptr;
85 bool minpcnt_set = false; 85 bool minpcnt_set = false;
86 bool record_opt_set = false;
87 bool try_stack_size = false;
86 88
87 symbol_conf.use_callchain = true; 89 symbol_conf.use_callchain = true;
88 90
@@ -100,6 +102,28 @@ parse_callchain_report_opt(const char *arg)
100 !parse_callchain_order(tok) || 102 !parse_callchain_order(tok) ||
101 !parse_callchain_sort_key(tok)) { 103 !parse_callchain_sort_key(tok)) {
102 /* parsing ok - move on to the next */ 104 /* parsing ok - move on to the next */
105 try_stack_size = false;
106 goto next;
107 } else if (allow_record_opt && !record_opt_set) {
108 if (parse_callchain_record(tok, &callchain_param))
109 goto try_numbers;
110
111 /* assume that number followed by 'dwarf' is stack size */
112 if (callchain_param.record_mode == CALLCHAIN_DWARF)
113 try_stack_size = true;
114
115 record_opt_set = true;
116 goto next;
117 }
118
119try_numbers:
120 if (try_stack_size) {
121 unsigned long size = 0;
122
123 if (get_stack_size(tok, &size) < 0)
124 return -1;
125 callchain_param.dump_size = size;
126 try_stack_size = false;
103 } else if (!minpcnt_set) { 127 } else if (!minpcnt_set) {
104 /* try to get the min percent */ 128 /* try to get the min percent */
105 callchain_param.min_percent = strtod(tok, &endptr); 129 callchain_param.min_percent = strtod(tok, &endptr);
@@ -112,7 +136,7 @@ parse_callchain_report_opt(const char *arg)
112 if (tok == endptr) 136 if (tok == endptr)
113 return -1; 137 return -1;
114 } 138 }
115 139next:
116 arg = NULL; 140 arg = NULL;
117 } 141 }
118 142
@@ -123,6 +147,16 @@ parse_callchain_report_opt(const char *arg)
123 return 0; 147 return 0;
124} 148}
125 149
150int parse_callchain_report_opt(const char *arg)
151{
152 return __parse_callchain_report_opt(arg, false);
153}
154
155int parse_callchain_top_opt(const char *arg)
156{
157 return __parse_callchain_report_opt(arg, true);
158}
159
126int perf_callchain_config(const char *var, const char *value) 160int perf_callchain_config(const char *var, const char *value)
127{ 161{
128 char *endptr; 162 char *endptr;
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index c9e3a2e85a72..836d59a001bc 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -192,6 +192,7 @@ extern const char record_callchain_help[];
192extern int parse_callchain_record(const char *arg, struct callchain_param *param); 192extern int parse_callchain_record(const char *arg, struct callchain_param *param);
193int parse_callchain_record_opt(const char *arg, struct callchain_param *param); 193int parse_callchain_record_opt(const char *arg, struct callchain_param *param);
194int parse_callchain_report_opt(const char *arg); 194int parse_callchain_report_opt(const char *arg);
195int parse_callchain_top_opt(const char *arg);
195int perf_callchain_config(const char *var, const char *value); 196int perf_callchain_config(const char *var, const char *value);
196 197
197static inline void callchain_cursor_snapshot(struct callchain_cursor *dest, 198static inline void callchain_cursor_snapshot(struct callchain_cursor *dest,