diff options
Diffstat (limited to 'tools/perf/builtin-diff.c')
-rw-r--r-- | tools/perf/builtin-diff.c | 50 |
1 files changed, 36 insertions, 14 deletions
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 204fffe22532..8bff543acaab 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c | |||
@@ -60,7 +60,6 @@ static int data__files_cnt; | |||
60 | #define data__for_each_file(i, d) data__for_each_file_start(i, d, 0) | 60 | #define data__for_each_file(i, d) data__for_each_file_start(i, d, 0) |
61 | #define data__for_each_file_new(i, d) data__for_each_file_start(i, d, 1) | 61 | #define data__for_each_file_new(i, d) data__for_each_file_start(i, d, 1) |
62 | 62 | ||
63 | static char diff__default_sort_order[] = "dso,symbol"; | ||
64 | static bool force; | 63 | static bool force; |
65 | static bool show_period; | 64 | static bool show_period; |
66 | static bool show_formula; | 65 | static bool show_formula; |
@@ -220,7 +219,8 @@ static int setup_compute(const struct option *opt, const char *str, | |||
220 | 219 | ||
221 | static double period_percent(struct hist_entry *he, u64 period) | 220 | static double period_percent(struct hist_entry *he, u64 period) |
222 | { | 221 | { |
223 | u64 total = he->hists->stats.total_period; | 222 | u64 total = hists__total_period(he->hists); |
223 | |||
224 | return (period * 100.0) / total; | 224 | return (period * 100.0) / total; |
225 | } | 225 | } |
226 | 226 | ||
@@ -259,11 +259,18 @@ static s64 compute_wdiff(struct hist_entry *he, struct hist_entry *pair) | |||
259 | static int formula_delta(struct hist_entry *he, struct hist_entry *pair, | 259 | static int formula_delta(struct hist_entry *he, struct hist_entry *pair, |
260 | char *buf, size_t size) | 260 | char *buf, size_t size) |
261 | { | 261 | { |
262 | u64 he_total = he->hists->stats.total_period; | ||
263 | u64 pair_total = pair->hists->stats.total_period; | ||
264 | |||
265 | if (symbol_conf.filter_relative) { | ||
266 | he_total = he->hists->stats.total_non_filtered_period; | ||
267 | pair_total = pair->hists->stats.total_non_filtered_period; | ||
268 | } | ||
262 | return scnprintf(buf, size, | 269 | return scnprintf(buf, size, |
263 | "(%" PRIu64 " * 100 / %" PRIu64 ") - " | 270 | "(%" PRIu64 " * 100 / %" PRIu64 ") - " |
264 | "(%" PRIu64 " * 100 / %" PRIu64 ")", | 271 | "(%" PRIu64 " * 100 / %" PRIu64 ")", |
265 | pair->stat.period, pair->hists->stats.total_period, | 272 | pair->stat.period, pair_total, |
266 | he->stat.period, he->hists->stats.total_period); | 273 | he->stat.period, he_total); |
267 | } | 274 | } |
268 | 275 | ||
269 | static int formula_ratio(struct hist_entry *he, struct hist_entry *pair, | 276 | static int formula_ratio(struct hist_entry *he, struct hist_entry *pair, |
@@ -327,16 +334,22 @@ static int diff__process_sample_event(struct perf_tool *tool __maybe_unused, | |||
327 | return -1; | 334 | return -1; |
328 | } | 335 | } |
329 | 336 | ||
330 | if (al.filtered) | ||
331 | return 0; | ||
332 | |||
333 | if (hists__add_entry(&evsel->hists, &al, sample->period, | 337 | if (hists__add_entry(&evsel->hists, &al, sample->period, |
334 | sample->weight, sample->transaction)) { | 338 | sample->weight, sample->transaction)) { |
335 | pr_warning("problem incrementing symbol period, skipping event\n"); | 339 | pr_warning("problem incrementing symbol period, skipping event\n"); |
336 | return -1; | 340 | return -1; |
337 | } | 341 | } |
338 | 342 | ||
343 | /* | ||
344 | * The total_period is updated here before going to the output | ||
345 | * tree since normally only the baseline hists will call | ||
346 | * hists__output_resort() and precompute needs the total | ||
347 | * period in order to sort entries by percentage delta. | ||
348 | */ | ||
339 | evsel->hists.stats.total_period += sample->period; | 349 | evsel->hists.stats.total_period += sample->period; |
350 | if (!al.filtered) | ||
351 | evsel->hists.stats.total_non_filtered_period += sample->period; | ||
352 | |||
340 | return 0; | 353 | return 0; |
341 | } | 354 | } |
342 | 355 | ||
@@ -564,8 +577,7 @@ static void hists__compute_resort(struct hists *hists) | |||
564 | hists->entries = RB_ROOT; | 577 | hists->entries = RB_ROOT; |
565 | next = rb_first(root); | 578 | next = rb_first(root); |
566 | 579 | ||
567 | hists->nr_entries = 0; | 580 | hists__reset_stats(hists); |
568 | hists->stats.total_period = 0; | ||
569 | hists__reset_col_len(hists); | 581 | hists__reset_col_len(hists); |
570 | 582 | ||
571 | while (next != NULL) { | 583 | while (next != NULL) { |
@@ -575,7 +587,10 @@ static void hists__compute_resort(struct hists *hists) | |||
575 | next = rb_next(&he->rb_node_in); | 587 | next = rb_next(&he->rb_node_in); |
576 | 588 | ||
577 | insert_hist_entry_by_compute(&hists->entries, he, compute); | 589 | insert_hist_entry_by_compute(&hists->entries, he, compute); |
578 | hists__inc_nr_entries(hists, he); | 590 | hists__inc_stats(hists, he); |
591 | |||
592 | if (!he->filtered) | ||
593 | hists__calc_col_len(hists, he); | ||
579 | } | 594 | } |
580 | } | 595 | } |
581 | 596 | ||
@@ -725,20 +740,24 @@ static const struct option options[] = { | |||
725 | OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]", | 740 | OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]", |
726 | "only consider these symbols"), | 741 | "only consider these symbols"), |
727 | OPT_STRING('s', "sort", &sort_order, "key[,key2...]", | 742 | OPT_STRING('s', "sort", &sort_order, "key[,key2...]", |
728 | "sort by key(s): pid, comm, dso, symbol, parent"), | 743 | "sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline, ..." |
744 | " Please refer the man page for the complete list."), | ||
729 | OPT_STRING('t', "field-separator", &symbol_conf.field_sep, "separator", | 745 | OPT_STRING('t', "field-separator", &symbol_conf.field_sep, "separator", |
730 | "separator for columns, no spaces will be added between " | 746 | "separator for columns, no spaces will be added between " |
731 | "columns '.' is reserved."), | 747 | "columns '.' is reserved."), |
732 | OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory", | 748 | OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory", |
733 | "Look for files with symbols relative to this directory"), | 749 | "Look for files with symbols relative to this directory"), |
734 | OPT_UINTEGER('o', "order", &sort_compute, "Specify compute sorting."), | 750 | OPT_UINTEGER('o', "order", &sort_compute, "Specify compute sorting."), |
751 | OPT_CALLBACK(0, "percentage", NULL, "relative|absolute", | ||
752 | "How to display percentage of filtered entries", parse_filter_percentage), | ||
735 | OPT_END() | 753 | OPT_END() |
736 | }; | 754 | }; |
737 | 755 | ||
738 | static double baseline_percent(struct hist_entry *he) | 756 | static double baseline_percent(struct hist_entry *he) |
739 | { | 757 | { |
740 | struct hists *hists = he->hists; | 758 | u64 total = hists__total_period(he->hists); |
741 | return 100.0 * he->stat.period / hists->stats.total_period; | 759 | |
760 | return 100.0 * he->stat.period / total; | ||
742 | } | 761 | } |
743 | 762 | ||
744 | static int hpp__color_baseline(struct perf_hpp_fmt *fmt, | 763 | static int hpp__color_baseline(struct perf_hpp_fmt *fmt, |
@@ -1120,7 +1139,8 @@ static int data_init(int argc, const char **argv) | |||
1120 | 1139 | ||
1121 | int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused) | 1140 | int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused) |
1122 | { | 1141 | { |
1123 | sort_order = diff__default_sort_order; | 1142 | perf_config(perf_default_config, NULL); |
1143 | |||
1124 | argc = parse_options(argc, argv, options, diff_usage, 0); | 1144 | argc = parse_options(argc, argv, options, diff_usage, 0); |
1125 | 1145 | ||
1126 | if (symbol__init() < 0) | 1146 | if (symbol__init() < 0) |
@@ -1131,6 +1151,8 @@ int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused) | |||
1131 | 1151 | ||
1132 | ui_init(); | 1152 | ui_init(); |
1133 | 1153 | ||
1154 | sort__mode = SORT_MODE__DIFF; | ||
1155 | |||
1134 | if (setup_sorting() < 0) | 1156 | if (setup_sorting() < 0) |
1135 | usage_with_options(diff_usage, options); | 1157 | usage_with_options(diff_usage, options); |
1136 | 1158 | ||