aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-report.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-report.c')
-rw-r--r--tools/perf/builtin-report.c57
1 files changed, 50 insertions, 7 deletions
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 287a173523a7..f854efda7686 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -33,6 +33,8 @@
33#include "util/sort.h" 33#include "util/sort.h"
34#include "util/hist.h" 34#include "util/hist.h"
35 35
36#include <linux/bitmap.h>
37
36static char const *input_name = "perf.data"; 38static char const *input_name = "perf.data";
37 39
38static bool force, use_tui, use_stdio; 40static bool force, use_tui, use_stdio;
@@ -45,9 +47,13 @@ static struct perf_read_values show_threads_values;
45static const char default_pretty_printing_style[] = "normal"; 47static const char default_pretty_printing_style[] = "normal";
46static const char *pretty_printing_style = default_pretty_printing_style; 48static const char *pretty_printing_style = default_pretty_printing_style;
47 49
48static char callchain_default_opt[] = "fractal,0.5"; 50static char callchain_default_opt[] = "fractal,0.5,callee";
51static bool inverted_callchain;
49static symbol_filter_t annotate_init; 52static symbol_filter_t annotate_init;
50 53
54static const char *cpu_list;
55static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
56
51static int perf_session__add_hist_entry(struct perf_session *session, 57static int perf_session__add_hist_entry(struct perf_session *session,
52 struct addr_location *al, 58 struct addr_location *al,
53 struct perf_sample *sample, 59 struct perf_sample *sample,
@@ -116,6 +122,9 @@ static int process_sample_event(union perf_event *event,
116 if (al.filtered || (hide_unresolved && al.sym == NULL)) 122 if (al.filtered || (hide_unresolved && al.sym == NULL))
117 return 0; 123 return 0;
118 124
125 if (cpu_list && !test_bit(sample->cpu, cpu_bitmap))
126 return 0;
127
119 if (al.map != NULL) 128 if (al.map != NULL)
120 al.map->dso->hit = 1; 129 al.map->dso->hit = 1;
121 130
@@ -262,6 +271,12 @@ static int __cmd_report(void)
262 if (session == NULL) 271 if (session == NULL)
263 return -ENOMEM; 272 return -ENOMEM;
264 273
274 if (cpu_list) {
275 ret = perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap);
276 if (ret)
277 goto out_delete;
278 }
279
265 if (show_threads) 280 if (show_threads)
266 perf_read_values_init(&show_threads_values); 281 perf_read_values_init(&show_threads_values);
267 282
@@ -386,13 +401,29 @@ parse_callchain_opt(const struct option *opt __used, const char *arg,
386 if (!tok) 401 if (!tok)
387 goto setup; 402 goto setup;
388 403
389 tok2 = strtok(NULL, ",");
390 callchain_param.min_percent = strtod(tok, &endptr); 404 callchain_param.min_percent = strtod(tok, &endptr);
391 if (tok == endptr) 405 if (tok == endptr)
392 return -1; 406 return -1;
393 407
394 if (tok2) 408 /* get the print limit */
409 tok2 = strtok(NULL, ",");
410 if (!tok2)
411 goto setup;
412
413 if (tok2[0] != 'c') {
395 callchain_param.print_limit = strtod(tok2, &endptr); 414 callchain_param.print_limit = strtod(tok2, &endptr);
415 tok2 = strtok(NULL, ",");
416 if (!tok2)
417 goto setup;
418 }
419
420 /* get the call chain order */
421 if (!strcmp(tok2, "caller"))
422 callchain_param.order = ORDER_CALLER;
423 else if (!strcmp(tok2, "callee"))
424 callchain_param.order = ORDER_CALLEE;
425 else
426 return -1;
396setup: 427setup:
397 if (callchain_register_param(&callchain_param) < 0) { 428 if (callchain_register_param(&callchain_param) < 0) {
398 fprintf(stderr, "Can't register callchain params\n"); 429 fprintf(stderr, "Can't register callchain params\n");
@@ -436,9 +467,10 @@ static const struct option options[] = {
436 "regex filter to identify parent, see: '--sort parent'"), 467 "regex filter to identify parent, see: '--sort parent'"),
437 OPT_BOOLEAN('x', "exclude-other", &symbol_conf.exclude_other, 468 OPT_BOOLEAN('x', "exclude-other", &symbol_conf.exclude_other,
438 "Only display entries with parent-match"), 469 "Only display entries with parent-match"),
439 OPT_CALLBACK_DEFAULT('g', "call-graph", NULL, "output_type,min_percent", 470 OPT_CALLBACK_DEFAULT('g', "call-graph", NULL, "output_type,min_percent, call_order",
440 "Display callchains using output_type (graph, flat, fractal, or none) and min percent threshold. " 471 "Display callchains using output_type (graph, flat, fractal, or none) , min percent threshold and callchain order. "
441 "Default: fractal,0.5", &parse_callchain_opt, callchain_default_opt), 472 "Default: fractal,0.5,callee", &parse_callchain_opt, callchain_default_opt),
473 OPT_BOOLEAN('G', "inverted", &inverted_callchain, "alias for inverted call graph"),
442 OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]", 474 OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
443 "only consider symbols in these dsos"), 475 "only consider symbols in these dsos"),
444 OPT_STRING('C', "comms", &symbol_conf.comm_list_str, "comm[,comm...]", 476 OPT_STRING('C', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
@@ -455,6 +487,7 @@ static const struct option options[] = {
455 "Only display entries resolved to a symbol"), 487 "Only display entries resolved to a symbol"),
456 OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory", 488 OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
457 "Look for files with symbols relative to this directory"), 489 "Look for files with symbols relative to this directory"),
490 OPT_STRING('c', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
458 OPT_END() 491 OPT_END()
459}; 492};
460 493
@@ -467,6 +500,9 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
467 else if (use_tui) 500 else if (use_tui)
468 use_browser = 1; 501 use_browser = 1;
469 502
503 if (inverted_callchain)
504 callchain_param.order = ORDER_CALLER;
505
470 if (strcmp(input_name, "-") != 0) 506 if (strcmp(input_name, "-") != 0)
471 setup_browser(true); 507 setup_browser(true);
472 else 508 else
@@ -504,7 +540,14 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
504 if (parent_pattern != default_parent_pattern) { 540 if (parent_pattern != default_parent_pattern) {
505 if (sort_dimension__add("parent") < 0) 541 if (sort_dimension__add("parent") < 0)
506 return -1; 542 return -1;
507 sort_parent.elide = 1; 543
544 /*
545 * Only show the parent fields if we explicitly
546 * sort that way. If we only use parent machinery
547 * for filtering, we don't want it.
548 */
549 if (!strstr(sort_order, "parent"))
550 sort_parent.elide = 1;
508 } else 551 } else
509 symbol_conf.exclude_other = false; 552 symbol_conf.exclude_other = false;
510 553