perf record/report: Add call graph / call chain profiling
[cascardo/linux.git] / tools / perf / builtin-report.c
1 /*
2  * builtin-report.c
3  *
4  * Builtin report command: Analyze the perf.data input file,
5  * look up and read DSOs and symbol information and display
6  * a histogram of results, along various sorting keys.
7  */
8 #include "builtin.h"
9
10 #include "util/util.h"
11
12 #include "util/color.h"
13 #include "util/list.h"
14 #include "util/cache.h"
15 #include "util/rbtree.h"
16 #include "util/symbol.h"
17 #include "util/string.h"
18
19 #include "perf.h"
20
21 #include "util/parse-options.h"
22 #include "util/parse-events.h"
23
24 #define SHOW_KERNEL     1
25 #define SHOW_USER       2
26 #define SHOW_HV         4
27
28 static char             const *input_name = "perf.data";
29 static char             *vmlinux = NULL;
30
31 static char             default_sort_order[] = "comm,dso";
32 static char             *sort_order = default_sort_order;
33
34 static int              input;
35 static int              show_mask = SHOW_KERNEL | SHOW_USER | SHOW_HV;
36
37 static int              dump_trace = 0;
38 #define dprintf(x...)   do { if (dump_trace) printf(x); } while (0)
39 #define cdprintf(x...)  do { if (dump_trace) color_fprintf(stdout, color, x); } while (0)
40
41 static int              verbose;
42 static int              full_paths;
43
44 static unsigned long    page_size;
45 static unsigned long    mmap_window = 32;
46
47 struct ip_chain_event {
48         __u16 nr;
49         __u16 hv;
50         __u16 kernel;
51         __u16 user;
52         __u64 ips[];
53 };
54
55 struct ip_event {
56         struct perf_event_header header;
57         __u64 ip;
58         __u32 pid, tid;
59         unsigned char __more_data[];
60 };
61
62 struct mmap_event {
63         struct perf_event_header header;
64         __u32 pid, tid;
65         __u64 start;
66         __u64 len;
67         __u64 pgoff;
68         char filename[PATH_MAX];
69 };
70
71 struct comm_event {
72         struct perf_event_header header;
73         __u32 pid, tid;
74         char comm[16];
75 };
76
77 struct fork_event {
78         struct perf_event_header header;
79         __u32 pid, ppid;
80 };
81
82 struct period_event {
83         struct perf_event_header header;
84         __u64 time;
85         __u64 id;
86         __u64 sample_period;
87 };
88
89 typedef union event_union {
90         struct perf_event_header        header;
91         struct ip_event                 ip;
92         struct mmap_event               mmap;
93         struct comm_event               comm;
94         struct fork_event               fork;
95         struct period_event             period;
96 } event_t;
97
98 static LIST_HEAD(dsos);
99 static struct dso *kernel_dso;
100 static struct dso *vdso;
101
102 static void dsos__add(struct dso *dso)
103 {
104         list_add_tail(&dso->node, &dsos);
105 }
106
107 static struct dso *dsos__find(const char *name)
108 {
109         struct dso *pos;
110
111         list_for_each_entry(pos, &dsos, node)
112                 if (strcmp(pos->name, name) == 0)
113                         return pos;
114         return NULL;
115 }
116
117 static struct dso *dsos__findnew(const char *name)
118 {
119         struct dso *dso = dsos__find(name);
120         int nr;
121
122         if (dso)
123                 return dso;
124
125         dso = dso__new(name, 0);
126         if (!dso)
127                 goto out_delete_dso;
128
129         nr = dso__load(dso, NULL, verbose);
130         if (nr < 0) {
131                 if (verbose)
132                         fprintf(stderr, "Failed to open: %s\n", name);
133                 goto out_delete_dso;
134         }
135         if (!nr && verbose) {
136                 fprintf(stderr,
137                 "No symbols found in: %s, maybe install a debug package?\n",
138                                 name);
139         }
140
141         dsos__add(dso);
142
143         return dso;
144
145 out_delete_dso:
146         dso__delete(dso);
147         return NULL;
148 }
149
150 static void dsos__fprintf(FILE *fp)
151 {
152         struct dso *pos;
153
154         list_for_each_entry(pos, &dsos, node)
155                 dso__fprintf(pos, fp);
156 }
157
158 static struct symbol *vdso__find_symbol(struct dso *dso, __u64 ip)
159 {
160         return dso__find_symbol(kernel_dso, ip);
161 }
162
163 static int load_kernel(void)
164 {
165         int err;
166
167         kernel_dso = dso__new("[kernel]", 0);
168         if (!kernel_dso)
169                 return -1;
170
171         err = dso__load_kernel(kernel_dso, vmlinux, NULL, verbose);
172         if (err) {
173                 dso__delete(kernel_dso);
174                 kernel_dso = NULL;
175         } else
176                 dsos__add(kernel_dso);
177
178         vdso = dso__new("[vdso]", 0);
179         if (!vdso)
180                 return -1;
181
182         vdso->find_symbol = vdso__find_symbol;
183
184         dsos__add(vdso);
185
186         return err;
187 }
188
189 static char __cwd[PATH_MAX];
190 static char *cwd = __cwd;
191 static int cwdlen;
192
193 static int strcommon(const char *pathname)
194 {
195         int n = 0;
196
197         while (pathname[n] == cwd[n] && n < cwdlen)
198                 ++n;
199
200         return n;
201 }
202
203 struct map {
204         struct list_head node;
205         __u64    start;
206         __u64    end;
207         __u64    pgoff;
208         __u64    (*map_ip)(struct map *, __u64);
209         struct dso       *dso;
210 };
211
212 static __u64 map__map_ip(struct map *map, __u64 ip)
213 {
214         return ip - map->start + map->pgoff;
215 }
216
217 static __u64 vdso__map_ip(struct map *map, __u64 ip)
218 {
219         return ip;
220 }
221
222 static inline int is_anon_memory(const char *filename)
223 {
224      return strcmp(filename, "//anon") == 0;
225 }
226
227 static struct map *map__new(struct mmap_event *event)
228 {
229         struct map *self = malloc(sizeof(*self));
230
231         if (self != NULL) {
232                 const char *filename = event->filename;
233                 char newfilename[PATH_MAX];
234                 int anon;
235
236                 if (cwd) {
237                         int n = strcommon(filename);
238
239                         if (n == cwdlen) {
240                                 snprintf(newfilename, sizeof(newfilename),
241                                          ".%s", filename + n);
242                                 filename = newfilename;
243                         }
244                 }
245
246                 anon = is_anon_memory(filename);
247
248                 if (anon) {
249                         snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", event->pid);
250                         filename = newfilename;
251                 }
252
253                 self->start = event->start;
254                 self->end   = event->start + event->len;
255                 self->pgoff = event->pgoff;
256
257                 self->dso = dsos__findnew(filename);
258                 if (self->dso == NULL)
259                         goto out_delete;
260
261                 if (self->dso == vdso || anon)
262                         self->map_ip = vdso__map_ip;
263                 else
264                         self->map_ip = map__map_ip;
265         }
266         return self;
267 out_delete:
268         free(self);
269         return NULL;
270 }
271
272 static struct map *map__clone(struct map *self)
273 {
274         struct map *map = malloc(sizeof(*self));
275
276         if (!map)
277                 return NULL;
278
279         memcpy(map, self, sizeof(*self));
280
281         return map;
282 }
283
284 static int map__overlap(struct map *l, struct map *r)
285 {
286         if (l->start > r->start) {
287                 struct map *t = l;
288                 l = r;
289                 r = t;
290         }
291
292         if (l->end > r->start)
293                 return 1;
294
295         return 0;
296 }
297
298 static size_t map__fprintf(struct map *self, FILE *fp)
299 {
300         return fprintf(fp, " %Lx-%Lx %Lx %s\n",
301                        self->start, self->end, self->pgoff, self->dso->name);
302 }
303
304
305 struct thread {
306         struct rb_node   rb_node;
307         struct list_head maps;
308         pid_t            pid;
309         char             *comm;
310 };
311
312 static struct thread *thread__new(pid_t pid)
313 {
314         struct thread *self = malloc(sizeof(*self));
315
316         if (self != NULL) {
317                 self->pid = pid;
318                 self->comm = malloc(32);
319                 if (self->comm)
320                         snprintf(self->comm, 32, ":%d", self->pid);
321                 INIT_LIST_HEAD(&self->maps);
322         }
323
324         return self;
325 }
326
327 static int thread__set_comm(struct thread *self, const char *comm)
328 {
329         if (self->comm)
330                 free(self->comm);
331         self->comm = strdup(comm);
332         return self->comm ? 0 : -ENOMEM;
333 }
334
335 static size_t thread__fprintf(struct thread *self, FILE *fp)
336 {
337         struct map *pos;
338         size_t ret = fprintf(fp, "Thread %d %s\n", self->pid, self->comm);
339
340         list_for_each_entry(pos, &self->maps, node)
341                 ret += map__fprintf(pos, fp);
342
343         return ret;
344 }
345
346
347 static struct rb_root threads;
348 static struct thread *last_match;
349
350 static struct thread *threads__findnew(pid_t pid)
351 {
352         struct rb_node **p = &threads.rb_node;
353         struct rb_node *parent = NULL;
354         struct thread *th;
355
356         /*
357          * Font-end cache - PID lookups come in blocks,
358          * so most of the time we dont have to look up
359          * the full rbtree:
360          */
361         if (last_match && last_match->pid == pid)
362                 return last_match;
363
364         while (*p != NULL) {
365                 parent = *p;
366                 th = rb_entry(parent, struct thread, rb_node);
367
368                 if (th->pid == pid) {
369                         last_match = th;
370                         return th;
371                 }
372
373                 if (pid < th->pid)
374                         p = &(*p)->rb_left;
375                 else
376                         p = &(*p)->rb_right;
377         }
378
379         th = thread__new(pid);
380         if (th != NULL) {
381                 rb_link_node(&th->rb_node, parent, p);
382                 rb_insert_color(&th->rb_node, &threads);
383                 last_match = th;
384         }
385
386         return th;
387 }
388
389 static void thread__insert_map(struct thread *self, struct map *map)
390 {
391         struct map *pos, *tmp;
392
393         list_for_each_entry_safe(pos, tmp, &self->maps, node) {
394                 if (map__overlap(pos, map)) {
395                         list_del_init(&pos->node);
396                         /* XXX leaks dsos */
397                         free(pos);
398                 }
399         }
400
401         list_add_tail(&map->node, &self->maps);
402 }
403
404 static int thread__fork(struct thread *self, struct thread *parent)
405 {
406         struct map *map;
407
408         if (self->comm)
409                 free(self->comm);
410         self->comm = strdup(parent->comm);
411         if (!self->comm)
412                 return -ENOMEM;
413
414         list_for_each_entry(map, &parent->maps, node) {
415                 struct map *new = map__clone(map);
416                 if (!new)
417                         return -ENOMEM;
418                 thread__insert_map(self, new);
419         }
420
421         return 0;
422 }
423
424 static struct map *thread__find_map(struct thread *self, __u64 ip)
425 {
426         struct map *pos;
427
428         if (self == NULL)
429                 return NULL;
430
431         list_for_each_entry(pos, &self->maps, node)
432                 if (ip >= pos->start && ip <= pos->end)
433                         return pos;
434
435         return NULL;
436 }
437
438 static size_t threads__fprintf(FILE *fp)
439 {
440         size_t ret = 0;
441         struct rb_node *nd;
442
443         for (nd = rb_first(&threads); nd; nd = rb_next(nd)) {
444                 struct thread *pos = rb_entry(nd, struct thread, rb_node);
445
446                 ret += thread__fprintf(pos, fp);
447         }
448
449         return ret;
450 }
451
452 /*
453  * histogram, sorted on item, collects counts
454  */
455
456 static struct rb_root hist;
457
458 struct hist_entry {
459         struct rb_node   rb_node;
460
461         struct thread    *thread;
462         struct map       *map;
463         struct dso       *dso;
464         struct symbol    *sym;
465         __u64            ip;
466         char             level;
467
468         __u64            count;
469 };
470
471 /*
472  * configurable sorting bits
473  */
474
475 struct sort_entry {
476         struct list_head list;
477
478         char *header;
479
480         int64_t (*cmp)(struct hist_entry *, struct hist_entry *);
481         int64_t (*collapse)(struct hist_entry *, struct hist_entry *);
482         size_t  (*print)(FILE *fp, struct hist_entry *);
483 };
484
485 /* --sort pid */
486
487 static int64_t
488 sort__thread_cmp(struct hist_entry *left, struct hist_entry *right)
489 {
490         return right->thread->pid - left->thread->pid;
491 }
492
493 static size_t
494 sort__thread_print(FILE *fp, struct hist_entry *self)
495 {
496         return fprintf(fp, "%16s:%5d", self->thread->comm ?: "", self->thread->pid);
497 }
498
499 static struct sort_entry sort_thread = {
500         .header = "         Command:  Pid",
501         .cmp    = sort__thread_cmp,
502         .print  = sort__thread_print,
503 };
504
505 /* --sort comm */
506
507 static int64_t
508 sort__comm_cmp(struct hist_entry *left, struct hist_entry *right)
509 {
510         return right->thread->pid - left->thread->pid;
511 }
512
513 static int64_t
514 sort__comm_collapse(struct hist_entry *left, struct hist_entry *right)
515 {
516         char *comm_l = left->thread->comm;
517         char *comm_r = right->thread->comm;
518
519         if (!comm_l || !comm_r) {
520                 if (!comm_l && !comm_r)
521                         return 0;
522                 else if (!comm_l)
523                         return -1;
524                 else
525                         return 1;
526         }
527
528         return strcmp(comm_l, comm_r);
529 }
530
531 static size_t
532 sort__comm_print(FILE *fp, struct hist_entry *self)
533 {
534         return fprintf(fp, "%16s", self->thread->comm);
535 }
536
537 static struct sort_entry sort_comm = {
538         .header         = "         Command",
539         .cmp            = sort__comm_cmp,
540         .collapse       = sort__comm_collapse,
541         .print          = sort__comm_print,
542 };
543
544 /* --sort dso */
545
546 static int64_t
547 sort__dso_cmp(struct hist_entry *left, struct hist_entry *right)
548 {
549         struct dso *dso_l = left->dso;
550         struct dso *dso_r = right->dso;
551
552         if (!dso_l || !dso_r) {
553                 if (!dso_l && !dso_r)
554                         return 0;
555                 else if (!dso_l)
556                         return -1;
557                 else
558                         return 1;
559         }
560
561         return strcmp(dso_l->name, dso_r->name);
562 }
563
564 static size_t
565 sort__dso_print(FILE *fp, struct hist_entry *self)
566 {
567         if (self->dso)
568                 return fprintf(fp, "%-25s", self->dso->name);
569
570         return fprintf(fp, "%016llx         ", (__u64)self->ip);
571 }
572
573 static struct sort_entry sort_dso = {
574         .header = "Shared Object            ",
575         .cmp    = sort__dso_cmp,
576         .print  = sort__dso_print,
577 };
578
579 /* --sort symbol */
580
581 static int64_t
582 sort__sym_cmp(struct hist_entry *left, struct hist_entry *right)
583 {
584         __u64 ip_l, ip_r;
585
586         if (left->sym == right->sym)
587                 return 0;
588
589         ip_l = left->sym ? left->sym->start : left->ip;
590         ip_r = right->sym ? right->sym->start : right->ip;
591
592         return (int64_t)(ip_r - ip_l);
593 }
594
595 static size_t
596 sort__sym_print(FILE *fp, struct hist_entry *self)
597 {
598         size_t ret = 0;
599
600         if (verbose)
601                 ret += fprintf(fp, "%#018llx  ", (__u64)self->ip);
602
603         if (self->sym) {
604                 ret += fprintf(fp, "[%c] %s",
605                         self->dso == kernel_dso ? 'k' : '.', self->sym->name);
606         } else {
607                 ret += fprintf(fp, "%#016llx", (__u64)self->ip);
608         }
609
610         return ret;
611 }
612
613 static struct sort_entry sort_sym = {
614         .header = "Symbol",
615         .cmp    = sort__sym_cmp,
616         .print  = sort__sym_print,
617 };
618
619 static int sort__need_collapse = 0;
620
621 struct sort_dimension {
622         char                    *name;
623         struct sort_entry       *entry;
624         int                     taken;
625 };
626
627 static struct sort_dimension sort_dimensions[] = {
628         { .name = "pid",        .entry = &sort_thread,  },
629         { .name = "comm",       .entry = &sort_comm,    },
630         { .name = "dso",        .entry = &sort_dso,     },
631         { .name = "symbol",     .entry = &sort_sym,     },
632 };
633
634 static LIST_HEAD(hist_entry__sort_list);
635
636 static int sort_dimension__add(char *tok)
637 {
638         int i;
639
640         for (i = 0; i < ARRAY_SIZE(sort_dimensions); i++) {
641                 struct sort_dimension *sd = &sort_dimensions[i];
642
643                 if (sd->taken)
644                         continue;
645
646                 if (strncasecmp(tok, sd->name, strlen(tok)))
647                         continue;
648
649                 if (sd->entry->collapse)
650                         sort__need_collapse = 1;
651
652                 list_add_tail(&sd->entry->list, &hist_entry__sort_list);
653                 sd->taken = 1;
654
655                 return 0;
656         }
657
658         return -ESRCH;
659 }
660
661 static int64_t
662 hist_entry__cmp(struct hist_entry *left, struct hist_entry *right)
663 {
664         struct sort_entry *se;
665         int64_t cmp = 0;
666
667         list_for_each_entry(se, &hist_entry__sort_list, list) {
668                 cmp = se->cmp(left, right);
669                 if (cmp)
670                         break;
671         }
672
673         return cmp;
674 }
675
676 static int64_t
677 hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
678 {
679         struct sort_entry *se;
680         int64_t cmp = 0;
681
682         list_for_each_entry(se, &hist_entry__sort_list, list) {
683                 int64_t (*f)(struct hist_entry *, struct hist_entry *);
684
685                 f = se->collapse ?: se->cmp;
686
687                 cmp = f(left, right);
688                 if (cmp)
689                         break;
690         }
691
692         return cmp;
693 }
694
695 static size_t
696 hist_entry__fprintf(FILE *fp, struct hist_entry *self, __u64 total_samples)
697 {
698         struct sort_entry *se;
699         size_t ret;
700
701         if (total_samples) {
702                 double percent = self->count * 100.0 / total_samples;
703                 char *color = PERF_COLOR_NORMAL;
704
705                 /*
706                  * We color high-overhead entries in red, mid-overhead
707                  * entries in green - and keep the low overhead places
708                  * normal:
709                  */
710                 if (percent >= 5.0) {
711                         color = PERF_COLOR_RED;
712                 } else {
713                         if (percent >= 0.5)
714                                 color = PERF_COLOR_GREEN;
715                 }
716
717                 ret = color_fprintf(fp, color, "   %6.2f%%",
718                                 (self->count * 100.0) / total_samples);
719         } else
720                 ret = fprintf(fp, "%12Ld ", self->count);
721
722         list_for_each_entry(se, &hist_entry__sort_list, list) {
723                 fprintf(fp, "  ");
724                 ret += se->print(fp, self);
725         }
726
727         ret += fprintf(fp, "\n");
728
729         return ret;
730 }
731
732 /*
733  * collect histogram counts
734  */
735
736 static int
737 hist_entry__add(struct thread *thread, struct map *map, struct dso *dso,
738                 struct symbol *sym, __u64 ip, char level, __u64 count)
739 {
740         struct rb_node **p = &hist.rb_node;
741         struct rb_node *parent = NULL;
742         struct hist_entry *he;
743         struct hist_entry entry = {
744                 .thread = thread,
745                 .map    = map,
746                 .dso    = dso,
747                 .sym    = sym,
748                 .ip     = ip,
749                 .level  = level,
750                 .count  = count,
751         };
752         int cmp;
753
754         while (*p != NULL) {
755                 parent = *p;
756                 he = rb_entry(parent, struct hist_entry, rb_node);
757
758                 cmp = hist_entry__cmp(&entry, he);
759
760                 if (!cmp) {
761                         he->count += count;
762                         return 0;
763                 }
764
765                 if (cmp < 0)
766                         p = &(*p)->rb_left;
767                 else
768                         p = &(*p)->rb_right;
769         }
770
771         he = malloc(sizeof(*he));
772         if (!he)
773                 return -ENOMEM;
774         *he = entry;
775         rb_link_node(&he->rb_node, parent, p);
776         rb_insert_color(&he->rb_node, &hist);
777
778         return 0;
779 }
780
781 static void hist_entry__free(struct hist_entry *he)
782 {
783         free(he);
784 }
785
786 /*
787  * collapse the histogram
788  */
789
790 static struct rb_root collapse_hists;
791
792 static void collapse__insert_entry(struct hist_entry *he)
793 {
794         struct rb_node **p = &collapse_hists.rb_node;
795         struct rb_node *parent = NULL;
796         struct hist_entry *iter;
797         int64_t cmp;
798
799         while (*p != NULL) {
800                 parent = *p;
801                 iter = rb_entry(parent, struct hist_entry, rb_node);
802
803                 cmp = hist_entry__collapse(iter, he);
804
805                 if (!cmp) {
806                         iter->count += he->count;
807                         hist_entry__free(he);
808                         return;
809                 }
810
811                 if (cmp < 0)
812                         p = &(*p)->rb_left;
813                 else
814                         p = &(*p)->rb_right;
815         }
816
817         rb_link_node(&he->rb_node, parent, p);
818         rb_insert_color(&he->rb_node, &collapse_hists);
819 }
820
821 static void collapse__resort(void)
822 {
823         struct rb_node *next;
824         struct hist_entry *n;
825
826         if (!sort__need_collapse)
827                 return;
828
829         next = rb_first(&hist);
830         while (next) {
831                 n = rb_entry(next, struct hist_entry, rb_node);
832                 next = rb_next(&n->rb_node);
833
834                 rb_erase(&n->rb_node, &hist);
835                 collapse__insert_entry(n);
836         }
837 }
838
839 /*
840  * reverse the map, sort on count.
841  */
842
843 static struct rb_root output_hists;
844
845 static void output__insert_entry(struct hist_entry *he)
846 {
847         struct rb_node **p = &output_hists.rb_node;
848         struct rb_node *parent = NULL;
849         struct hist_entry *iter;
850
851         while (*p != NULL) {
852                 parent = *p;
853                 iter = rb_entry(parent, struct hist_entry, rb_node);
854
855                 if (he->count > iter->count)
856                         p = &(*p)->rb_left;
857                 else
858                         p = &(*p)->rb_right;
859         }
860
861         rb_link_node(&he->rb_node, parent, p);
862         rb_insert_color(&he->rb_node, &output_hists);
863 }
864
865 static void output__resort(void)
866 {
867         struct rb_node *next;
868         struct hist_entry *n;
869         struct rb_root *tree = &hist;
870
871         if (sort__need_collapse)
872                 tree = &collapse_hists;
873
874         next = rb_first(tree);
875
876         while (next) {
877                 n = rb_entry(next, struct hist_entry, rb_node);
878                 next = rb_next(&n->rb_node);
879
880                 rb_erase(&n->rb_node, tree);
881                 output__insert_entry(n);
882         }
883 }
884
885 static size_t output__fprintf(FILE *fp, __u64 total_samples)
886 {
887         struct hist_entry *pos;
888         struct sort_entry *se;
889         struct rb_node *nd;
890         size_t ret = 0;
891
892         fprintf(fp, "\n");
893         fprintf(fp, "#\n");
894         fprintf(fp, "# (%Ld samples)\n", (__u64)total_samples);
895         fprintf(fp, "#\n");
896
897         fprintf(fp, "# Overhead");
898         list_for_each_entry(se, &hist_entry__sort_list, list)
899                 fprintf(fp, "  %s", se->header);
900         fprintf(fp, "\n");
901
902         fprintf(fp, "# ........");
903         list_for_each_entry(se, &hist_entry__sort_list, list) {
904                 int i;
905
906                 fprintf(fp, "  ");
907                 for (i = 0; i < strlen(se->header); i++)
908                         fprintf(fp, ".");
909         }
910         fprintf(fp, "\n");
911
912         fprintf(fp, "#\n");
913
914         for (nd = rb_first(&output_hists); nd; nd = rb_next(nd)) {
915                 pos = rb_entry(nd, struct hist_entry, rb_node);
916                 ret += hist_entry__fprintf(fp, pos, total_samples);
917         }
918
919         if (!strcmp(sort_order, default_sort_order)) {
920                 fprintf(fp, "#\n");
921                 fprintf(fp, "# (For more details, try: perf report --sort comm,dso,symbol)\n");
922                 fprintf(fp, "#\n");
923         }
924         fprintf(fp, "\n");
925
926         return ret;
927 }
928
929 static void register_idle_thread(void)
930 {
931         struct thread *thread = threads__findnew(0);
932
933         if (thread == NULL ||
934                         thread__set_comm(thread, "[idle]")) {
935                 fprintf(stderr, "problem inserting idle task.\n");
936                 exit(-1);
937         }
938 }
939
940 static unsigned long total = 0,
941                      total_mmap = 0,
942                      total_comm = 0,
943                      total_fork = 0,
944                      total_unknown = 0;
945
946 static int
947 process_overflow_event(event_t *event, unsigned long offset, unsigned long head)
948 {
949         char level;
950         int show = 0;
951         struct dso *dso = NULL;
952         struct thread *thread = threads__findnew(event->ip.pid);
953         __u64 ip = event->ip.ip;
954         __u64 period = 1;
955         struct map *map = NULL;
956         void *more_data = event->ip.__more_data;
957         struct ip_chain_event *chain;
958
959         if (event->header.type & PERF_SAMPLE_PERIOD) {
960                 period = *(__u64 *)more_data;
961                 more_data += sizeof(__u64);
962         }
963
964         dprintf("%p [%p]: PERF_EVENT (IP, %d): %d: %p period: %Ld\n",
965                 (void *)(offset + head),
966                 (void *)(long)(event->header.size),
967                 event->header.misc,
968                 event->ip.pid,
969                 (void *)(long)ip,
970                 (long long)period);
971
972         if (event->header.type & PERF_SAMPLE_CALLCHAIN) {
973                 int i;
974
975                 chain = (void *)more_data;
976
977                 if (dump_trace) {
978                         dprintf("... chain: u:%d, k:%d, nr:%d\n",
979                                 chain->user,
980                                 chain->kernel,
981                                 chain->nr);
982
983                         for (i = 0; i < chain->nr; i++)
984                                 dprintf("..... %2d: %p\n", i, (void *)chain->ips[i]);
985                 }
986         }
987
988         dprintf(" ... thread: %s:%d\n", thread->comm, thread->pid);
989
990         if (thread == NULL) {
991                 fprintf(stderr, "problem processing %d event, skipping it.\n",
992                         event->header.type);
993                 return -1;
994         }
995
996         if (event->header.misc & PERF_EVENT_MISC_KERNEL) {
997                 show = SHOW_KERNEL;
998                 level = 'k';
999
1000                 dso = kernel_dso;
1001
1002                 dprintf(" ...... dso: %s\n", dso->name);
1003
1004         } else if (event->header.misc & PERF_EVENT_MISC_USER) {
1005
1006                 show = SHOW_USER;
1007                 level = '.';
1008
1009                 map = thread__find_map(thread, ip);
1010                 if (map != NULL) {
1011                         ip = map->map_ip(map, ip);
1012                         dso = map->dso;
1013                 } else {
1014                         /*
1015                          * If this is outside of all known maps,
1016                          * and is a negative address, try to look it
1017                          * up in the kernel dso, as it might be a
1018                          * vsyscall (which executes in user-mode):
1019                          */
1020                         if ((long long)ip < 0)
1021                                 dso = kernel_dso;
1022                 }
1023                 dprintf(" ...... dso: %s\n", dso ? dso->name : "<not found>");
1024
1025         } else {
1026                 show = SHOW_HV;
1027                 level = 'H';
1028                 dprintf(" ...... dso: [hypervisor]\n");
1029         }
1030
1031         if (show & show_mask) {
1032                 struct symbol *sym = NULL;
1033
1034                 if (dso)
1035                         sym = dso->find_symbol(dso, ip);
1036
1037                 if (hist_entry__add(thread, map, dso, sym, ip, level, period)) {
1038                         fprintf(stderr,
1039                 "problem incrementing symbol count, skipping event\n");
1040                         return -1;
1041                 }
1042         }
1043         total += period;
1044
1045         return 0;
1046 }
1047
1048 static int
1049 process_mmap_event(event_t *event, unsigned long offset, unsigned long head)
1050 {
1051         struct thread *thread = threads__findnew(event->mmap.pid);
1052         struct map *map = map__new(&event->mmap);
1053
1054         dprintf("%p [%p]: PERF_EVENT_MMAP %d: [%p(%p) @ %p]: %s\n",
1055                 (void *)(offset + head),
1056                 (void *)(long)(event->header.size),
1057                 event->mmap.pid,
1058                 (void *)(long)event->mmap.start,
1059                 (void *)(long)event->mmap.len,
1060                 (void *)(long)event->mmap.pgoff,
1061                 event->mmap.filename);
1062
1063         if (thread == NULL || map == NULL) {
1064                 dprintf("problem processing PERF_EVENT_MMAP, skipping event.\n");
1065                 return 0;
1066         }
1067
1068         thread__insert_map(thread, map);
1069         total_mmap++;
1070
1071         return 0;
1072 }
1073
1074 static int
1075 process_comm_event(event_t *event, unsigned long offset, unsigned long head)
1076 {
1077         struct thread *thread = threads__findnew(event->comm.pid);
1078
1079         dprintf("%p [%p]: PERF_EVENT_COMM: %s:%d\n",
1080                 (void *)(offset + head),
1081                 (void *)(long)(event->header.size),
1082                 event->comm.comm, event->comm.pid);
1083
1084         if (thread == NULL ||
1085             thread__set_comm(thread, event->comm.comm)) {
1086                 dprintf("problem processing PERF_EVENT_COMM, skipping event.\n");
1087                 return -1;
1088         }
1089         total_comm++;
1090
1091         return 0;
1092 }
1093
1094 static int
1095 process_fork_event(event_t *event, unsigned long offset, unsigned long head)
1096 {
1097         struct thread *thread = threads__findnew(event->fork.pid);
1098         struct thread *parent = threads__findnew(event->fork.ppid);
1099
1100         dprintf("%p [%p]: PERF_EVENT_FORK: %d:%d\n",
1101                 (void *)(offset + head),
1102                 (void *)(long)(event->header.size),
1103                 event->fork.pid, event->fork.ppid);
1104
1105         if (!thread || !parent || thread__fork(thread, parent)) {
1106                 dprintf("problem processing PERF_EVENT_FORK, skipping event.\n");
1107                 return -1;
1108         }
1109         total_fork++;
1110
1111         return 0;
1112 }
1113
1114 static int
1115 process_period_event(event_t *event, unsigned long offset, unsigned long head)
1116 {
1117         dprintf("%p [%p]: PERF_EVENT_PERIOD: time:%Ld, id:%Ld: period:%Ld\n",
1118                 (void *)(offset + head),
1119                 (void *)(long)(event->header.size),
1120                 event->period.time,
1121                 event->period.id,
1122                 event->period.sample_period);
1123
1124         return 0;
1125 }
1126
1127 static void trace_event(event_t *event)
1128 {
1129         unsigned char *raw_event = (void *)event;
1130         char *color = PERF_COLOR_BLUE;
1131         int i, j;
1132
1133         if (!dump_trace)
1134                 return;
1135
1136         dprintf(".");
1137         cdprintf("\n. ... raw event: size %d bytes\n", event->header.size);
1138
1139         for (i = 0; i < event->header.size; i++) {
1140                 if ((i & 15) == 0) {
1141                         dprintf(".");
1142                         cdprintf("  %04x: ", i);
1143                 }
1144
1145                 cdprintf(" %02x", raw_event[i]);
1146
1147                 if (((i & 15) == 15) || i == event->header.size-1) {
1148                         cdprintf("  ");
1149                         for (j = 0; j < 15-(i & 15); j++)
1150                                 cdprintf("   ");
1151                         for (j = 0; j < (i & 15); j++) {
1152                                 if (isprint(raw_event[i-15+j]))
1153                                         cdprintf("%c", raw_event[i-15+j]);
1154                                 else
1155                                         cdprintf(".");
1156                         }
1157                         cdprintf("\n");
1158                 }
1159         }
1160         dprintf(".\n");
1161 }
1162
1163 static int
1164 process_event(event_t *event, unsigned long offset, unsigned long head)
1165 {
1166         trace_event(event);
1167
1168         if (event->header.misc & PERF_EVENT_MISC_OVERFLOW)
1169                 return process_overflow_event(event, offset, head);
1170
1171         switch (event->header.type) {
1172         case PERF_EVENT_MMAP:
1173                 return process_mmap_event(event, offset, head);
1174
1175         case PERF_EVENT_COMM:
1176                 return process_comm_event(event, offset, head);
1177
1178         case PERF_EVENT_FORK:
1179                 return process_fork_event(event, offset, head);
1180
1181         case PERF_EVENT_PERIOD:
1182                 return process_period_event(event, offset, head);
1183         /*
1184          * We dont process them right now but they are fine:
1185          */
1186
1187         case PERF_EVENT_THROTTLE:
1188         case PERF_EVENT_UNTHROTTLE:
1189                 return 0;
1190
1191         default:
1192                 return -1;
1193         }
1194
1195         return 0;
1196 }
1197
1198 static int __cmd_report(void)
1199 {
1200         int ret, rc = EXIT_FAILURE;
1201         unsigned long offset = 0;
1202         unsigned long head = 0;
1203         struct stat stat;
1204         event_t *event;
1205         uint32_t size;
1206         char *buf;
1207
1208         register_idle_thread();
1209
1210         input = open(input_name, O_RDONLY);
1211         if (input < 0) {
1212                 fprintf(stderr, " failed to open file: %s", input_name);
1213                 if (!strcmp(input_name, "perf.data"))
1214                         fprintf(stderr, "  (try 'perf record' first)");
1215                 fprintf(stderr, "\n");
1216                 exit(-1);
1217         }
1218
1219         ret = fstat(input, &stat);
1220         if (ret < 0) {
1221                 perror("failed to stat file");
1222                 exit(-1);
1223         }
1224
1225         if (!stat.st_size) {
1226                 fprintf(stderr, "zero-sized file, nothing to do!\n");
1227                 exit(0);
1228         }
1229
1230         if (load_kernel() < 0) {
1231                 perror("failed to load kernel symbols");
1232                 return EXIT_FAILURE;
1233         }
1234
1235         if (!full_paths) {
1236                 if (getcwd(__cwd, sizeof(__cwd)) == NULL) {
1237                         perror("failed to get the current directory");
1238                         return EXIT_FAILURE;
1239                 }
1240                 cwdlen = strlen(cwd);
1241         } else {
1242                 cwd = NULL;
1243                 cwdlen = 0;
1244         }
1245 remap:
1246         buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ,
1247                            MAP_SHARED, input, offset);
1248         if (buf == MAP_FAILED) {
1249                 perror("failed to mmap file");
1250                 exit(-1);
1251         }
1252
1253 more:
1254         event = (event_t *)(buf + head);
1255
1256         size = event->header.size;
1257         if (!size)
1258                 size = 8;
1259
1260         if (head + event->header.size >= page_size * mmap_window) {
1261                 unsigned long shift = page_size * (head / page_size);
1262                 int ret;
1263
1264                 ret = munmap(buf, page_size * mmap_window);
1265                 assert(ret == 0);
1266
1267                 offset += shift;
1268                 head -= shift;
1269                 goto remap;
1270         }
1271
1272         size = event->header.size;
1273
1274         dprintf("\n%p [%p]: event: %d\n",
1275                         (void *)(offset + head),
1276                         (void *)(long)event->header.size,
1277                         event->header.type);
1278
1279         if (!size || process_event(event, offset, head) < 0) {
1280
1281                 dprintf("%p [%p]: skipping unknown header type: %d\n",
1282                         (void *)(offset + head),
1283                         (void *)(long)(event->header.size),
1284                         event->header.type);
1285
1286                 total_unknown++;
1287
1288                 /*
1289                  * assume we lost track of the stream, check alignment, and
1290                  * increment a single u64 in the hope to catch on again 'soon'.
1291                  */
1292
1293                 if (unlikely(head & 7))
1294                         head &= ~7ULL;
1295
1296                 size = 8;
1297         }
1298
1299         head += size;
1300
1301         if (offset + head < stat.st_size)
1302                 goto more;
1303
1304         rc = EXIT_SUCCESS;
1305         close(input);
1306
1307         dprintf("      IP events: %10ld\n", total);
1308         dprintf("    mmap events: %10ld\n", total_mmap);
1309         dprintf("    comm events: %10ld\n", total_comm);
1310         dprintf("    fork events: %10ld\n", total_fork);
1311         dprintf(" unknown events: %10ld\n", total_unknown);
1312
1313         if (dump_trace)
1314                 return 0;
1315
1316         if (verbose >= 3)
1317                 threads__fprintf(stdout);
1318
1319         if (verbose >= 2)
1320                 dsos__fprintf(stdout);
1321
1322         collapse__resort();
1323         output__resort();
1324         output__fprintf(stdout, total);
1325
1326         return rc;
1327 }
1328
1329 static const char * const report_usage[] = {
1330         "perf report [<options>] <command>",
1331         NULL
1332 };
1333
1334 static const struct option options[] = {
1335         OPT_STRING('i', "input", &input_name, "file",
1336                     "input file name"),
1337         OPT_BOOLEAN('v', "verbose", &verbose,
1338                     "be more verbose (show symbol address, etc)"),
1339         OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
1340                     "dump raw trace in ASCII"),
1341         OPT_STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"),
1342         OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
1343                    "sort by key(s): pid, comm, dso, symbol. Default: pid,symbol"),
1344         OPT_BOOLEAN('P', "full-paths", &full_paths,
1345                     "Don't shorten the pathnames taking into account the cwd"),
1346         OPT_END()
1347 };
1348
1349 static void setup_sorting(void)
1350 {
1351         char *tmp, *tok, *str = strdup(sort_order);
1352
1353         for (tok = strtok_r(str, ", ", &tmp);
1354                         tok; tok = strtok_r(NULL, ", ", &tmp)) {
1355                 if (sort_dimension__add(tok) < 0) {
1356                         error("Unknown --sort key: `%s'", tok);
1357                         usage_with_options(report_usage, options);
1358                 }
1359         }
1360
1361         free(str);
1362 }
1363
1364 int cmd_report(int argc, const char **argv, const char *prefix)
1365 {
1366         symbol__init();
1367
1368         page_size = getpagesize();
1369
1370         argc = parse_options(argc, argv, options, report_usage, 0);
1371
1372         setup_sorting();
1373
1374         /*
1375          * Any (unrecognized) arguments left?
1376          */
1377         if (argc)
1378                 usage_with_options(report_usage, options);
1379
1380         setup_pager();
1381
1382         return __cmd_report();
1383 }