ae490d58af9203b87d71ab3bb0ac21ddfbfab407
[linux-2.6-block.git] / tools / perf / builtin-diff.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * builtin-diff.c
4  *
5  * Builtin diff command: Analyze two perf.data input files, look up and read
6  * DSOs and symbol information, sort them and produce a diff.
7  */
8 #include "builtin.h"
9 #include "perf.h"
10
11 #include "util/debug.h"
12 #include "util/event.h"
13 #include "util/hist.h"
14 #include "util/evsel.h"
15 #include "util/evlist.h"
16 #include "util/session.h"
17 #include "util/tool.h"
18 #include "util/sort.h"
19 #include "util/srcline.h"
20 #include "util/symbol.h"
21 #include "util/data.h"
22 #include "util/config.h"
23 #include "util/time-utils.h"
24 #include "util/annotate.h"
25 #include "util/map.h"
26 #include "util/spark.h"
27 #include "util/block-info.h"
28 #include "util/stream.h"
29 #include "util/util.h"
30 #include <linux/err.h>
31 #include <linux/zalloc.h>
32 #include <subcmd/pager.h>
33 #include <subcmd/parse-options.h>
34
35 #include <errno.h>
36 #include <inttypes.h>
37 #include <stdlib.h>
38 #include <math.h>
39
40 struct perf_diff {
41         struct perf_tool                 tool;
42         const char                      *time_str;
43         struct perf_time_interval       *ptime_range;
44         int                              range_size;
45         int                              range_num;
46         bool                             has_br_stack;
47         bool                             stream;
48 };
49
50 /* Diff command specific HPP columns. */
51 enum {
52         PERF_HPP_DIFF__BASELINE,
53         PERF_HPP_DIFF__PERIOD,
54         PERF_HPP_DIFF__PERIOD_BASELINE,
55         PERF_HPP_DIFF__DELTA,
56         PERF_HPP_DIFF__RATIO,
57         PERF_HPP_DIFF__WEIGHTED_DIFF,
58         PERF_HPP_DIFF__FORMULA,
59         PERF_HPP_DIFF__DELTA_ABS,
60         PERF_HPP_DIFF__CYCLES,
61         PERF_HPP_DIFF__CYCLES_HIST,
62
63         PERF_HPP_DIFF__MAX_INDEX
64 };
65
66 struct diff_hpp_fmt {
67         struct perf_hpp_fmt      fmt;
68         int                      idx;
69         char                    *header;
70         int                      header_width;
71 };
72
73 struct data__file {
74         struct perf_session     *session;
75         struct perf_data         data;
76         int                      idx;
77         struct hists            *hists;
78         struct evlist_streams   *evlist_streams;
79         struct diff_hpp_fmt      fmt[PERF_HPP_DIFF__MAX_INDEX];
80 };
81
82 static struct data__file *data__files;
83 static int data__files_cnt;
84
85 #define data__for_each_file_start(i, d, s)      \
86         for (i = s, d = &data__files[s];        \
87              i < data__files_cnt;               \
88              i++, d = &data__files[i])
89
90 #define data__for_each_file(i, d) data__for_each_file_start(i, d, 0)
91 #define data__for_each_file_new(i, d) data__for_each_file_start(i, d, 1)
92
93 static bool force;
94 static bool show_period;
95 static bool show_formula;
96 static bool show_baseline_only;
97 static bool cycles_hist;
98 static unsigned int sort_compute = 1;
99
100 static s64 compute_wdiff_w1;
101 static s64 compute_wdiff_w2;
102
103 static const char               *cpu_list;
104 static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
105
106 enum {
107         COMPUTE_DELTA,
108         COMPUTE_RATIO,
109         COMPUTE_WEIGHTED_DIFF,
110         COMPUTE_DELTA_ABS,
111         COMPUTE_CYCLES,
112         COMPUTE_MAX,
113         COMPUTE_STREAM, /* After COMPUTE_MAX to avoid use current compute arrays */
114 };
115
116 const char *compute_names[COMPUTE_MAX] = {
117         [COMPUTE_DELTA] = "delta",
118         [COMPUTE_DELTA_ABS] = "delta-abs",
119         [COMPUTE_RATIO] = "ratio",
120         [COMPUTE_WEIGHTED_DIFF] = "wdiff",
121         [COMPUTE_CYCLES] = "cycles",
122 };
123
124 static int compute = COMPUTE_DELTA_ABS;
125
126 static int compute_2_hpp[COMPUTE_MAX] = {
127         [COMPUTE_DELTA]         = PERF_HPP_DIFF__DELTA,
128         [COMPUTE_DELTA_ABS]     = PERF_HPP_DIFF__DELTA_ABS,
129         [COMPUTE_RATIO]         = PERF_HPP_DIFF__RATIO,
130         [COMPUTE_WEIGHTED_DIFF] = PERF_HPP_DIFF__WEIGHTED_DIFF,
131         [COMPUTE_CYCLES]        = PERF_HPP_DIFF__CYCLES,
132 };
133
134 #define MAX_COL_WIDTH 70
135
136 static struct header_column {
137         const char *name;
138         int width;
139 } columns[PERF_HPP_DIFF__MAX_INDEX] = {
140         [PERF_HPP_DIFF__BASELINE] = {
141                 .name  = "Baseline",
142         },
143         [PERF_HPP_DIFF__PERIOD] = {
144                 .name  = "Period",
145                 .width = 14,
146         },
147         [PERF_HPP_DIFF__PERIOD_BASELINE] = {
148                 .name  = "Base period",
149                 .width = 14,
150         },
151         [PERF_HPP_DIFF__DELTA] = {
152                 .name  = "Delta",
153                 .width = 7,
154         },
155         [PERF_HPP_DIFF__DELTA_ABS] = {
156                 .name  = "Delta Abs",
157                 .width = 7,
158         },
159         [PERF_HPP_DIFF__RATIO] = {
160                 .name  = "Ratio",
161                 .width = 14,
162         },
163         [PERF_HPP_DIFF__WEIGHTED_DIFF] = {
164                 .name  = "Weighted diff",
165                 .width = 14,
166         },
167         [PERF_HPP_DIFF__FORMULA] = {
168                 .name  = "Formula",
169                 .width = MAX_COL_WIDTH,
170         },
171         [PERF_HPP_DIFF__CYCLES] = {
172                 .name  = "[Program Block Range] Cycles Diff",
173                 .width = 70,
174         },
175         [PERF_HPP_DIFF__CYCLES_HIST] = {
176                 .name  = "stddev/Hist",
177                 .width = NUM_SPARKS + 9,
178         }
179 };
180
181 static int setup_compute_opt_wdiff(char *opt)
182 {
183         char *w1_str = opt;
184         char *w2_str;
185
186         int ret = -EINVAL;
187
188         if (!opt)
189                 goto out;
190
191         w2_str = strchr(opt, ',');
192         if (!w2_str)
193                 goto out;
194
195         *w2_str++ = 0x0;
196         if (!*w2_str)
197                 goto out;
198
199         compute_wdiff_w1 = strtol(w1_str, NULL, 10);
200         compute_wdiff_w2 = strtol(w2_str, NULL, 10);
201
202         if (!compute_wdiff_w1 || !compute_wdiff_w2)
203                 goto out;
204
205         pr_debug("compute wdiff w1(%" PRId64 ") w2(%" PRId64 ")\n",
206                   compute_wdiff_w1, compute_wdiff_w2);
207
208         ret = 0;
209
210  out:
211         if (ret)
212                 pr_err("Failed: wrong weight data, use 'wdiff:w1,w2'\n");
213
214         return ret;
215 }
216
217 static int setup_compute_opt(char *opt)
218 {
219         if (compute == COMPUTE_WEIGHTED_DIFF)
220                 return setup_compute_opt_wdiff(opt);
221
222         if (opt) {
223                 pr_err("Failed: extra option specified '%s'", opt);
224                 return -EINVAL;
225         }
226
227         return 0;
228 }
229
230 static int setup_compute(const struct option *opt, const char *str,
231                          int unset __maybe_unused)
232 {
233         int *cp = (int *) opt->value;
234         char *cstr = (char *) str;
235         char buf[50];
236         unsigned i;
237         char *option;
238
239         if (!str) {
240                 *cp = COMPUTE_DELTA;
241                 return 0;
242         }
243
244         option = strchr(str, ':');
245         if (option) {
246                 unsigned len = option++ - str;
247
248                 /*
249                  * The str data are not writeable, so we need
250                  * to use another buffer.
251                  */
252
253                 /* No option value is longer. */
254                 if (len >= sizeof(buf))
255                         return -EINVAL;
256
257                 strncpy(buf, str, len);
258                 buf[len] = 0x0;
259                 cstr = buf;
260         }
261
262         for (i = 0; i < COMPUTE_MAX; i++)
263                 if (!strcmp(cstr, compute_names[i])) {
264                         *cp = i;
265                         return setup_compute_opt(option);
266                 }
267
268         pr_err("Failed: '%s' is not computation method "
269                "(use 'delta','ratio' or 'wdiff')\n", str);
270         return -EINVAL;
271 }
272
273 static double period_percent(struct hist_entry *he, u64 period)
274 {
275         u64 total = hists__total_period(he->hists);
276
277         return (period * 100.0) / total;
278 }
279
280 static double compute_delta(struct hist_entry *he, struct hist_entry *pair)
281 {
282         double old_percent = period_percent(he, he->stat.period);
283         double new_percent = period_percent(pair, pair->stat.period);
284
285         pair->diff.period_ratio_delta = new_percent - old_percent;
286         pair->diff.computed = true;
287         return pair->diff.period_ratio_delta;
288 }
289
290 static double compute_ratio(struct hist_entry *he, struct hist_entry *pair)
291 {
292         double old_period = he->stat.period ?: 1;
293         double new_period = pair->stat.period;
294
295         pair->diff.computed = true;
296         pair->diff.period_ratio = new_period / old_period;
297         return pair->diff.period_ratio;
298 }
299
300 static s64 compute_wdiff(struct hist_entry *he, struct hist_entry *pair)
301 {
302         u64 old_period = he->stat.period;
303         u64 new_period = pair->stat.period;
304
305         pair->diff.computed = true;
306         pair->diff.wdiff = new_period * compute_wdiff_w2 -
307                            old_period * compute_wdiff_w1;
308
309         return pair->diff.wdiff;
310 }
311
312 static int formula_delta(struct hist_entry *he, struct hist_entry *pair,
313                          char *buf, size_t size)
314 {
315         u64 he_total = he->hists->stats.total_period;
316         u64 pair_total = pair->hists->stats.total_period;
317
318         if (symbol_conf.filter_relative) {
319                 he_total = he->hists->stats.total_non_filtered_period;
320                 pair_total = pair->hists->stats.total_non_filtered_period;
321         }
322         return scnprintf(buf, size,
323                          "(%" PRIu64 " * 100 / %" PRIu64 ") - "
324                          "(%" PRIu64 " * 100 / %" PRIu64 ")",
325                          pair->stat.period, pair_total,
326                          he->stat.period, he_total);
327 }
328
329 static int formula_ratio(struct hist_entry *he, struct hist_entry *pair,
330                          char *buf, size_t size)
331 {
332         double old_period = he->stat.period;
333         double new_period = pair->stat.period;
334
335         return scnprintf(buf, size, "%.0F / %.0F", new_period, old_period);
336 }
337
338 static int formula_wdiff(struct hist_entry *he, struct hist_entry *pair,
339                          char *buf, size_t size)
340 {
341         u64 old_period = he->stat.period;
342         u64 new_period = pair->stat.period;
343
344         return scnprintf(buf, size,
345                   "(%" PRIu64 " * " "%" PRId64 ") - (%" PRIu64 " * " "%" PRId64 ")",
346                   new_period, compute_wdiff_w2, old_period, compute_wdiff_w1);
347 }
348
349 static int formula_fprintf(struct hist_entry *he, struct hist_entry *pair,
350                            char *buf, size_t size)
351 {
352         switch (compute) {
353         case COMPUTE_DELTA:
354         case COMPUTE_DELTA_ABS:
355                 return formula_delta(he, pair, buf, size);
356         case COMPUTE_RATIO:
357                 return formula_ratio(he, pair, buf, size);
358         case COMPUTE_WEIGHTED_DIFF:
359                 return formula_wdiff(he, pair, buf, size);
360         default:
361                 BUG_ON(1);
362         }
363
364         return -1;
365 }
366
367 static void *block_hist_zalloc(size_t size)
368 {
369         struct block_hist *bh;
370
371         bh = zalloc(size + sizeof(*bh));
372         if (!bh)
373                 return NULL;
374
375         return &bh->he;
376 }
377
378 static void block_hist_free(void *he)
379 {
380         struct block_hist *bh;
381
382         bh = container_of(he, struct block_hist, he);
383         hists__delete_entries(&bh->block_hists);
384         free(bh);
385 }
386
387 struct hist_entry_ops block_hist_ops = {
388         .new    = block_hist_zalloc,
389         .free   = block_hist_free,
390 };
391
392 static int diff__process_sample_event(const struct perf_tool *tool,
393                                       union perf_event *event,
394                                       struct perf_sample *sample,
395                                       struct evsel *evsel,
396                                       struct machine *machine)
397 {
398         struct perf_diff *pdiff = container_of(tool, struct perf_diff, tool);
399         struct addr_location al;
400         struct hists *hists = evsel__hists(evsel);
401         struct hist_entry_iter iter = {
402                 .evsel  = evsel,
403                 .sample = sample,
404                 .ops    = &hist_iter_normal,
405         };
406         int ret = -1;
407
408         if (perf_time__ranges_skip_sample(pdiff->ptime_range, pdiff->range_num,
409                                           sample->time)) {
410                 return 0;
411         }
412
413         addr_location__init(&al);
414         if (machine__resolve(machine, &al, sample) < 0) {
415                 pr_warning("problem processing %d event, skipping it.\n",
416                            event->header.type);
417                 ret = -1;
418                 goto out;
419         }
420
421         if (cpu_list && !test_bit(sample->cpu, cpu_bitmap)) {
422                 ret = 0;
423                 goto out;
424         }
425
426         switch (compute) {
427         case COMPUTE_CYCLES:
428                 if (!hists__add_entry_ops(hists, &block_hist_ops, &al, NULL,
429                                           NULL, NULL, NULL, sample, true)) {
430                         pr_warning("problem incrementing symbol period, "
431                                    "skipping event\n");
432                         goto out;
433                 }
434
435                 hist__account_cycles(sample->branch_stack, &al, sample,
436                                      false, NULL, evsel);
437                 break;
438
439         case COMPUTE_STREAM:
440                 if (hist_entry_iter__add(&iter, &al, PERF_MAX_STACK_DEPTH,
441                                          NULL)) {
442                         pr_debug("problem adding hist entry, skipping event\n");
443                         goto out;
444                 }
445                 break;
446
447         default:
448                 if (!hists__add_entry(hists, &al, NULL, NULL, NULL, NULL, sample,
449                                       true)) {
450                         pr_warning("problem incrementing symbol period, "
451                                    "skipping event\n");
452                         goto out;
453                 }
454         }
455
456         /*
457          * The total_period is updated here before going to the output
458          * tree since normally only the baseline hists will call
459          * hists__output_resort() and precompute needs the total
460          * period in order to sort entries by percentage delta.
461          */
462         hists->stats.total_period += sample->period;
463         if (!al.filtered)
464                 hists->stats.total_non_filtered_period += sample->period;
465         ret = 0;
466 out:
467         addr_location__exit(&al);
468         return ret;
469 }
470
471 static struct perf_diff pdiff;
472
473 static struct evsel *evsel_match(struct evsel *evsel, struct evlist *evlist)
474 {
475         struct evsel *e;
476
477         evlist__for_each_entry(evlist, e) {
478                 if ((evsel->core.attr.type == e->core.attr.type) &&
479                     (evsel->core.attr.config == e->core.attr.config))
480                         return e;
481         }
482
483         return NULL;
484 }
485
486 static void evlist__collapse_resort(struct evlist *evlist)
487 {
488         struct evsel *evsel;
489
490         evlist__for_each_entry(evlist, evsel) {
491                 struct hists *hists = evsel__hists(evsel);
492
493                 hists__collapse_resort(hists, NULL);
494         }
495 }
496
497 static struct data__file *fmt_to_data_file(struct perf_hpp_fmt *fmt)
498 {
499         struct diff_hpp_fmt *dfmt = container_of(fmt, struct diff_hpp_fmt, fmt);
500         void *ptr = dfmt - dfmt->idx;
501         struct data__file *d = container_of(ptr, struct data__file, fmt);
502
503         return d;
504 }
505
506 static struct hist_entry*
507 get_pair_data(struct hist_entry *he, struct data__file *d)
508 {
509         if (hist_entry__has_pairs(he)) {
510                 struct hist_entry *pair;
511
512                 list_for_each_entry(pair, &he->pairs.head, pairs.node)
513                         if (pair->hists == d->hists)
514                                 return pair;
515         }
516
517         return NULL;
518 }
519
520 static struct hist_entry*
521 get_pair_fmt(struct hist_entry *he, struct diff_hpp_fmt *dfmt)
522 {
523         struct data__file *d = fmt_to_data_file(&dfmt->fmt);
524
525         return get_pair_data(he, d);
526 }
527
528 static void hists__baseline_only(struct hists *hists)
529 {
530         struct rb_root_cached *root;
531         struct rb_node *next;
532
533         if (hists__has(hists, need_collapse))
534                 root = &hists->entries_collapsed;
535         else
536                 root = hists->entries_in;
537
538         next = rb_first_cached(root);
539         while (next != NULL) {
540                 struct hist_entry *he = rb_entry(next, struct hist_entry, rb_node_in);
541
542                 next = rb_next(&he->rb_node_in);
543                 if (!hist_entry__next_pair(he)) {
544                         rb_erase_cached(&he->rb_node_in, root);
545                         hist_entry__delete(he);
546                 }
547         }
548 }
549
550 static int64_t block_cycles_diff_cmp(struct hist_entry *left,
551                                      struct hist_entry *right)
552 {
553         bool pairs_left  = hist_entry__has_pairs(left);
554         bool pairs_right = hist_entry__has_pairs(right);
555         s64 l, r;
556
557         if (!pairs_left && !pairs_right)
558                 return 0;
559
560         l = llabs(left->diff.cycles);
561         r = llabs(right->diff.cycles);
562         return r - l;
563 }
564
565 static int64_t block_sort(struct perf_hpp_fmt *fmt __maybe_unused,
566                           struct hist_entry *left, struct hist_entry *right)
567 {
568         return block_cycles_diff_cmp(right, left);
569 }
570
571 static void init_block_hist(struct block_hist *bh)
572 {
573         __hists__init(&bh->block_hists, &bh->block_list);
574         perf_hpp_list__init(&bh->block_list);
575
576         INIT_LIST_HEAD(&bh->block_fmt.list);
577         INIT_LIST_HEAD(&bh->block_fmt.sort_list);
578         bh->block_fmt.cmp = block_info__cmp;
579         bh->block_fmt.sort = block_sort;
580         perf_hpp_list__register_sort_field(&bh->block_list,
581                                            &bh->block_fmt);
582         bh->valid = true;
583 }
584
585 static struct hist_entry *get_block_pair(struct hist_entry *he,
586                                          struct hists *hists_pair)
587 {
588         struct rb_root_cached *root = hists_pair->entries_in;
589         struct rb_node *next = rb_first_cached(root);
590         int64_t cmp;
591
592         while (next != NULL) {
593                 struct hist_entry *he_pair = rb_entry(next, struct hist_entry,
594                                                       rb_node_in);
595
596                 next = rb_next(&he_pair->rb_node_in);
597
598                 cmp = __block_info__cmp(he_pair, he);
599                 if (!cmp)
600                         return he_pair;
601         }
602
603         return NULL;
604 }
605
606 static void init_spark_values(unsigned long *svals, int num)
607 {
608         for (int i = 0; i < num; i++)
609                 svals[i] = 0;
610 }
611
612 static void update_spark_value(unsigned long *svals, int num,
613                                struct stats *stats, u64 val)
614 {
615         int n = stats->n;
616
617         if (n < num)
618                 svals[n] = val;
619 }
620
621 static void compute_cycles_diff(struct hist_entry *he,
622                                 struct hist_entry *pair)
623 {
624         pair->diff.computed = true;
625         if (pair->block_info->num && he->block_info->num) {
626                 pair->diff.cycles =
627                         pair->block_info->cycles_aggr / pair->block_info->num_aggr -
628                         he->block_info->cycles_aggr / he->block_info->num_aggr;
629
630                 if (!cycles_hist)
631                         return;
632
633                 init_stats(&pair->diff.stats);
634                 init_spark_values(pair->diff.svals, NUM_SPARKS);
635
636                 for (int i = 0; i < pair->block_info->num; i++) {
637                         u64 val;
638
639                         if (i >= he->block_info->num || i >= NUM_SPARKS)
640                                 break;
641
642                         val = llabs(pair->block_info->cycles_spark[i] -
643                                      he->block_info->cycles_spark[i]);
644
645                         update_spark_value(pair->diff.svals, NUM_SPARKS,
646                                            &pair->diff.stats, val);
647                         update_stats(&pair->diff.stats, val);
648                 }
649         }
650 }
651
652 static void block_hists_match(struct hists *hists_base,
653                               struct hists *hists_pair)
654 {
655         struct rb_root_cached *root = hists_base->entries_in;
656         struct rb_node *next = rb_first_cached(root);
657
658         while (next != NULL) {
659                 struct hist_entry *he = rb_entry(next, struct hist_entry,
660                                                  rb_node_in);
661                 struct hist_entry *pair = get_block_pair(he, hists_pair);
662
663                 next = rb_next(&he->rb_node_in);
664
665                 if (pair) {
666                         hist_entry__add_pair(pair, he);
667                         compute_cycles_diff(he, pair);
668                 }
669         }
670 }
671
672 static void hists__precompute(struct hists *hists)
673 {
674         struct rb_root_cached *root;
675         struct rb_node *next;
676
677         if (hists__has(hists, need_collapse))
678                 root = &hists->entries_collapsed;
679         else
680                 root = hists->entries_in;
681
682         next = rb_first_cached(root);
683         while (next != NULL) {
684                 struct block_hist *bh, *pair_bh;
685                 struct hist_entry *he, *pair;
686                 struct data__file *d;
687                 int i;
688
689                 he   = rb_entry(next, struct hist_entry, rb_node_in);
690                 next = rb_next(&he->rb_node_in);
691
692                 if (compute == COMPUTE_CYCLES) {
693                         bh = container_of(he, struct block_hist, he);
694                         init_block_hist(bh);
695                         block_info__process_sym(he, bh, NULL, 0, 0);
696                 }
697
698                 data__for_each_file_new(i, d) {
699                         pair = get_pair_data(he, d);
700                         if (!pair)
701                                 continue;
702
703                         switch (compute) {
704                         case COMPUTE_DELTA:
705                         case COMPUTE_DELTA_ABS:
706                                 compute_delta(he, pair);
707                                 break;
708                         case COMPUTE_RATIO:
709                                 compute_ratio(he, pair);
710                                 break;
711                         case COMPUTE_WEIGHTED_DIFF:
712                                 compute_wdiff(he, pair);
713                                 break;
714                         case COMPUTE_CYCLES:
715                                 pair_bh = container_of(pair, struct block_hist,
716                                                        he);
717                                 init_block_hist(pair_bh);
718                                 block_info__process_sym(pair, pair_bh, NULL, 0, 0);
719
720                                 bh = container_of(he, struct block_hist, he);
721
722                                 if (bh->valid && pair_bh->valid) {
723                                         block_hists_match(&bh->block_hists,
724                                                           &pair_bh->block_hists);
725                                         hists__output_resort(&pair_bh->block_hists,
726                                                              NULL);
727                                 }
728                                 break;
729                         default:
730                                 BUG_ON(1);
731                         }
732                 }
733         }
734 }
735
736 static int64_t cmp_doubles(double l, double r)
737 {
738         if (l > r)
739                 return -1;
740         else if (l < r)
741                 return 1;
742         else
743                 return 0;
744 }
745
746 static int64_t
747 __hist_entry__cmp_compute(struct hist_entry *left, struct hist_entry *right,
748                         int c)
749 {
750         switch (c) {
751         case COMPUTE_DELTA:
752         {
753                 double l = left->diff.period_ratio_delta;
754                 double r = right->diff.period_ratio_delta;
755
756                 return cmp_doubles(l, r);
757         }
758         case COMPUTE_DELTA_ABS:
759         {
760                 double l = fabs(left->diff.period_ratio_delta);
761                 double r = fabs(right->diff.period_ratio_delta);
762
763                 return cmp_doubles(l, r);
764         }
765         case COMPUTE_RATIO:
766         {
767                 double l = left->diff.period_ratio;
768                 double r = right->diff.period_ratio;
769
770                 return cmp_doubles(l, r);
771         }
772         case COMPUTE_WEIGHTED_DIFF:
773         {
774                 s64 l = left->diff.wdiff;
775                 s64 r = right->diff.wdiff;
776
777                 return r - l;
778         }
779         default:
780                 BUG_ON(1);
781         }
782
783         return 0;
784 }
785
786 static int64_t
787 hist_entry__cmp_compute(struct hist_entry *left, struct hist_entry *right,
788                         int c, int sort_idx)
789 {
790         bool pairs_left  = hist_entry__has_pairs(left);
791         bool pairs_right = hist_entry__has_pairs(right);
792         struct hist_entry *p_right, *p_left;
793
794         if (!pairs_left && !pairs_right)
795                 return 0;
796
797         if (!pairs_left || !pairs_right)
798                 return pairs_left ? -1 : 1;
799
800         p_left  = get_pair_data(left,  &data__files[sort_idx]);
801         p_right = get_pair_data(right, &data__files[sort_idx]);
802
803         if (!p_left && !p_right)
804                 return 0;
805
806         if (!p_left || !p_right)
807                 return p_left ? -1 : 1;
808
809         /*
810          * We have 2 entries of same kind, let's
811          * make the data comparison.
812          */
813         return __hist_entry__cmp_compute(p_left, p_right, c);
814 }
815
816 static int64_t
817 hist_entry__cmp_compute_idx(struct hist_entry *left, struct hist_entry *right,
818                             int c, int sort_idx)
819 {
820         struct hist_entry *p_right, *p_left;
821
822         p_left  = get_pair_data(left,  &data__files[sort_idx]);
823         p_right = get_pair_data(right, &data__files[sort_idx]);
824
825         if (!p_left && !p_right)
826                 return 0;
827
828         if (!p_left || !p_right)
829                 return p_left ? -1 : 1;
830
831         if (c != COMPUTE_DELTA && c != COMPUTE_DELTA_ABS) {
832                 /*
833                  * The delta can be computed without the baseline, but
834                  * others are not.  Put those entries which have no
835                  * values below.
836                  */
837                 if (left->dummy && right->dummy)
838                         return 0;
839
840                 if (left->dummy || right->dummy)
841                         return left->dummy ? 1 : -1;
842         }
843
844         return __hist_entry__cmp_compute(p_left, p_right, c);
845 }
846
847 static int64_t
848 hist_entry__cmp_nop(struct perf_hpp_fmt *fmt __maybe_unused,
849                     struct hist_entry *left __maybe_unused,
850                     struct hist_entry *right __maybe_unused)
851 {
852         return 0;
853 }
854
855 static int64_t
856 hist_entry__cmp_baseline(struct perf_hpp_fmt *fmt __maybe_unused,
857                          struct hist_entry *left, struct hist_entry *right)
858 {
859         if (left->stat.period == right->stat.period)
860                 return 0;
861         return left->stat.period > right->stat.period ? 1 : -1;
862 }
863
864 static int64_t
865 hist_entry__cmp_delta(struct perf_hpp_fmt *fmt,
866                       struct hist_entry *left, struct hist_entry *right)
867 {
868         struct data__file *d = fmt_to_data_file(fmt);
869
870         return hist_entry__cmp_compute(right, left, COMPUTE_DELTA, d->idx);
871 }
872
873 static int64_t
874 hist_entry__cmp_delta_abs(struct perf_hpp_fmt *fmt,
875                       struct hist_entry *left, struct hist_entry *right)
876 {
877         struct data__file *d = fmt_to_data_file(fmt);
878
879         return hist_entry__cmp_compute(right, left, COMPUTE_DELTA_ABS, d->idx);
880 }
881
882 static int64_t
883 hist_entry__cmp_ratio(struct perf_hpp_fmt *fmt,
884                       struct hist_entry *left, struct hist_entry *right)
885 {
886         struct data__file *d = fmt_to_data_file(fmt);
887
888         return hist_entry__cmp_compute(right, left, COMPUTE_RATIO, d->idx);
889 }
890
891 static int64_t
892 hist_entry__cmp_wdiff(struct perf_hpp_fmt *fmt,
893                       struct hist_entry *left, struct hist_entry *right)
894 {
895         struct data__file *d = fmt_to_data_file(fmt);
896
897         return hist_entry__cmp_compute(right, left, COMPUTE_WEIGHTED_DIFF, d->idx);
898 }
899
900 static int64_t
901 hist_entry__cmp_delta_idx(struct perf_hpp_fmt *fmt __maybe_unused,
902                           struct hist_entry *left, struct hist_entry *right)
903 {
904         return hist_entry__cmp_compute_idx(right, left, COMPUTE_DELTA,
905                                            sort_compute);
906 }
907
908 static int64_t
909 hist_entry__cmp_delta_abs_idx(struct perf_hpp_fmt *fmt __maybe_unused,
910                               struct hist_entry *left, struct hist_entry *right)
911 {
912         return hist_entry__cmp_compute_idx(right, left, COMPUTE_DELTA_ABS,
913                                            sort_compute);
914 }
915
916 static int64_t
917 hist_entry__cmp_ratio_idx(struct perf_hpp_fmt *fmt __maybe_unused,
918                           struct hist_entry *left, struct hist_entry *right)
919 {
920         return hist_entry__cmp_compute_idx(right, left, COMPUTE_RATIO,
921                                            sort_compute);
922 }
923
924 static int64_t
925 hist_entry__cmp_wdiff_idx(struct perf_hpp_fmt *fmt __maybe_unused,
926                           struct hist_entry *left, struct hist_entry *right)
927 {
928         return hist_entry__cmp_compute_idx(right, left, COMPUTE_WEIGHTED_DIFF,
929                                            sort_compute);
930 }
931
932 static void hists__process(struct hists *hists)
933 {
934         if (show_baseline_only)
935                 hists__baseline_only(hists);
936
937         hists__precompute(hists);
938         hists__output_resort(hists, NULL);
939
940         if (compute == COMPUTE_CYCLES)
941                 symbol_conf.report_block = true;
942
943         hists__fprintf(hists, !quiet, 0, 0, 0, stdout,
944                        !symbol_conf.use_callchain);
945 }
946
947 static void data__fprintf(void)
948 {
949         struct data__file *d;
950         int i;
951
952         fprintf(stdout, "# Data files:\n");
953
954         data__for_each_file(i, d)
955                 fprintf(stdout, "#  [%d] %s %s\n",
956                         d->idx, d->data.path,
957                         !d->idx ? "(Baseline)" : "");
958
959         fprintf(stdout, "#\n");
960 }
961
962 static void data_process(void)
963 {
964         struct evlist *evlist_base = data__files[0].session->evlist;
965         struct evsel *evsel_base;
966         bool first = true;
967
968         evlist__for_each_entry(evlist_base, evsel_base) {
969                 struct hists *hists_base = evsel__hists(evsel_base);
970                 struct data__file *d;
971                 int i;
972
973                 data__for_each_file_new(i, d) {
974                         struct evlist *evlist = d->session->evlist;
975                         struct evsel *evsel;
976                         struct hists *hists;
977
978                         evsel = evsel_match(evsel_base, evlist);
979                         if (!evsel)
980                                 continue;
981
982                         hists = evsel__hists(evsel);
983                         d->hists = hists;
984
985                         hists__match(hists_base, hists);
986
987                         if (!show_baseline_only)
988                                 hists__link(hists_base, hists);
989                 }
990
991                 if (!quiet) {
992                         fprintf(stdout, "%s# Event '%s'\n#\n", first ? "" : "\n",
993                                 evsel__name(evsel_base));
994                 }
995
996                 first = false;
997
998                 if (verbose > 0 || ((data__files_cnt > 2) && !quiet))
999                         data__fprintf();
1000
1001                 /* Don't sort callchain for perf diff */
1002                 evsel__reset_sample_bit(evsel_base, CALLCHAIN);
1003
1004                 hists__process(hists_base);
1005         }
1006 }
1007
1008 static int process_base_stream(struct data__file *data_base,
1009                                struct data__file *data_pair,
1010                                const char *title __maybe_unused)
1011 {
1012         struct evlist *evlist_base = data_base->session->evlist;
1013         struct evlist *evlist_pair = data_pair->session->evlist;
1014         struct evsel *evsel_base, *evsel_pair;
1015         struct evsel_streams *es_base, *es_pair;
1016
1017         evlist__for_each_entry(evlist_base, evsel_base) {
1018                 evsel_pair = evsel_match(evsel_base, evlist_pair);
1019                 if (!evsel_pair)
1020                         continue;
1021
1022                 es_base = evsel_streams__entry(data_base->evlist_streams,
1023                                                evsel_base);
1024                 if (!es_base)
1025                         return -1;
1026
1027                 es_pair = evsel_streams__entry(data_pair->evlist_streams,
1028                                                evsel_pair);
1029                 if (!es_pair)
1030                         return -1;
1031
1032                 evsel_streams__match(es_base, es_pair);
1033                 evsel_streams__report(es_base, es_pair);
1034         }
1035
1036         return 0;
1037 }
1038
1039 static void stream_process(void)
1040 {
1041         /*
1042          * Stream comparison only supports two data files.
1043          * perf.data.old and perf.data. data__files[0] is perf.data.old,
1044          * data__files[1] is perf.data.
1045          */
1046         process_base_stream(&data__files[0], &data__files[1],
1047                             "# Output based on old perf data:\n#\n");
1048 }
1049
1050 static void data__free(struct data__file *d)
1051 {
1052         int col;
1053
1054         if (d->evlist_streams)
1055                 evlist_streams__delete(d->evlist_streams);
1056
1057         for (col = 0; col < PERF_HPP_DIFF__MAX_INDEX; col++) {
1058                 struct diff_hpp_fmt *fmt = &d->fmt[col];
1059
1060                 zfree(&fmt->header);
1061         }
1062 }
1063
1064 static int abstime_str_dup(char **pstr)
1065 {
1066         char *str = NULL;
1067
1068         if (pdiff.time_str && strchr(pdiff.time_str, ':')) {
1069                 str = strdup(pdiff.time_str);
1070                 if (!str)
1071                         return -ENOMEM;
1072         }
1073
1074         *pstr = str;
1075         return 0;
1076 }
1077
1078 static int parse_absolute_time(struct data__file *d, char **pstr)
1079 {
1080         char *p = *pstr;
1081         int ret;
1082
1083         /*
1084          * Absolute timestamp for one file has the format: a.b,c.d
1085          * For multiple files, the format is: a.b,c.d:a.b,c.d
1086          */
1087         p = strchr(*pstr, ':');
1088         if (p) {
1089                 if (p == *pstr) {
1090                         pr_err("Invalid time string\n");
1091                         return -EINVAL;
1092                 }
1093
1094                 *p = 0;
1095                 p++;
1096                 if (*p == 0) {
1097                         pr_err("Invalid time string\n");
1098                         return -EINVAL;
1099                 }
1100         }
1101
1102         ret = perf_time__parse_for_ranges(*pstr, d->session,
1103                                           &pdiff.ptime_range,
1104                                           &pdiff.range_size,
1105                                           &pdiff.range_num);
1106         if (ret < 0)
1107                 return ret;
1108
1109         if (!p || *p == 0)
1110                 *pstr = NULL;
1111         else
1112                 *pstr = p;
1113
1114         return ret;
1115 }
1116
1117 static int parse_percent_time(struct data__file *d)
1118 {
1119         int ret;
1120
1121         ret = perf_time__parse_for_ranges(pdiff.time_str, d->session,
1122                                           &pdiff.ptime_range,
1123                                           &pdiff.range_size,
1124                                           &pdiff.range_num);
1125         return ret;
1126 }
1127
1128 static int parse_time_str(struct data__file *d, char *abstime_ostr,
1129                            char **pabstime_tmp)
1130 {
1131         int ret = 0;
1132
1133         if (abstime_ostr)
1134                 ret = parse_absolute_time(d, pabstime_tmp);
1135         else if (pdiff.time_str)
1136                 ret = parse_percent_time(d);
1137
1138         return ret;
1139 }
1140
1141 static int check_file_brstack(void)
1142 {
1143         struct data__file *d;
1144         bool has_br_stack;
1145         int i;
1146
1147         data__for_each_file(i, d) {
1148                 d->session = perf_session__new(&d->data, &pdiff.tool);
1149                 if (IS_ERR(d->session)) {
1150                         pr_err("Failed to open %s\n", d->data.path);
1151                         return PTR_ERR(d->session);
1152                 }
1153
1154                 has_br_stack = perf_header__has_feat(&d->session->header,
1155                                                      HEADER_BRANCH_STACK);
1156                 perf_session__delete(d->session);
1157                 if (!has_br_stack)
1158                         return 0;
1159         }
1160
1161         /* Set only all files having branch stacks */
1162         pdiff.has_br_stack = true;
1163         return 0;
1164 }
1165
1166 static int __cmd_diff(void)
1167 {
1168         struct data__file *d;
1169         int ret, i;
1170         char *abstime_ostr, *abstime_tmp;
1171
1172         ret = abstime_str_dup(&abstime_ostr);
1173         if (ret)
1174                 return ret;
1175
1176         abstime_tmp = abstime_ostr;
1177         ret = -EINVAL;
1178
1179         data__for_each_file(i, d) {
1180                 d->session = perf_session__new(&d->data, &pdiff.tool);
1181                 if (IS_ERR(d->session)) {
1182                         ret = PTR_ERR(d->session);
1183                         pr_err("Failed to open %s\n", d->data.path);
1184                         goto out_delete;
1185                 }
1186
1187                 if (pdiff.time_str) {
1188                         ret = parse_time_str(d, abstime_ostr, &abstime_tmp);
1189                         if (ret < 0)
1190                                 goto out_delete;
1191                 }
1192
1193                 if (cpu_list) {
1194                         ret = perf_session__cpu_bitmap(d->session, cpu_list,
1195                                                        cpu_bitmap);
1196                         if (ret < 0)
1197                                 goto out_delete;
1198                 }
1199
1200                 ret = perf_session__process_events(d->session);
1201                 if (ret) {
1202                         pr_err("Failed to process %s\n", d->data.path);
1203                         goto out_delete;
1204                 }
1205
1206                 evlist__collapse_resort(d->session->evlist);
1207
1208                 if (pdiff.ptime_range)
1209                         zfree(&pdiff.ptime_range);
1210
1211                 if (compute == COMPUTE_STREAM) {
1212                         d->evlist_streams = evlist__create_streams(
1213                                                 d->session->evlist, 5);
1214                         if (!d->evlist_streams) {
1215                                 ret = -ENOMEM;
1216                                 goto out_delete;
1217                         }
1218                 }
1219         }
1220
1221         if (compute == COMPUTE_STREAM)
1222                 stream_process();
1223         else
1224                 data_process();
1225
1226  out_delete:
1227         data__for_each_file(i, d) {
1228                 if (!IS_ERR(d->session))
1229                         perf_session__delete(d->session);
1230                 data__free(d);
1231         }
1232
1233         free(data__files);
1234
1235         if (pdiff.ptime_range)
1236                 zfree(&pdiff.ptime_range);
1237
1238         if (abstime_ostr)
1239                 free(abstime_ostr);
1240
1241         return ret;
1242 }
1243
1244 static const char * const diff_usage[] = {
1245         "perf diff [<options>] [old_file] [new_file]",
1246         NULL,
1247 };
1248
1249 static const struct option options[] = {
1250         OPT_INCR('v', "verbose", &verbose,
1251                     "be more verbose (show symbol address, etc)"),
1252         OPT_BOOLEAN('q', "quiet", &quiet, "Do not show any warnings or messages"),
1253         OPT_BOOLEAN('b', "baseline-only", &show_baseline_only,
1254                     "Show only items with match in baseline"),
1255         OPT_CALLBACK('c', "compute", &compute,
1256                      "delta,delta-abs,ratio,wdiff:w1,w2 (default delta-abs),cycles",
1257                      "Entries differential computation selection",
1258                      setup_compute),
1259         OPT_BOOLEAN('p', "period", &show_period,
1260                     "Show period values."),
1261         OPT_BOOLEAN('F', "formula", &show_formula,
1262                     "Show formula."),
1263         OPT_BOOLEAN(0, "cycles-hist", &cycles_hist,
1264                     "Show cycles histogram and standard deviation "
1265                     "- WARNING: use only with -c cycles."),
1266         OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
1267                     "dump raw trace in ASCII"),
1268         OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
1269         OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name,
1270                    "file", "kallsyms pathname"),
1271         OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules,
1272                     "load module symbols - WARNING: use only with -k and LIVE kernel"),
1273         OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
1274                    "only consider symbols in these dsos"),
1275         OPT_STRING('C', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
1276                    "only consider symbols in these comms"),
1277         OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
1278                    "only consider these symbols"),
1279         OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
1280                    "sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline, ..."
1281                    " Please refer the man page for the complete list."),
1282         OPT_STRING_NOEMPTY('t', "field-separator", &symbol_conf.field_sep, "separator",
1283                    "separator for columns, no spaces will be added between "
1284                    "columns '.' is reserved."),
1285         OPT_CALLBACK(0, "symfs", NULL, "directory",
1286                      "Look for files with symbols relative to this directory",
1287                      symbol__config_symfs),
1288         OPT_UINTEGER('o', "order", &sort_compute, "Specify compute sorting."),
1289         OPT_CALLBACK(0, "percentage", NULL, "relative|absolute",
1290                      "How to display percentage of filtered entries", parse_filter_percentage),
1291         OPT_STRING(0, "time", &pdiff.time_str, "str",
1292                    "Time span (time percent or absolute timestamp)"),
1293         OPT_STRING(0, "cpu", &cpu_list, "cpu", "list of cpus to profile"),
1294         OPT_STRING(0, "pid", &symbol_conf.pid_list_str, "pid[,pid...]",
1295                    "only consider symbols in these pids"),
1296         OPT_STRING(0, "tid", &symbol_conf.tid_list_str, "tid[,tid...]",
1297                    "only consider symbols in these tids"),
1298         OPT_BOOLEAN(0, "stream", &pdiff.stream,
1299                     "Enable hot streams comparison."),
1300         OPT_END()
1301 };
1302
1303 static double baseline_percent(struct hist_entry *he)
1304 {
1305         u64 total = hists__total_period(he->hists);
1306
1307         return 100.0 * he->stat.period / total;
1308 }
1309
1310 static int hpp__color_baseline(struct perf_hpp_fmt *fmt,
1311                                struct perf_hpp *hpp, struct hist_entry *he)
1312 {
1313         struct diff_hpp_fmt *dfmt =
1314                 container_of(fmt, struct diff_hpp_fmt, fmt);
1315         double percent = baseline_percent(he);
1316         char pfmt[20] = " ";
1317
1318         if (!he->dummy) {
1319                 scnprintf(pfmt, 20, "%%%d.2f%%%%", dfmt->header_width - 1);
1320                 return percent_color_snprintf(hpp->buf, hpp->size,
1321                                               pfmt, percent);
1322         } else
1323                 return scnprintf(hpp->buf, hpp->size, "%*s",
1324                                  dfmt->header_width, pfmt);
1325 }
1326
1327 static int hpp__entry_baseline(struct hist_entry *he, char *buf, size_t size)
1328 {
1329         double percent = baseline_percent(he);
1330         const char *fmt = symbol_conf.field_sep ? "%.2f" : "%6.2f%%";
1331         int ret = 0;
1332
1333         if (!he->dummy)
1334                 ret = scnprintf(buf, size, fmt, percent);
1335
1336         return ret;
1337 }
1338
1339 static int cycles_printf(struct hist_entry *he, struct hist_entry *pair,
1340                          struct perf_hpp *hpp, int width)
1341 {
1342         struct block_hist *bh = container_of(he, struct block_hist, he);
1343         struct block_hist *bh_pair = container_of(pair, struct block_hist, he);
1344         struct hist_entry *block_he;
1345         struct block_info *bi;
1346         char buf[128];
1347         char *start_line, *end_line;
1348
1349         block_he = hists__get_entry(&bh_pair->block_hists, bh->block_idx);
1350         if (!block_he) {
1351                 hpp->skip = true;
1352                 return 0;
1353         }
1354
1355         /*
1356          * Avoid printing the warning "addr2line_init failed for ..."
1357          */
1358         symbol_conf.disable_add2line_warn = true;
1359
1360         bi = block_he->block_info;
1361
1362         start_line = map__srcline(he->ms.map, bi->sym->start + bi->start,
1363                                   he->ms.sym);
1364
1365         end_line = map__srcline(he->ms.map, bi->sym->start + bi->end,
1366                                 he->ms.sym);
1367
1368         if (start_line != SRCLINE_UNKNOWN &&
1369             end_line != SRCLINE_UNKNOWN) {
1370                 scnprintf(buf, sizeof(buf), "[%s -> %s] %4ld",
1371                           start_line, end_line, block_he->diff.cycles);
1372         } else {
1373                 scnprintf(buf, sizeof(buf), "[%7lx -> %7lx] %4ld",
1374                           bi->start, bi->end, block_he->diff.cycles);
1375         }
1376
1377         zfree_srcline(&start_line);
1378         zfree_srcline(&end_line);
1379
1380         return scnprintf(hpp->buf, hpp->size, "%*s", width, buf);
1381 }
1382
1383 static int __hpp__color_compare(struct perf_hpp_fmt *fmt,
1384                                 struct perf_hpp *hpp, struct hist_entry *he,
1385                                 int comparison_method)
1386 {
1387         struct diff_hpp_fmt *dfmt =
1388                 container_of(fmt, struct diff_hpp_fmt, fmt);
1389         struct hist_entry *pair = get_pair_fmt(he, dfmt);
1390         double diff;
1391         s64 wdiff;
1392         char pfmt[20] = " ";
1393
1394         if (!pair) {
1395                 if (comparison_method == COMPUTE_CYCLES) {
1396                         struct block_hist *bh;
1397
1398                         bh = container_of(he, struct block_hist, he);
1399                         if (bh->block_idx)
1400                                 hpp->skip = true;
1401                 }
1402
1403                 goto no_print;
1404         }
1405
1406         switch (comparison_method) {
1407         case COMPUTE_DELTA:
1408                 if (pair->diff.computed)
1409                         diff = pair->diff.period_ratio_delta;
1410                 else
1411                         diff = compute_delta(he, pair);
1412
1413                 scnprintf(pfmt, 20, "%%%+d.2f%%%%", dfmt->header_width - 1);
1414                 return percent_color_snprintf(hpp->buf, hpp->size,
1415                                         pfmt, diff);
1416         case COMPUTE_RATIO:
1417                 if (he->dummy)
1418                         goto dummy_print;
1419                 if (pair->diff.computed)
1420                         diff = pair->diff.period_ratio;
1421                 else
1422                         diff = compute_ratio(he, pair);
1423
1424                 scnprintf(pfmt, 20, "%%%d.6f", dfmt->header_width);
1425                 return value_color_snprintf(hpp->buf, hpp->size,
1426                                         pfmt, diff);
1427         case COMPUTE_WEIGHTED_DIFF:
1428                 if (he->dummy)
1429                         goto dummy_print;
1430                 if (pair->diff.computed)
1431                         wdiff = pair->diff.wdiff;
1432                 else
1433                         wdiff = compute_wdiff(he, pair);
1434
1435                 scnprintf(pfmt, 20, "%%14ld", dfmt->header_width);
1436                 return color_snprintf(hpp->buf, hpp->size,
1437                                 get_percent_color(wdiff),
1438                                 pfmt, wdiff);
1439         case COMPUTE_CYCLES:
1440                 return cycles_printf(he, pair, hpp, dfmt->header_width);
1441         default:
1442                 BUG_ON(1);
1443         }
1444 dummy_print:
1445         return scnprintf(hpp->buf, hpp->size, "%*s",
1446                         dfmt->header_width, "N/A");
1447 no_print:
1448         return scnprintf(hpp->buf, hpp->size, "%*s",
1449                         dfmt->header_width, pfmt);
1450 }
1451
1452 static int hpp__color_delta(struct perf_hpp_fmt *fmt,
1453                         struct perf_hpp *hpp, struct hist_entry *he)
1454 {
1455         return __hpp__color_compare(fmt, hpp, he, COMPUTE_DELTA);
1456 }
1457
1458 static int hpp__color_ratio(struct perf_hpp_fmt *fmt,
1459                         struct perf_hpp *hpp, struct hist_entry *he)
1460 {
1461         return __hpp__color_compare(fmt, hpp, he, COMPUTE_RATIO);
1462 }
1463
1464 static int hpp__color_wdiff(struct perf_hpp_fmt *fmt,
1465                         struct perf_hpp *hpp, struct hist_entry *he)
1466 {
1467         return __hpp__color_compare(fmt, hpp, he, COMPUTE_WEIGHTED_DIFF);
1468 }
1469
1470 static int hpp__color_cycles(struct perf_hpp_fmt *fmt,
1471                              struct perf_hpp *hpp, struct hist_entry *he)
1472 {
1473         return __hpp__color_compare(fmt, hpp, he, COMPUTE_CYCLES);
1474 }
1475
1476 static int all_zero(unsigned long *vals, int len)
1477 {
1478         int i;
1479
1480         for (i = 0; i < len; i++)
1481                 if (vals[i] != 0)
1482                         return 0;
1483         return 1;
1484 }
1485
1486 static int print_cycles_spark(char *bf, int size, unsigned long *svals, u64 n)
1487 {
1488         int printed;
1489
1490         if (n <= 1)
1491                 return 0;
1492
1493         if (n > NUM_SPARKS)
1494                 n = NUM_SPARKS;
1495         if (all_zero(svals, n))
1496                 return 0;
1497
1498         printed = print_spark(bf, size, svals, n);
1499         printed += scnprintf(bf + printed, size - printed, " ");
1500         return printed;
1501 }
1502
1503 static int hpp__color_cycles_hist(struct perf_hpp_fmt *fmt,
1504                             struct perf_hpp *hpp, struct hist_entry *he)
1505 {
1506         struct diff_hpp_fmt *dfmt =
1507                 container_of(fmt, struct diff_hpp_fmt, fmt);
1508         struct hist_entry *pair = get_pair_fmt(he, dfmt);
1509         struct block_hist *bh = container_of(he, struct block_hist, he);
1510         struct block_hist *bh_pair;
1511         struct hist_entry *block_he;
1512         char spark[32], buf[128];
1513         double r;
1514         int ret, pad;
1515
1516         if (!pair) {
1517                 if (bh->block_idx)
1518                         hpp->skip = true;
1519
1520                 goto no_print;
1521         }
1522
1523         bh_pair = container_of(pair, struct block_hist, he);
1524
1525         block_he = hists__get_entry(&bh_pair->block_hists, bh->block_idx);
1526         if (!block_he) {
1527                 hpp->skip = true;
1528                 goto no_print;
1529         }
1530
1531         ret = print_cycles_spark(spark, sizeof(spark), block_he->diff.svals,
1532                                  block_he->diff.stats.n);
1533
1534         r = rel_stddev_stats(stddev_stats(&block_he->diff.stats),
1535                              avg_stats(&block_he->diff.stats));
1536
1537         if (ret) {
1538                 /*
1539                  * Padding spaces if number of sparks less than NUM_SPARKS
1540                  * otherwise the output is not aligned.
1541                  */
1542                 pad = NUM_SPARKS - ((ret - 1) / 3);
1543                 scnprintf(buf, sizeof(buf), "%s%5.1f%% %s", "\u00B1", r, spark);
1544                 ret = scnprintf(hpp->buf, hpp->size, "%*s",
1545                                 dfmt->header_width, buf);
1546
1547                 if (pad) {
1548                         ret += scnprintf(hpp->buf + ret, hpp->size - ret,
1549                                          "%-*s", pad, " ");
1550                 }
1551
1552                 return ret;
1553         }
1554
1555 no_print:
1556         return scnprintf(hpp->buf, hpp->size, "%*s",
1557                         dfmt->header_width, " ");
1558 }
1559
1560 static void
1561 hpp__entry_unpair(struct hist_entry *he, int idx, char *buf, size_t size)
1562 {
1563         switch (idx) {
1564         case PERF_HPP_DIFF__PERIOD_BASELINE:
1565                 scnprintf(buf, size, "%" PRIu64, he->stat.period);
1566                 break;
1567
1568         default:
1569                 break;
1570         }
1571 }
1572
1573 static void
1574 hpp__entry_pair(struct hist_entry *he, struct hist_entry *pair,
1575                 int idx, char *buf, size_t size)
1576 {
1577         double diff;
1578         double ratio;
1579         s64 wdiff;
1580
1581         switch (idx) {
1582         case PERF_HPP_DIFF__DELTA:
1583         case PERF_HPP_DIFF__DELTA_ABS:
1584                 if (pair->diff.computed)
1585                         diff = pair->diff.period_ratio_delta;
1586                 else
1587                         diff = compute_delta(he, pair);
1588
1589                 scnprintf(buf, size, "%+4.2F%%", diff);
1590                 break;
1591
1592         case PERF_HPP_DIFF__RATIO:
1593                 /* No point for ratio number if we are dummy.. */
1594                 if (he->dummy) {
1595                         scnprintf(buf, size, "N/A");
1596                         break;
1597                 }
1598
1599                 if (pair->diff.computed)
1600                         ratio = pair->diff.period_ratio;
1601                 else
1602                         ratio = compute_ratio(he, pair);
1603
1604                 if (ratio > 0.0)
1605                         scnprintf(buf, size, "%14.6F", ratio);
1606                 break;
1607
1608         case PERF_HPP_DIFF__WEIGHTED_DIFF:
1609                 /* No point for wdiff number if we are dummy.. */
1610                 if (he->dummy) {
1611                         scnprintf(buf, size, "N/A");
1612                         break;
1613                 }
1614
1615                 if (pair->diff.computed)
1616                         wdiff = pair->diff.wdiff;
1617                 else
1618                         wdiff = compute_wdiff(he, pair);
1619
1620                 if (wdiff != 0)
1621                         scnprintf(buf, size, "%14ld", wdiff);
1622                 break;
1623
1624         case PERF_HPP_DIFF__FORMULA:
1625                 formula_fprintf(he, pair, buf, size);
1626                 break;
1627
1628         case PERF_HPP_DIFF__PERIOD:
1629                 scnprintf(buf, size, "%" PRIu64, pair->stat.period);
1630                 break;
1631
1632         default:
1633                 BUG_ON(1);
1634         }
1635 }
1636
1637 static void
1638 __hpp__entry_global(struct hist_entry *he, struct diff_hpp_fmt *dfmt,
1639                     char *buf, size_t size)
1640 {
1641         struct hist_entry *pair = get_pair_fmt(he, dfmt);
1642         int idx = dfmt->idx;
1643
1644         /* baseline is special */
1645         if (idx == PERF_HPP_DIFF__BASELINE)
1646                 hpp__entry_baseline(he, buf, size);
1647         else {
1648                 if (pair)
1649                         hpp__entry_pair(he, pair, idx, buf, size);
1650                 else
1651                         hpp__entry_unpair(he, idx, buf, size);
1652         }
1653 }
1654
1655 static int hpp__entry_global(struct perf_hpp_fmt *_fmt, struct perf_hpp *hpp,
1656                              struct hist_entry *he)
1657 {
1658         struct diff_hpp_fmt *dfmt =
1659                 container_of(_fmt, struct diff_hpp_fmt, fmt);
1660         char buf[MAX_COL_WIDTH] = " ";
1661
1662         __hpp__entry_global(he, dfmt, buf, MAX_COL_WIDTH);
1663
1664         if (symbol_conf.field_sep)
1665                 return scnprintf(hpp->buf, hpp->size, "%s", buf);
1666         else
1667                 return scnprintf(hpp->buf, hpp->size, "%*s",
1668                                  dfmt->header_width, buf);
1669 }
1670
1671 static int hpp__header(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
1672                        struct hists *hists __maybe_unused,
1673                        int line __maybe_unused,
1674                        int *span __maybe_unused)
1675 {
1676         struct diff_hpp_fmt *dfmt =
1677                 container_of(fmt, struct diff_hpp_fmt, fmt);
1678
1679         BUG_ON(!dfmt->header);
1680         return scnprintf(hpp->buf, hpp->size, dfmt->header);
1681 }
1682
1683 static int hpp__width(struct perf_hpp_fmt *fmt,
1684                       struct perf_hpp *hpp __maybe_unused,
1685                       struct hists *hists __maybe_unused)
1686 {
1687         struct diff_hpp_fmt *dfmt =
1688                 container_of(fmt, struct diff_hpp_fmt, fmt);
1689
1690         BUG_ON(dfmt->header_width <= 0);
1691         return dfmt->header_width;
1692 }
1693
1694 static void init_header(struct data__file *d, struct diff_hpp_fmt *dfmt)
1695 {
1696 #define MAX_HEADER_NAME 100
1697         char buf_indent[MAX_HEADER_NAME];
1698         char buf[MAX_HEADER_NAME];
1699         const char *header = NULL;
1700         int width = 0;
1701
1702         BUG_ON(dfmt->idx >= PERF_HPP_DIFF__MAX_INDEX);
1703         header = columns[dfmt->idx].name;
1704         width  = columns[dfmt->idx].width;
1705
1706         /* Only our defined HPP fmts should appear here. */
1707         BUG_ON(!header);
1708
1709         if (data__files_cnt > 2)
1710                 scnprintf(buf, MAX_HEADER_NAME, "%s/%d", header, d->idx);
1711
1712 #define NAME (data__files_cnt > 2 ? buf : header)
1713         dfmt->header_width = width;
1714         width = (int) strlen(NAME);
1715         if (dfmt->header_width < width)
1716                 dfmt->header_width = width;
1717
1718         scnprintf(buf_indent, MAX_HEADER_NAME, "%*s",
1719                   dfmt->header_width, NAME);
1720
1721         dfmt->header = strdup(buf_indent);
1722 #undef MAX_HEADER_NAME
1723 #undef NAME
1724 }
1725
1726 static void data__hpp_register(struct data__file *d, int idx)
1727 {
1728         struct diff_hpp_fmt *dfmt = &d->fmt[idx];
1729         struct perf_hpp_fmt *fmt = &dfmt->fmt;
1730
1731         dfmt->idx = idx;
1732
1733         fmt->header = hpp__header;
1734         fmt->width  = hpp__width;
1735         fmt->entry  = hpp__entry_global;
1736         fmt->cmp    = hist_entry__cmp_nop;
1737         fmt->collapse = hist_entry__cmp_nop;
1738
1739         /* TODO more colors */
1740         switch (idx) {
1741         case PERF_HPP_DIFF__BASELINE:
1742                 fmt->color = hpp__color_baseline;
1743                 fmt->sort  = hist_entry__cmp_baseline;
1744                 break;
1745         case PERF_HPP_DIFF__DELTA:
1746                 fmt->color = hpp__color_delta;
1747                 fmt->sort  = hist_entry__cmp_delta;
1748                 break;
1749         case PERF_HPP_DIFF__RATIO:
1750                 fmt->color = hpp__color_ratio;
1751                 fmt->sort  = hist_entry__cmp_ratio;
1752                 break;
1753         case PERF_HPP_DIFF__WEIGHTED_DIFF:
1754                 fmt->color = hpp__color_wdiff;
1755                 fmt->sort  = hist_entry__cmp_wdiff;
1756                 break;
1757         case PERF_HPP_DIFF__DELTA_ABS:
1758                 fmt->color = hpp__color_delta;
1759                 fmt->sort  = hist_entry__cmp_delta_abs;
1760                 break;
1761         case PERF_HPP_DIFF__CYCLES:
1762                 fmt->color = hpp__color_cycles;
1763                 fmt->sort  = hist_entry__cmp_nop;
1764                 break;
1765         case PERF_HPP_DIFF__CYCLES_HIST:
1766                 fmt->color = hpp__color_cycles_hist;
1767                 fmt->sort  = hist_entry__cmp_nop;
1768                 break;
1769         default:
1770                 fmt->sort  = hist_entry__cmp_nop;
1771                 break;
1772         }
1773
1774         init_header(d, dfmt);
1775         perf_hpp__column_register(fmt);
1776         perf_hpp__register_sort_field(fmt);
1777 }
1778
1779 static int ui_init(void)
1780 {
1781         struct data__file *d;
1782         struct perf_hpp_fmt *fmt;
1783         int i;
1784
1785         data__for_each_file(i, d) {
1786
1787                 /*
1788                  * Baseline or compute related columns:
1789                  *
1790                  *   PERF_HPP_DIFF__BASELINE
1791                  *   PERF_HPP_DIFF__DELTA
1792                  *   PERF_HPP_DIFF__RATIO
1793                  *   PERF_HPP_DIFF__WEIGHTED_DIFF
1794                  *   PERF_HPP_DIFF__CYCLES
1795                  */
1796                 data__hpp_register(d, i ? compute_2_hpp[compute] :
1797                                           PERF_HPP_DIFF__BASELINE);
1798
1799                 if (cycles_hist && i)
1800                         data__hpp_register(d, PERF_HPP_DIFF__CYCLES_HIST);
1801
1802                 /*
1803                  * And the rest:
1804                  *
1805                  * PERF_HPP_DIFF__FORMULA
1806                  * PERF_HPP_DIFF__PERIOD
1807                  * PERF_HPP_DIFF__PERIOD_BASELINE
1808                  */
1809                 if (show_formula && i)
1810                         data__hpp_register(d, PERF_HPP_DIFF__FORMULA);
1811
1812                 if (show_period)
1813                         data__hpp_register(d, i ? PERF_HPP_DIFF__PERIOD :
1814                                                   PERF_HPP_DIFF__PERIOD_BASELINE);
1815         }
1816
1817         if (!sort_compute)
1818                 return 0;
1819
1820         /*
1821          * Prepend an fmt to sort on columns at 'sort_compute' first.
1822          * This fmt is added only to the sort list but not to the
1823          * output fields list.
1824          *
1825          * Note that this column (data) can be compared twice - one
1826          * for this 'sort_compute' fmt and another for the normal
1827          * diff_hpp_fmt.  But it shouldn't a problem as most entries
1828          * will be sorted out by first try or baseline and comparing
1829          * is not a costly operation.
1830          */
1831         fmt = zalloc(sizeof(*fmt));
1832         if (fmt == NULL) {
1833                 pr_err("Memory allocation failed\n");
1834                 return -1;
1835         }
1836
1837         fmt->cmp      = hist_entry__cmp_nop;
1838         fmt->collapse = hist_entry__cmp_nop;
1839
1840         switch (compute) {
1841         case COMPUTE_DELTA:
1842                 fmt->sort = hist_entry__cmp_delta_idx;
1843                 break;
1844         case COMPUTE_RATIO:
1845                 fmt->sort = hist_entry__cmp_ratio_idx;
1846                 break;
1847         case COMPUTE_WEIGHTED_DIFF:
1848                 fmt->sort = hist_entry__cmp_wdiff_idx;
1849                 break;
1850         case COMPUTE_DELTA_ABS:
1851                 fmt->sort = hist_entry__cmp_delta_abs_idx;
1852                 break;
1853         case COMPUTE_CYCLES:
1854                 /*
1855                  * Should set since 'fmt->sort' is called without
1856                  * checking valid during sorting
1857                  */
1858                 fmt->sort = hist_entry__cmp_nop;
1859                 break;
1860         default:
1861                 BUG_ON(1);
1862         }
1863
1864         perf_hpp__prepend_sort_field(fmt);
1865         return 0;
1866 }
1867
1868 static int data_init(int argc, const char **argv)
1869 {
1870         struct data__file *d;
1871         static const char *defaults[] = {
1872                 "perf.data.old",
1873                 "perf.data",
1874         };
1875         bool use_default = true;
1876         int i;
1877
1878         data__files_cnt = 2;
1879
1880         if (argc) {
1881                 if (argc == 1)
1882                         defaults[1] = argv[0];
1883                 else {
1884                         data__files_cnt = argc;
1885                         use_default = false;
1886                 }
1887         } else if (perf_guest) {
1888                 defaults[0] = "perf.data.host";
1889                 defaults[1] = "perf.data.guest";
1890         }
1891
1892         if (sort_compute >= (unsigned int) data__files_cnt) {
1893                 pr_err("Order option out of limit.\n");
1894                 return -EINVAL;
1895         }
1896
1897         data__files = zalloc(sizeof(*data__files) * data__files_cnt);
1898         if (!data__files)
1899                 return -ENOMEM;
1900
1901         data__for_each_file(i, d) {
1902                 struct perf_data *data = &d->data;
1903
1904                 data->path  = use_default ? defaults[i] : argv[i];
1905                 data->mode  = PERF_DATA_MODE_READ;
1906                 data->force = force;
1907
1908                 d->idx  = i;
1909         }
1910
1911         return 0;
1912 }
1913
1914 static int diff__config(const char *var, const char *value,
1915                         void *cb __maybe_unused)
1916 {
1917         if (!strcmp(var, "diff.order")) {
1918                 int ret;
1919                 if (perf_config_int(&ret, var, value) < 0)
1920                         return -1;
1921                 sort_compute = ret;
1922                 return 0;
1923         }
1924         if (!strcmp(var, "diff.compute")) {
1925                 if (!strcmp(value, "delta")) {
1926                         compute = COMPUTE_DELTA;
1927                 } else if (!strcmp(value, "delta-abs")) {
1928                         compute = COMPUTE_DELTA_ABS;
1929                 } else if (!strcmp(value, "ratio")) {
1930                         compute = COMPUTE_RATIO;
1931                 } else if (!strcmp(value, "wdiff")) {
1932                         compute = COMPUTE_WEIGHTED_DIFF;
1933                 } else {
1934                         pr_err("Invalid compute method: %s\n", value);
1935                         return -1;
1936                 }
1937         }
1938
1939         return 0;
1940 }
1941
1942 int cmd_diff(int argc, const char **argv)
1943 {
1944         int ret = hists__init();
1945
1946         if (ret < 0)
1947                 return ret;
1948
1949         perf_tool__init(&pdiff.tool, /*ordered_events=*/true);
1950         pdiff.tool.sample       = diff__process_sample_event;
1951         pdiff.tool.mmap = perf_event__process_mmap;
1952         pdiff.tool.mmap2        = perf_event__process_mmap2;
1953         pdiff.tool.comm = perf_event__process_comm;
1954         pdiff.tool.exit = perf_event__process_exit;
1955         pdiff.tool.fork = perf_event__process_fork;
1956         pdiff.tool.lost = perf_event__process_lost;
1957         pdiff.tool.namespaces = perf_event__process_namespaces;
1958         pdiff.tool.cgroup = perf_event__process_cgroup;
1959         pdiff.tool.ordering_requires_timestamps = true;
1960
1961         perf_config(diff__config, NULL);
1962
1963         argc = parse_options(argc, argv, options, diff_usage, 0);
1964
1965         if (quiet)
1966                 perf_quiet_option();
1967
1968         if (cycles_hist && (compute != COMPUTE_CYCLES))
1969                 usage_with_options(diff_usage, options);
1970
1971         if (pdiff.stream)
1972                 compute = COMPUTE_STREAM;
1973
1974         symbol__annotation_init();
1975
1976         if (symbol__init(NULL) < 0)
1977                 return -1;
1978
1979         if (data_init(argc, argv) < 0)
1980                 return -1;
1981
1982         if (check_file_brstack() < 0)
1983                 return -1;
1984
1985         if ((compute == COMPUTE_CYCLES || compute == COMPUTE_STREAM)
1986             && !pdiff.has_br_stack) {
1987                 return -1;
1988         }
1989
1990         if (compute == COMPUTE_STREAM) {
1991                 symbol_conf.show_branchflag_count = true;
1992                 symbol_conf.disable_add2line_warn = true;
1993                 callchain_param.mode = CHAIN_FLAT;
1994                 callchain_param.key = CCKEY_SRCLINE;
1995                 callchain_param.branch_callstack = 1;
1996                 symbol_conf.use_callchain = true;
1997                 callchain_register_param(&callchain_param);
1998                 sort_order = "srcline,symbol,dso";
1999         } else {
2000                 if (ui_init() < 0)
2001                         return -1;
2002
2003                 sort__mode = SORT_MODE__DIFF;
2004         }
2005
2006         if (setup_sorting(NULL) < 0)
2007                 usage_with_options(diff_usage, options);
2008
2009         setup_pager();
2010
2011         sort__setup_elide(NULL);
2012
2013         return __cmd_diff();
2014 }