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.c58
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
93static int hist_iter__report_callback(struct hist_entry_iter *iter, 96static 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
469static void report__collapse_hists(struct report *rep) 472static 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
499static void report__output_resort(struct report *rep) 506static 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);