diff options
author | Namhyung Kim <namhyung@kernel.org> | 2015-11-09 00:45:37 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2015-11-19 11:19:22 -0500 |
commit | 26e779245dd6f5270c0696860438e5c03d0780fd (patch) | |
tree | d1ede86280f98fd6684339e03b4431ef4c1125db /tools/perf/ui/stdio/hist.c | |
parent | 566c69c36e6178774dd484ea4a02b76f6bd0ede4 (diff) |
perf report: Support folded callchain mode on --stdio
Add new call chain option (-g) 'folded' to print callchains in a line.
The callchains are separated by semicolons, and preceded by (absolute)
percent values and a space.
For example, the following 20 lines can be printed in 3 lines with the
folded output mode:
$ perf report -g flat --no-children | grep -v ^# | head -20
60.48% swapper [kernel.vmlinux] [k] intel_idle
54.60%
intel_idle
cpuidle_enter_state
cpuidle_enter
call_cpuidle
cpu_startup_entry
start_secondary
5.88%
intel_idle
cpuidle_enter_state
cpuidle_enter
call_cpuidle
cpu_startup_entry
rest_init
start_kernel
x86_64_start_reservations
x86_64_start_kernel
$ perf report -g folded --no-children | grep -v ^# | head -3
60.48% swapper [kernel.vmlinux] [k] intel_idle
54.60% intel_idle;cpuidle_enter_state;cpuidle_enter;call_cpuidle;cpu_startup_entry;start_secondary
5.88% intel_idle;cpuidle_enter_state;cpuidle_enter;call_cpuidle;cpu_startup_entry;rest_init;start_kernel;x86_64_start_reservations;x86_64_start_kernel
This mode is supported only for --stdio now and intended to be used by
some scripts like in FlameGraphs[1]. Support for other UI might be
added later.
[1] http://www.brendangregg.com/FlameGraphs/cpuflamegraphs.html
Requested-and-Tested-by: Brendan Gregg <brendan.d.gregg@gmail.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1447047946-1691-2-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/ui/stdio/hist.c')
-rw-r--r-- | tools/perf/ui/stdio/hist.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c index dfcbc90146ef..ea7984932d9a 100644 --- a/tools/perf/ui/stdio/hist.c +++ b/tools/perf/ui/stdio/hist.c | |||
@@ -260,6 +260,58 @@ static size_t callchain__fprintf_flat(FILE *fp, struct rb_root *tree, | |||
260 | return ret; | 260 | return ret; |
261 | } | 261 | } |
262 | 262 | ||
263 | static size_t __callchain__fprintf_folded(FILE *fp, struct callchain_node *node) | ||
264 | { | ||
265 | const char *sep = symbol_conf.field_sep ?: ";"; | ||
266 | struct callchain_list *chain; | ||
267 | size_t ret = 0; | ||
268 | char bf[1024]; | ||
269 | bool first; | ||
270 | |||
271 | if (!node) | ||
272 | return 0; | ||
273 | |||
274 | ret += __callchain__fprintf_folded(fp, node->parent); | ||
275 | |||
276 | first = (ret == 0); | ||
277 | list_for_each_entry(chain, &node->val, list) { | ||
278 | if (chain->ip >= PERF_CONTEXT_MAX) | ||
279 | continue; | ||
280 | ret += fprintf(fp, "%s%s", first ? "" : sep, | ||
281 | callchain_list__sym_name(chain, | ||
282 | bf, sizeof(bf), false)); | ||
283 | first = false; | ||
284 | } | ||
285 | |||
286 | return ret; | ||
287 | } | ||
288 | |||
289 | static size_t callchain__fprintf_folded(FILE *fp, struct rb_root *tree, | ||
290 | u64 total_samples) | ||
291 | { | ||
292 | size_t ret = 0; | ||
293 | u32 entries_printed = 0; | ||
294 | struct callchain_node *chain; | ||
295 | struct rb_node *rb_node = rb_first(tree); | ||
296 | |||
297 | while (rb_node) { | ||
298 | double percent; | ||
299 | |||
300 | chain = rb_entry(rb_node, struct callchain_node, rb_node); | ||
301 | percent = chain->hit * 100.0 / total_samples; | ||
302 | |||
303 | ret += fprintf(fp, "%.2f%% ", percent); | ||
304 | ret += __callchain__fprintf_folded(fp, chain); | ||
305 | ret += fprintf(fp, "\n"); | ||
306 | if (++entries_printed == callchain_param.print_limit) | ||
307 | break; | ||
308 | |||
309 | rb_node = rb_next(rb_node); | ||
310 | } | ||
311 | |||
312 | return ret; | ||
313 | } | ||
314 | |||
263 | static size_t hist_entry_callchain__fprintf(struct hist_entry *he, | 315 | static size_t hist_entry_callchain__fprintf(struct hist_entry *he, |
264 | u64 total_samples, int left_margin, | 316 | u64 total_samples, int left_margin, |
265 | FILE *fp) | 317 | FILE *fp) |
@@ -278,6 +330,9 @@ static size_t hist_entry_callchain__fprintf(struct hist_entry *he, | |||
278 | case CHAIN_FLAT: | 330 | case CHAIN_FLAT: |
279 | return callchain__fprintf_flat(fp, &he->sorted_chain, total_samples); | 331 | return callchain__fprintf_flat(fp, &he->sorted_chain, total_samples); |
280 | break; | 332 | break; |
333 | case CHAIN_FOLDED: | ||
334 | return callchain__fprintf_folded(fp, &he->sorted_chain, total_samples); | ||
335 | break; | ||
281 | case CHAIN_NONE: | 336 | case CHAIN_NONE: |
282 | break; | 337 | break; |
283 | default: | 338 | default: |