diff options
Diffstat (limited to 'tools/perf/builtin-report.c')
-rw-r--r-- | tools/perf/builtin-report.c | 58 |
1 files changed, 44 insertions, 14 deletions
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 2bf537f190a0..7eea49f9ed46 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -75,7 +75,10 @@ static int report__config(const char *var, const char *value, void *cb) | |||
75 | return 0; | 75 | return 0; |
76 | } | 76 | } |
77 | if (!strcmp(var, "report.percent-limit")) { | 77 | if (!strcmp(var, "report.percent-limit")) { |
78 | rep->min_percent = strtof(value, NULL); | 78 | double pcnt = strtof(value, NULL); |
79 | |||
80 | rep->min_percent = pcnt; | ||
81 | callchain_param.min_percent = pcnt; | ||
79 | return 0; | 82 | return 0; |
80 | } | 83 | } |
81 | if (!strcmp(var, "report.children")) { | 84 | if (!strcmp(var, "report.children")) { |
@@ -87,7 +90,7 @@ static int report__config(const char *var, const char *value, void *cb) | |||
87 | return 0; | 90 | return 0; |
88 | } | 91 | } |
89 | 92 | ||
90 | return perf_default_config(var, value, cb); | 93 | return 0; |
91 | } | 94 | } |
92 | 95 | ||
93 | static int hist_iter__report_callback(struct hist_entry_iter *iter, | 96 | static int hist_iter__report_callback(struct hist_entry_iter *iter, |
@@ -466,10 +469,11 @@ static int report__browse_hists(struct report *rep) | |||
466 | return ret; | 469 | return ret; |
467 | } | 470 | } |
468 | 471 | ||
469 | static void report__collapse_hists(struct report *rep) | 472 | static int report__collapse_hists(struct report *rep) |
470 | { | 473 | { |
471 | struct ui_progress prog; | 474 | struct ui_progress prog; |
472 | struct perf_evsel *pos; | 475 | struct perf_evsel *pos; |
476 | int ret = 0; | ||
473 | 477 | ||
474 | ui_progress__init(&prog, rep->nr_entries, "Merging related events..."); | 478 | ui_progress__init(&prog, rep->nr_entries, "Merging related events..."); |
475 | 479 | ||
@@ -481,7 +485,9 @@ static void report__collapse_hists(struct report *rep) | |||
481 | 485 | ||
482 | hists->socket_filter = rep->socket_filter; | 486 | hists->socket_filter = rep->socket_filter; |
483 | 487 | ||
484 | hists__collapse_resort(hists, &prog); | 488 | ret = hists__collapse_resort(hists, &prog); |
489 | if (ret < 0) | ||
490 | break; | ||
485 | 491 | ||
486 | /* Non-group events are considered as leader */ | 492 | /* Non-group events are considered as leader */ |
487 | if (symbol_conf.event_group && | 493 | if (symbol_conf.event_group && |
@@ -494,6 +500,7 @@ static void report__collapse_hists(struct report *rep) | |||
494 | } | 500 | } |
495 | 501 | ||
496 | ui_progress__finish(); | 502 | ui_progress__finish(); |
503 | return ret; | ||
497 | } | 504 | } |
498 | 505 | ||
499 | static void report__output_resort(struct report *rep) | 506 | static void report__output_resort(struct report *rep) |
@@ -504,7 +511,7 @@ static void report__output_resort(struct report *rep) | |||
504 | ui_progress__init(&prog, rep->nr_entries, "Sorting events for output..."); | 511 | ui_progress__init(&prog, rep->nr_entries, "Sorting events for output..."); |
505 | 512 | ||
506 | evlist__for_each(rep->session->evlist, pos) | 513 | evlist__for_each(rep->session->evlist, pos) |
507 | hists__output_resort(evsel__hists(pos), &prog); | 514 | perf_evsel__output_resort(pos, &prog); |
508 | 515 | ||
509 | ui_progress__finish(); | 516 | ui_progress__finish(); |
510 | } | 517 | } |
@@ -561,7 +568,11 @@ static int __cmd_report(struct report *rep) | |||
561 | } | 568 | } |
562 | } | 569 | } |
563 | 570 | ||
564 | report__collapse_hists(rep); | 571 | ret = report__collapse_hists(rep); |
572 | if (ret) { | ||
573 | ui__error("failed to process hist entry\n"); | ||
574 | return ret; | ||
575 | } | ||
565 | 576 | ||
566 | if (session_done()) | 577 | if (session_done()) |
567 | return 0; | 578 | return 0; |
@@ -633,8 +644,10 @@ parse_percent_limit(const struct option *opt, const char *str, | |||
633 | int unset __maybe_unused) | 644 | int unset __maybe_unused) |
634 | { | 645 | { |
635 | struct report *rep = opt->value; | 646 | struct report *rep = opt->value; |
647 | double pcnt = strtof(str, NULL); | ||
636 | 648 | ||
637 | rep->min_percent = strtof(str, NULL); | 649 | rep->min_percent = pcnt; |
650 | callchain_param.min_percent = pcnt; | ||
638 | return 0; | 651 | return 0; |
639 | } | 652 | } |
640 | 653 | ||
@@ -798,6 +811,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) | |||
798 | "only show processor socket that match with this filter"), | 811 | "only show processor socket that match with this filter"), |
799 | OPT_BOOLEAN(0, "raw-trace", &symbol_conf.raw_trace, | 812 | OPT_BOOLEAN(0, "raw-trace", &symbol_conf.raw_trace, |
800 | "Show raw trace event output (do not use print fmt or plugins)"), | 813 | "Show raw trace event output (do not use print fmt or plugins)"), |
814 | OPT_BOOLEAN(0, "hierarchy", &symbol_conf.report_hierarchy, | ||
815 | "Show entries in a hierarchy"), | ||
801 | OPT_END() | 816 | OPT_END() |
802 | }; | 817 | }; |
803 | struct perf_data_file file = { | 818 | struct perf_data_file file = { |
@@ -907,13 +922,19 @@ repeat: | |||
907 | symbol_conf.cumulate_callchain = false; | 922 | symbol_conf.cumulate_callchain = false; |
908 | } | 923 | } |
909 | 924 | ||
910 | if (setup_sorting(session->evlist) < 0) { | 925 | if (symbol_conf.report_hierarchy) { |
911 | if (sort_order) | 926 | /* disable incompatible options */ |
912 | parse_options_usage(report_usage, options, "s", 1); | 927 | symbol_conf.event_group = false; |
913 | if (field_order) | 928 | symbol_conf.cumulate_callchain = false; |
914 | parse_options_usage(sort_order ? NULL : report_usage, | 929 | |
915 | options, "F", 1); | 930 | if (field_order) { |
916 | goto error; | 931 | pr_err("Error: --hierarchy and --fields options cannot be used together\n"); |
932 | parse_options_usage(report_usage, options, "F", 1); | ||
933 | parse_options_usage(NULL, options, "hierarchy", 0); | ||
934 | goto error; | ||
935 | } | ||
936 | |||
937 | sort__need_collapse = true; | ||
917 | } | 938 | } |
918 | 939 | ||
919 | /* Force tty output for header output and per-thread stat. */ | 940 | /* Force tty output for header output and per-thread stat. */ |
@@ -925,6 +946,15 @@ repeat: | |||
925 | else | 946 | else |
926 | use_browser = 0; | 947 | use_browser = 0; |
927 | 948 | ||
949 | if (setup_sorting(session->evlist) < 0) { | ||
950 | if (sort_order) | ||
951 | parse_options_usage(report_usage, options, "s", 1); | ||
952 | if (field_order) | ||
953 | parse_options_usage(sort_order ? NULL : report_usage, | ||
954 | options, "F", 1); | ||
955 | goto error; | ||
956 | } | ||
957 | |||
928 | if (report.header || report.header_only) { | 958 | if (report.header || report.header_only) { |
929 | perf_session__fprintf_info(session, stdout, | 959 | perf_session__fprintf_info(session, stdout, |
930 | report.show_full_info); | 960 | report.show_full_info); |