diff options
author | Namhyung Kim <namhyung@kernel.org> | 2014-09-22 21:01:43 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2014-09-26 11:43:24 -0400 |
commit | 2b9240cafe9780f77b257321b13c4c4d2c2d0dc8 (patch) | |
tree | caceef75312309f35e427f01194fb2943c56f609 /tools | |
parent | f7f084f4d3c29b0f9877a32fc6e2feacd47695b9 (diff) |
perf tools: Introduce perf_callchain_config()
This patch adds support for following config options to ~/.perfconfig file.
[call-graph]
record-mode = dwarf
dump-size = 8192
print-type = fractal
order = callee
threshold = 0.5
print-limit = 128
sort-key = function
Reviewed-by: David Ahern <dsahern@gmail.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Milian Wolff <mail@milianw.de>
Cc: Namhyung Kim <namhyung.kim@lge.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1411434104-5307-5-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/util/callchain.c | 109 | ||||
-rw-r--r-- | tools/perf/util/callchain.h | 1 | ||||
-rw-r--r-- | tools/perf/util/config.c | 3 |
3 files changed, 94 insertions, 19 deletions
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index ba7297230143..c84d3f8dcb75 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c | |||
@@ -109,6 +109,49 @@ int parse_callchain_record_opt(const char *arg) | |||
109 | return ret; | 109 | return ret; |
110 | } | 110 | } |
111 | 111 | ||
112 | static int parse_callchain_mode(const char *value) | ||
113 | { | ||
114 | if (!strncmp(value, "graph", strlen(value))) { | ||
115 | callchain_param.mode = CHAIN_GRAPH_ABS; | ||
116 | return 0; | ||
117 | } | ||
118 | if (!strncmp(value, "flat", strlen(value))) { | ||
119 | callchain_param.mode = CHAIN_FLAT; | ||
120 | return 0; | ||
121 | } | ||
122 | if (!strncmp(value, "fractal", strlen(value))) { | ||
123 | callchain_param.mode = CHAIN_GRAPH_REL; | ||
124 | return 0; | ||
125 | } | ||
126 | return -1; | ||
127 | } | ||
128 | |||
129 | static int parse_callchain_order(const char *value) | ||
130 | { | ||
131 | if (!strncmp(value, "caller", strlen(value))) { | ||
132 | callchain_param.order = ORDER_CALLER; | ||
133 | return 0; | ||
134 | } | ||
135 | if (!strncmp(value, "callee", strlen(value))) { | ||
136 | callchain_param.order = ORDER_CALLEE; | ||
137 | return 0; | ||
138 | } | ||
139 | return -1; | ||
140 | } | ||
141 | |||
142 | static int parse_callchain_sort_key(const char *value) | ||
143 | { | ||
144 | if (!strncmp(value, "function", strlen(value))) { | ||
145 | callchain_param.key = CCKEY_FUNCTION; | ||
146 | return 0; | ||
147 | } | ||
148 | if (!strncmp(value, "address", strlen(value))) { | ||
149 | callchain_param.key = CCKEY_ADDRESS; | ||
150 | return 0; | ||
151 | } | ||
152 | return -1; | ||
153 | } | ||
154 | |||
112 | int | 155 | int |
113 | parse_callchain_report_opt(const char *arg) | 156 | parse_callchain_report_opt(const char *arg) |
114 | { | 157 | { |
@@ -128,25 +171,12 @@ parse_callchain_report_opt(const char *arg) | |||
128 | return 0; | 171 | return 0; |
129 | } | 172 | } |
130 | 173 | ||
131 | /* try to get the output mode */ | 174 | if (!parse_callchain_mode(tok) || |
132 | if (!strncmp(tok, "graph", strlen(tok))) | 175 | !parse_callchain_order(tok) || |
133 | callchain_param.mode = CHAIN_GRAPH_ABS; | 176 | !parse_callchain_sort_key(tok)) { |
134 | else if (!strncmp(tok, "flat", strlen(tok))) | 177 | /* parsing ok - move on to the next */ |
135 | callchain_param.mode = CHAIN_FLAT; | 178 | } else if (!minpcnt_set) { |
136 | else if (!strncmp(tok, "fractal", strlen(tok))) | 179 | /* try to get the min percent */ |
137 | callchain_param.mode = CHAIN_GRAPH_REL; | ||
138 | /* try to get the call chain order */ | ||
139 | else if (!strncmp(tok, "caller", strlen(tok))) | ||
140 | callchain_param.order = ORDER_CALLER; | ||
141 | else if (!strncmp(tok, "callee", strlen(tok))) | ||
142 | callchain_param.order = ORDER_CALLEE; | ||
143 | /* try to get the sort key */ | ||
144 | else if (!strncmp(tok, "function", strlen(tok))) | ||
145 | callchain_param.key = CCKEY_FUNCTION; | ||
146 | else if (!strncmp(tok, "address", strlen(tok))) | ||
147 | callchain_param.key = CCKEY_ADDRESS; | ||
148 | /* try to get the min percent */ | ||
149 | else if (!minpcnt_set) { | ||
150 | callchain_param.min_percent = strtod(tok, &endptr); | 180 | callchain_param.min_percent = strtod(tok, &endptr); |
151 | if (tok == endptr) | 181 | if (tok == endptr) |
152 | return -1; | 182 | return -1; |
@@ -168,6 +198,47 @@ parse_callchain_report_opt(const char *arg) | |||
168 | return 0; | 198 | return 0; |
169 | } | 199 | } |
170 | 200 | ||
201 | int perf_callchain_config(const char *var, const char *value) | ||
202 | { | ||
203 | char *endptr; | ||
204 | |||
205 | if (prefixcmp(var, "call-graph.")) | ||
206 | return 0; | ||
207 | var += sizeof("call-graph.") - 1; | ||
208 | |||
209 | if (!strcmp(var, "record-mode")) | ||
210 | return parse_callchain_record_opt(value); | ||
211 | #ifdef HAVE_DWARF_UNWIND_SUPPORT | ||
212 | if (!strcmp(var, "dump-size")) { | ||
213 | unsigned long size = 0; | ||
214 | int ret; | ||
215 | |||
216 | ret = get_stack_size(value, &size); | ||
217 | callchain_param.dump_size = size; | ||
218 | |||
219 | return ret; | ||
220 | } | ||
221 | #endif | ||
222 | if (!strcmp(var, "print-type")) | ||
223 | return parse_callchain_mode(value); | ||
224 | if (!strcmp(var, "order")) | ||
225 | return parse_callchain_order(value); | ||
226 | if (!strcmp(var, "sort-key")) | ||
227 | return parse_callchain_sort_key(value); | ||
228 | if (!strcmp(var, "threshold")) { | ||
229 | callchain_param.min_percent = strtod(value, &endptr); | ||
230 | if (value == endptr) | ||
231 | return -1; | ||
232 | } | ||
233 | if (!strcmp(var, "print-limit")) { | ||
234 | callchain_param.print_limit = strtod(value, &endptr); | ||
235 | if (value == endptr) | ||
236 | return -1; | ||
237 | } | ||
238 | |||
239 | return 0; | ||
240 | } | ||
241 | |||
171 | static void | 242 | static void |
172 | rb_insert_callchain(struct rb_root *root, struct callchain_node *chain, | 243 | rb_insert_callchain(struct rb_root *root, struct callchain_node *chain, |
173 | enum chain_mode mode) | 244 | enum chain_mode mode) |
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index 8adfbf0bab5c..2a1f5a46543a 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h | |||
@@ -170,6 +170,7 @@ int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node * | |||
170 | extern const char record_callchain_help[]; | 170 | extern const char record_callchain_help[]; |
171 | int parse_callchain_record_opt(const char *arg); | 171 | int parse_callchain_record_opt(const char *arg); |
172 | int parse_callchain_report_opt(const char *arg); | 172 | int parse_callchain_report_opt(const char *arg); |
173 | int perf_callchain_config(const char *var, const char *value); | ||
173 | 174 | ||
174 | static inline void callchain_cursor_snapshot(struct callchain_cursor *dest, | 175 | static inline void callchain_cursor_snapshot(struct callchain_cursor *dest, |
175 | struct callchain_cursor *src) | 176 | struct callchain_cursor *src) |
diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index 9970b8b0190b..953512ed72ba 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c | |||
@@ -396,6 +396,9 @@ int perf_default_config(const char *var, const char *value, | |||
396 | if (!prefixcmp(var, "ui.")) | 396 | if (!prefixcmp(var, "ui.")) |
397 | return perf_ui_config(var, value); | 397 | return perf_ui_config(var, value); |
398 | 398 | ||
399 | if (!prefixcmp(var, "call-graph.")) | ||
400 | return perf_callchain_config(var, value); | ||
401 | |||
399 | /* Add other config variables here. */ | 402 | /* Add other config variables here. */ |
400 | return 0; | 403 | return 0; |
401 | } | 404 | } |