diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2010-05-09 19:28:10 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2010-05-09 20:15:35 -0400 |
commit | 232a5c948da5e23dff27e48180abf4a4238f7602 (patch) | |
tree | bf17e2e428a77b656946e798e3b099dc09c658be /tools/perf | |
parent | 1f626bc36847ac8dd192f055aed0f9678a781313 (diff) |
perf report: Allow limiting the number of entries to print in callchains
Works by adding a third parameter to the '-g' argument, after the graph
type and minimum percentage, for example:
[root@doppio linux-2.6-tip]# perf report -g fractal,0.5,2
Will show only the first two symbols where at least 0.5% of the samples
took place.
All the other symbols that don't fall outside these constraints will be
put together in the last entry, prefixed with "[...]" and the total
percentage for them.
Suggested-by: Arjan van de Ven <arjan@linux.intel.com>
Acked-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r-- | tools/perf/builtin-report.c | 5 | ||||
-rw-r--r-- | tools/perf/util/callchain.h | 1 | ||||
-rw-r--r-- | tools/perf/util/hist.c | 10 |
3 files changed, 15 insertions, 1 deletions
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 5e2f47f88ec6..642a6d8eb5dc 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -343,7 +343,7 @@ static int | |||
343 | parse_callchain_opt(const struct option *opt __used, const char *arg, | 343 | parse_callchain_opt(const struct option *opt __used, const char *arg, |
344 | int unset) | 344 | int unset) |
345 | { | 345 | { |
346 | char *tok; | 346 | char *tok, *tok2; |
347 | char *endptr; | 347 | char *endptr; |
348 | 348 | ||
349 | /* | 349 | /* |
@@ -388,10 +388,13 @@ parse_callchain_opt(const struct option *opt __used, const char *arg, | |||
388 | if (!tok) | 388 | if (!tok) |
389 | goto setup; | 389 | goto setup; |
390 | 390 | ||
391 | tok2 = strtok(NULL, ","); | ||
391 | callchain_param.min_percent = strtod(tok, &endptr); | 392 | callchain_param.min_percent = strtod(tok, &endptr); |
392 | if (tok == endptr) | 393 | if (tok == endptr) |
393 | return -1; | 394 | return -1; |
394 | 395 | ||
396 | if (tok2) | ||
397 | callchain_param.print_limit = strtod(tok2, &endptr); | ||
395 | setup: | 398 | setup: |
396 | if (register_callchain_param(&callchain_param) < 0) { | 399 | if (register_callchain_param(&callchain_param) < 0) { |
397 | fprintf(stderr, "Can't register callchain params\n"); | 400 | fprintf(stderr, "Can't register callchain params\n"); |
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index 0f4da093cbd8..1cba1f5504e7 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h | |||
@@ -34,6 +34,7 @@ typedef void (*sort_chain_func_t)(struct rb_root *, struct callchain_node *, | |||
34 | 34 | ||
35 | struct callchain_param { | 35 | struct callchain_param { |
36 | enum chain_mode mode; | 36 | enum chain_mode mode; |
37 | u32 print_limit; | ||
37 | double min_percent; | 38 | double min_percent; |
38 | sort_chain_func_t sort; | 39 | sort_chain_func_t sort; |
39 | }; | 40 | }; |
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index e0c8a722e11f..0f154a530dfd 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
@@ -333,6 +333,7 @@ static size_t __callchain__fprintf_graph(FILE *fp, struct callchain_node *self, | |||
333 | u64 remaining; | 333 | u64 remaining; |
334 | size_t ret = 0; | 334 | size_t ret = 0; |
335 | int i; | 335 | int i; |
336 | uint entries_printed = 0; | ||
336 | 337 | ||
337 | if (callchain_param.mode == CHAIN_GRAPH_REL) | 338 | if (callchain_param.mode == CHAIN_GRAPH_REL) |
338 | new_total = self->children_hit; | 339 | new_total = self->children_hit; |
@@ -379,6 +380,8 @@ static size_t __callchain__fprintf_graph(FILE *fp, struct callchain_node *self, | |||
379 | new_depth_mask | (1 << depth), | 380 | new_depth_mask | (1 << depth), |
380 | left_margin); | 381 | left_margin); |
381 | node = next; | 382 | node = next; |
383 | if (++entries_printed == callchain_param.print_limit) | ||
384 | break; | ||
382 | } | 385 | } |
383 | 386 | ||
384 | if (callchain_param.mode == CHAIN_GRAPH_REL && | 387 | if (callchain_param.mode == CHAIN_GRAPH_REL && |
@@ -404,6 +407,7 @@ static size_t callchain__fprintf_graph(FILE *fp, struct callchain_node *self, | |||
404 | bool printed = false; | 407 | bool printed = false; |
405 | int i = 0; | 408 | int i = 0; |
406 | int ret = 0; | 409 | int ret = 0; |
410 | u32 entries_printed = 0; | ||
407 | 411 | ||
408 | list_for_each_entry(chain, &self->val, list) { | 412 | list_for_each_entry(chain, &self->val, list) { |
409 | if (!i++ && sort__first_dimension == SORT_SYM) | 413 | if (!i++ && sort__first_dimension == SORT_SYM) |
@@ -424,6 +428,9 @@ static size_t callchain__fprintf_graph(FILE *fp, struct callchain_node *self, | |||
424 | ret += fprintf(fp, " %s\n", chain->ms.sym->name); | 428 | ret += fprintf(fp, " %s\n", chain->ms.sym->name); |
425 | else | 429 | else |
426 | ret += fprintf(fp, " %p\n", (void *)(long)chain->ip); | 430 | ret += fprintf(fp, " %p\n", (void *)(long)chain->ip); |
431 | |||
432 | if (++entries_printed == callchain_param.print_limit) | ||
433 | break; | ||
427 | } | 434 | } |
428 | 435 | ||
429 | ret += __callchain__fprintf_graph(fp, self, total_samples, 1, 1, left_margin); | 436 | ret += __callchain__fprintf_graph(fp, self, total_samples, 1, 1, left_margin); |
@@ -462,6 +469,7 @@ static size_t hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self, | |||
462 | struct rb_node *rb_node; | 469 | struct rb_node *rb_node; |
463 | struct callchain_node *chain; | 470 | struct callchain_node *chain; |
464 | size_t ret = 0; | 471 | size_t ret = 0; |
472 | u32 entries_printed = 0; | ||
465 | 473 | ||
466 | rb_node = rb_first(&self->sorted_chain); | 474 | rb_node = rb_first(&self->sorted_chain); |
467 | while (rb_node) { | 475 | while (rb_node) { |
@@ -484,6 +492,8 @@ static size_t hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self, | |||
484 | break; | 492 | break; |
485 | } | 493 | } |
486 | ret += fprintf(fp, "\n"); | 494 | ret += fprintf(fp, "\n"); |
495 | if (++entries_printed == callchain_param.print_limit) | ||
496 | break; | ||
487 | rb_node = rb_next(rb_node); | 497 | rb_node = rb_next(rb_node); |
488 | } | 498 | } |
489 | 499 | ||