perf report: Add raw displaying of per-thread counters
[linux-2.6/libata-dev.git] / tools / perf / builtin-report.c
blob2357c66fb91dc059d4d414298b32b1283c7c5ab7
1 /*
2 * builtin-report.c
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"
10 #include "util/util.h"
12 #include "util/color.h"
13 #include <linux/list.h>
14 #include "util/cache.h"
15 #include <linux/rbtree.h>
16 #include "util/symbol.h"
17 #include "util/string.h"
18 #include "util/callchain.h"
19 #include "util/strlist.h"
20 #include "util/values.h"
22 #include "perf.h"
23 #include "util/header.h"
25 #include "util/parse-options.h"
26 #include "util/parse-events.h"
28 #define SHOW_KERNEL 1
29 #define SHOW_USER 2
30 #define SHOW_HV 4
32 static char const *input_name = "perf.data";
33 static char *vmlinux = NULL;
35 static char default_sort_order[] = "comm,dso,symbol";
36 static char *sort_order = default_sort_order;
37 static char *dso_list_str, *comm_list_str, *sym_list_str,
38 *col_width_list_str;
39 static struct strlist *dso_list, *comm_list, *sym_list;
40 static char *field_sep;
42 static int input;
43 static int show_mask = SHOW_KERNEL | SHOW_USER | SHOW_HV;
45 static int dump_trace = 0;
46 #define dprintf(x...) do { if (dump_trace) printf(x); } while (0)
47 #define cdprintf(x...) do { if (dump_trace) color_fprintf(stdout, color, x); } while (0)
49 static int verbose;
50 #define eprintf(x...) do { if (verbose) fprintf(stderr, x); } while (0)
52 static int modules;
54 static int full_paths;
55 static int show_nr_samples;
57 static int show_threads;
58 static struct perf_read_values show_threads_values;
60 static char default_pretty_printing_style[] = "normal";
61 static char *pretty_printing_style = default_pretty_printing_style;
63 static unsigned long page_size;
64 static unsigned long mmap_window = 32;
66 static char default_parent_pattern[] = "^sys_|^do_page_fault";
67 static char *parent_pattern = default_parent_pattern;
68 static regex_t parent_regex;
70 static int exclude_other = 1;
72 static char callchain_default_opt[] = "fractal,0.5";
74 static int callchain;
76 static
77 struct callchain_param callchain_param = {
78 .mode = CHAIN_GRAPH_REL,
79 .min_percent = 0.5
82 static u64 sample_type;
84 struct ip_event {
85 struct perf_event_header header;
86 u64 ip;
87 u32 pid, tid;
88 unsigned char __more_data[];
91 struct mmap_event {
92 struct perf_event_header header;
93 u32 pid, tid;
94 u64 start;
95 u64 len;
96 u64 pgoff;
97 char filename[PATH_MAX];
100 struct comm_event {
101 struct perf_event_header header;
102 u32 pid, tid;
103 char comm[16];
106 struct fork_event {
107 struct perf_event_header header;
108 u32 pid, ppid;
109 u32 tid, ptid;
112 struct lost_event {
113 struct perf_event_header header;
114 u64 id;
115 u64 lost;
118 struct read_event {
119 struct perf_event_header header;
120 u32 pid,tid;
121 u64 value;
122 u64 time_enabled;
123 u64 time_running;
124 u64 id;
127 typedef union event_union {
128 struct perf_event_header header;
129 struct ip_event ip;
130 struct mmap_event mmap;
131 struct comm_event comm;
132 struct fork_event fork;
133 struct lost_event lost;
134 struct read_event read;
135 } event_t;
137 static int repsep_fprintf(FILE *fp, const char *fmt, ...)
139 int n;
140 va_list ap;
142 va_start(ap, fmt);
143 if (!field_sep)
144 n = vfprintf(fp, fmt, ap);
145 else {
146 char *bf = NULL;
147 n = vasprintf(&bf, fmt, ap);
148 if (n > 0) {
149 char *sep = bf;
150 while (1) {
151 sep = strchr(sep, *field_sep);
152 if (sep == NULL)
153 break;
154 *sep = '.';
157 fputs(bf, fp);
158 free(bf);
160 va_end(ap);
161 return n;
164 static LIST_HEAD(dsos);
165 static struct dso *kernel_dso;
166 static struct dso *vdso;
167 static struct dso *hypervisor_dso;
169 static void dsos__add(struct dso *dso)
171 list_add_tail(&dso->node, &dsos);
174 static struct dso *dsos__find(const char *name)
176 struct dso *pos;
178 list_for_each_entry(pos, &dsos, node)
179 if (strcmp(pos->name, name) == 0)
180 return pos;
181 return NULL;
184 static struct dso *dsos__findnew(const char *name)
186 struct dso *dso = dsos__find(name);
187 int nr;
189 if (dso)
190 return dso;
192 dso = dso__new(name, 0);
193 if (!dso)
194 goto out_delete_dso;
196 nr = dso__load(dso, NULL, verbose);
197 if (nr < 0) {
198 eprintf("Failed to open: %s\n", name);
199 goto out_delete_dso;
201 if (!nr)
202 eprintf("No symbols found in: %s, maybe install a debug package?\n", name);
204 dsos__add(dso);
206 return dso;
208 out_delete_dso:
209 dso__delete(dso);
210 return NULL;
213 static void dsos__fprintf(FILE *fp)
215 struct dso *pos;
217 list_for_each_entry(pos, &dsos, node)
218 dso__fprintf(pos, fp);
221 static struct symbol *vdso__find_symbol(struct dso *dso, u64 ip)
223 return dso__find_symbol(dso, ip);
226 static int load_kernel(void)
228 int err;
230 kernel_dso = dso__new("[kernel]", 0);
231 if (!kernel_dso)
232 return -1;
234 err = dso__load_kernel(kernel_dso, vmlinux, NULL, verbose, modules);
235 if (err <= 0) {
236 dso__delete(kernel_dso);
237 kernel_dso = NULL;
238 } else
239 dsos__add(kernel_dso);
241 vdso = dso__new("[vdso]", 0);
242 if (!vdso)
243 return -1;
245 vdso->find_symbol = vdso__find_symbol;
247 dsos__add(vdso);
249 hypervisor_dso = dso__new("[hypervisor]", 0);
250 if (!hypervisor_dso)
251 return -1;
252 dsos__add(hypervisor_dso);
254 return err;
257 static char __cwd[PATH_MAX];
258 static char *cwd = __cwd;
259 static int cwdlen;
261 static int strcommon(const char *pathname)
263 int n = 0;
265 while (n < cwdlen && pathname[n] == cwd[n])
266 ++n;
268 return n;
271 struct map {
272 struct list_head node;
273 u64 start;
274 u64 end;
275 u64 pgoff;
276 u64 (*map_ip)(struct map *, u64);
277 struct dso *dso;
280 static u64 map__map_ip(struct map *map, u64 ip)
282 return ip - map->start + map->pgoff;
285 static u64 vdso__map_ip(struct map *map __used, u64 ip)
287 return ip;
290 static inline int is_anon_memory(const char *filename)
292 return strcmp(filename, "//anon") == 0;
295 static struct map *map__new(struct mmap_event *event)
297 struct map *self = malloc(sizeof(*self));
299 if (self != NULL) {
300 const char *filename = event->filename;
301 char newfilename[PATH_MAX];
302 int anon;
304 if (cwd) {
305 int n = strcommon(filename);
307 if (n == cwdlen) {
308 snprintf(newfilename, sizeof(newfilename),
309 ".%s", filename + n);
310 filename = newfilename;
314 anon = is_anon_memory(filename);
316 if (anon) {
317 snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", event->pid);
318 filename = newfilename;
321 self->start = event->start;
322 self->end = event->start + event->len;
323 self->pgoff = event->pgoff;
325 self->dso = dsos__findnew(filename);
326 if (self->dso == NULL)
327 goto out_delete;
329 if (self->dso == vdso || anon)
330 self->map_ip = vdso__map_ip;
331 else
332 self->map_ip = map__map_ip;
334 return self;
335 out_delete:
336 free(self);
337 return NULL;
340 static struct map *map__clone(struct map *self)
342 struct map *map = malloc(sizeof(*self));
344 if (!map)
345 return NULL;
347 memcpy(map, self, sizeof(*self));
349 return map;
352 static int map__overlap(struct map *l, struct map *r)
354 if (l->start > r->start) {
355 struct map *t = l;
356 l = r;
357 r = t;
360 if (l->end > r->start)
361 return 1;
363 return 0;
366 static size_t map__fprintf(struct map *self, FILE *fp)
368 return fprintf(fp, " %Lx-%Lx %Lx %s\n",
369 self->start, self->end, self->pgoff, self->dso->name);
373 struct thread {
374 struct rb_node rb_node;
375 struct list_head maps;
376 pid_t pid;
377 char *comm;
380 static struct thread *thread__new(pid_t pid)
382 struct thread *self = malloc(sizeof(*self));
384 if (self != NULL) {
385 self->pid = pid;
386 self->comm = malloc(32);
387 if (self->comm)
388 snprintf(self->comm, 32, ":%d", self->pid);
389 INIT_LIST_HEAD(&self->maps);
392 return self;
395 static unsigned int dsos__col_width,
396 comms__col_width,
397 threads__col_width;
399 static int thread__set_comm(struct thread *self, const char *comm)
401 if (self->comm)
402 free(self->comm);
403 self->comm = strdup(comm);
404 if (!self->comm)
405 return -ENOMEM;
407 if (!col_width_list_str && !field_sep &&
408 (!comm_list || strlist__has_entry(comm_list, comm))) {
409 unsigned int slen = strlen(comm);
410 if (slen > comms__col_width) {
411 comms__col_width = slen;
412 threads__col_width = slen + 6;
416 return 0;
419 static size_t thread__fprintf(struct thread *self, FILE *fp)
421 struct map *pos;
422 size_t ret = fprintf(fp, "Thread %d %s\n", self->pid, self->comm);
424 list_for_each_entry(pos, &self->maps, node)
425 ret += map__fprintf(pos, fp);
427 return ret;
431 static struct rb_root threads;
432 static struct thread *last_match;
434 static struct thread *threads__findnew(pid_t pid)
436 struct rb_node **p = &threads.rb_node;
437 struct rb_node *parent = NULL;
438 struct thread *th;
441 * Font-end cache - PID lookups come in blocks,
442 * so most of the time we dont have to look up
443 * the full rbtree:
445 if (last_match && last_match->pid == pid)
446 return last_match;
448 while (*p != NULL) {
449 parent = *p;
450 th = rb_entry(parent, struct thread, rb_node);
452 if (th->pid == pid) {
453 last_match = th;
454 return th;
457 if (pid < th->pid)
458 p = &(*p)->rb_left;
459 else
460 p = &(*p)->rb_right;
463 th = thread__new(pid);
464 if (th != NULL) {
465 rb_link_node(&th->rb_node, parent, p);
466 rb_insert_color(&th->rb_node, &threads);
467 last_match = th;
470 return th;
473 static void thread__insert_map(struct thread *self, struct map *map)
475 struct map *pos, *tmp;
477 list_for_each_entry_safe(pos, tmp, &self->maps, node) {
478 if (map__overlap(pos, map)) {
479 if (verbose >= 2) {
480 printf("overlapping maps:\n");
481 map__fprintf(map, stdout);
482 map__fprintf(pos, stdout);
485 if (map->start <= pos->start && map->end > pos->start)
486 pos->start = map->end;
488 if (map->end >= pos->end && map->start < pos->end)
489 pos->end = map->start;
491 if (verbose >= 2) {
492 printf("after collision:\n");
493 map__fprintf(pos, stdout);
496 if (pos->start >= pos->end) {
497 list_del_init(&pos->node);
498 free(pos);
503 list_add_tail(&map->node, &self->maps);
506 static int thread__fork(struct thread *self, struct thread *parent)
508 struct map *map;
510 if (self->comm)
511 free(self->comm);
512 self->comm = strdup(parent->comm);
513 if (!self->comm)
514 return -ENOMEM;
516 list_for_each_entry(map, &parent->maps, node) {
517 struct map *new = map__clone(map);
518 if (!new)
519 return -ENOMEM;
520 thread__insert_map(self, new);
523 return 0;
526 static struct map *thread__find_map(struct thread *self, u64 ip)
528 struct map *pos;
530 if (self == NULL)
531 return NULL;
533 list_for_each_entry(pos, &self->maps, node)
534 if (ip >= pos->start && ip <= pos->end)
535 return pos;
537 return NULL;
540 static size_t threads__fprintf(FILE *fp)
542 size_t ret = 0;
543 struct rb_node *nd;
545 for (nd = rb_first(&threads); nd; nd = rb_next(nd)) {
546 struct thread *pos = rb_entry(nd, struct thread, rb_node);
548 ret += thread__fprintf(pos, fp);
551 return ret;
555 * histogram, sorted on item, collects counts
558 static struct rb_root hist;
560 struct hist_entry {
561 struct rb_node rb_node;
563 struct thread *thread;
564 struct map *map;
565 struct dso *dso;
566 struct symbol *sym;
567 struct symbol *parent;
568 u64 ip;
569 char level;
570 struct callchain_node callchain;
571 struct rb_root sorted_chain;
573 u64 count;
577 * configurable sorting bits
580 struct sort_entry {
581 struct list_head list;
583 char *header;
585 int64_t (*cmp)(struct hist_entry *, struct hist_entry *);
586 int64_t (*collapse)(struct hist_entry *, struct hist_entry *);
587 size_t (*print)(FILE *fp, struct hist_entry *, unsigned int width);
588 unsigned int *width;
589 bool elide;
592 static int64_t cmp_null(void *l, void *r)
594 if (!l && !r)
595 return 0;
596 else if (!l)
597 return -1;
598 else
599 return 1;
602 /* --sort pid */
604 static int64_t
605 sort__thread_cmp(struct hist_entry *left, struct hist_entry *right)
607 return right->thread->pid - left->thread->pid;
610 static size_t
611 sort__thread_print(FILE *fp, struct hist_entry *self, unsigned int width)
613 return repsep_fprintf(fp, "%*s:%5d", width - 6,
614 self->thread->comm ?: "", self->thread->pid);
617 static struct sort_entry sort_thread = {
618 .header = "Command: Pid",
619 .cmp = sort__thread_cmp,
620 .print = sort__thread_print,
621 .width = &threads__col_width,
624 /* --sort comm */
626 static int64_t
627 sort__comm_cmp(struct hist_entry *left, struct hist_entry *right)
629 return right->thread->pid - left->thread->pid;
632 static int64_t
633 sort__comm_collapse(struct hist_entry *left, struct hist_entry *right)
635 char *comm_l = left->thread->comm;
636 char *comm_r = right->thread->comm;
638 if (!comm_l || !comm_r)
639 return cmp_null(comm_l, comm_r);
641 return strcmp(comm_l, comm_r);
644 static size_t
645 sort__comm_print(FILE *fp, struct hist_entry *self, unsigned int width)
647 return repsep_fprintf(fp, "%*s", width, self->thread->comm);
650 static struct sort_entry sort_comm = {
651 .header = "Command",
652 .cmp = sort__comm_cmp,
653 .collapse = sort__comm_collapse,
654 .print = sort__comm_print,
655 .width = &comms__col_width,
658 /* --sort dso */
660 static int64_t
661 sort__dso_cmp(struct hist_entry *left, struct hist_entry *right)
663 struct dso *dso_l = left->dso;
664 struct dso *dso_r = right->dso;
666 if (!dso_l || !dso_r)
667 return cmp_null(dso_l, dso_r);
669 return strcmp(dso_l->name, dso_r->name);
672 static size_t
673 sort__dso_print(FILE *fp, struct hist_entry *self, unsigned int width)
675 if (self->dso)
676 return repsep_fprintf(fp, "%-*s", width, self->dso->name);
678 return repsep_fprintf(fp, "%*llx", width, (u64)self->ip);
681 static struct sort_entry sort_dso = {
682 .header = "Shared Object",
683 .cmp = sort__dso_cmp,
684 .print = sort__dso_print,
685 .width = &dsos__col_width,
688 /* --sort symbol */
690 static int64_t
691 sort__sym_cmp(struct hist_entry *left, struct hist_entry *right)
693 u64 ip_l, ip_r;
695 if (left->sym == right->sym)
696 return 0;
698 ip_l = left->sym ? left->sym->start : left->ip;
699 ip_r = right->sym ? right->sym->start : right->ip;
701 return (int64_t)(ip_r - ip_l);
704 static size_t
705 sort__sym_print(FILE *fp, struct hist_entry *self, unsigned int width __used)
707 size_t ret = 0;
709 if (verbose)
710 ret += repsep_fprintf(fp, "%#018llx %c ", (u64)self->ip,
711 dso__symtab_origin(self->dso));
713 ret += repsep_fprintf(fp, "[%c] ", self->level);
714 if (self->sym) {
715 ret += repsep_fprintf(fp, "%s", self->sym->name);
717 if (self->sym->module)
718 ret += repsep_fprintf(fp, "\t[%s]",
719 self->sym->module->name);
720 } else {
721 ret += repsep_fprintf(fp, "%#016llx", (u64)self->ip);
724 return ret;
727 static struct sort_entry sort_sym = {
728 .header = "Symbol",
729 .cmp = sort__sym_cmp,
730 .print = sort__sym_print,
733 /* --sort parent */
735 static int64_t
736 sort__parent_cmp(struct hist_entry *left, struct hist_entry *right)
738 struct symbol *sym_l = left->parent;
739 struct symbol *sym_r = right->parent;
741 if (!sym_l || !sym_r)
742 return cmp_null(sym_l, sym_r);
744 return strcmp(sym_l->name, sym_r->name);
747 static size_t
748 sort__parent_print(FILE *fp, struct hist_entry *self, unsigned int width)
750 return repsep_fprintf(fp, "%-*s", width,
751 self->parent ? self->parent->name : "[other]");
754 static unsigned int parent_symbol__col_width;
756 static struct sort_entry sort_parent = {
757 .header = "Parent symbol",
758 .cmp = sort__parent_cmp,
759 .print = sort__parent_print,
760 .width = &parent_symbol__col_width,
763 static int sort__need_collapse = 0;
764 static int sort__has_parent = 0;
766 struct sort_dimension {
767 char *name;
768 struct sort_entry *entry;
769 int taken;
772 static struct sort_dimension sort_dimensions[] = {
773 { .name = "pid", .entry = &sort_thread, },
774 { .name = "comm", .entry = &sort_comm, },
775 { .name = "dso", .entry = &sort_dso, },
776 { .name = "symbol", .entry = &sort_sym, },
777 { .name = "parent", .entry = &sort_parent, },
780 static LIST_HEAD(hist_entry__sort_list);
782 static int sort_dimension__add(char *tok)
784 unsigned int i;
786 for (i = 0; i < ARRAY_SIZE(sort_dimensions); i++) {
787 struct sort_dimension *sd = &sort_dimensions[i];
789 if (sd->taken)
790 continue;
792 if (strncasecmp(tok, sd->name, strlen(tok)))
793 continue;
795 if (sd->entry->collapse)
796 sort__need_collapse = 1;
798 if (sd->entry == &sort_parent) {
799 int ret = regcomp(&parent_regex, parent_pattern, REG_EXTENDED);
800 if (ret) {
801 char err[BUFSIZ];
803 regerror(ret, &parent_regex, err, sizeof(err));
804 fprintf(stderr, "Invalid regex: %s\n%s",
805 parent_pattern, err);
806 exit(-1);
808 sort__has_parent = 1;
811 list_add_tail(&sd->entry->list, &hist_entry__sort_list);
812 sd->taken = 1;
814 return 0;
817 return -ESRCH;
820 static int64_t
821 hist_entry__cmp(struct hist_entry *left, struct hist_entry *right)
823 struct sort_entry *se;
824 int64_t cmp = 0;
826 list_for_each_entry(se, &hist_entry__sort_list, list) {
827 cmp = se->cmp(left, right);
828 if (cmp)
829 break;
832 return cmp;
835 static int64_t
836 hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
838 struct sort_entry *se;
839 int64_t cmp = 0;
841 list_for_each_entry(se, &hist_entry__sort_list, list) {
842 int64_t (*f)(struct hist_entry *, struct hist_entry *);
844 f = se->collapse ?: se->cmp;
846 cmp = f(left, right);
847 if (cmp)
848 break;
851 return cmp;
854 static size_t ipchain__fprintf_graph_line(FILE *fp, int depth, int depth_mask)
856 int i;
857 size_t ret = 0;
859 ret += fprintf(fp, "%s", " ");
861 for (i = 0; i < depth; i++)
862 if (depth_mask & (1 << i))
863 ret += fprintf(fp, "| ");
864 else
865 ret += fprintf(fp, " ");
867 ret += fprintf(fp, "\n");
869 return ret;
871 static size_t
872 ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain, int depth,
873 int depth_mask, int count, u64 total_samples,
874 int hits)
876 int i;
877 size_t ret = 0;
879 ret += fprintf(fp, "%s", " ");
880 for (i = 0; i < depth; i++) {
881 if (depth_mask & (1 << i))
882 ret += fprintf(fp, "|");
883 else
884 ret += fprintf(fp, " ");
885 if (!count && i == depth - 1) {
886 double percent;
888 percent = hits * 100.0 / total_samples;
889 ret += percent_color_fprintf(fp, "--%2.2f%%-- ", percent);
890 } else
891 ret += fprintf(fp, "%s", " ");
893 if (chain->sym)
894 ret += fprintf(fp, "%s\n", chain->sym->name);
895 else
896 ret += fprintf(fp, "%p\n", (void *)(long)chain->ip);
898 return ret;
901 static struct symbol *rem_sq_bracket;
902 static struct callchain_list rem_hits;
904 static void init_rem_hits(void)
906 rem_sq_bracket = malloc(sizeof(*rem_sq_bracket) + 6);
907 if (!rem_sq_bracket) {
908 fprintf(stderr, "Not enough memory to display remaining hits\n");
909 return;
912 strcpy(rem_sq_bracket->name, "[...]");
913 rem_hits.sym = rem_sq_bracket;
916 static size_t
917 callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
918 u64 total_samples, int depth, int depth_mask)
920 struct rb_node *node, *next;
921 struct callchain_node *child;
922 struct callchain_list *chain;
923 int new_depth_mask = depth_mask;
924 u64 new_total;
925 u64 remaining;
926 size_t ret = 0;
927 int i;
929 if (callchain_param.mode == CHAIN_GRAPH_REL)
930 new_total = self->children_hit;
931 else
932 new_total = total_samples;
934 remaining = new_total;
936 node = rb_first(&self->rb_root);
937 while (node) {
938 u64 cumul;
940 child = rb_entry(node, struct callchain_node, rb_node);
941 cumul = cumul_hits(child);
942 remaining -= cumul;
945 * The depth mask manages the output of pipes that show
946 * the depth. We don't want to keep the pipes of the current
947 * level for the last child of this depth.
948 * Except if we have remaining filtered hits. They will
949 * supersede the last child
951 next = rb_next(node);
952 if (!next && (callchain_param.mode != CHAIN_GRAPH_REL || !remaining))
953 new_depth_mask &= ~(1 << (depth - 1));
956 * But we keep the older depth mask for the line seperator
957 * to keep the level link until we reach the last child
959 ret += ipchain__fprintf_graph_line(fp, depth, depth_mask);
960 i = 0;
961 list_for_each_entry(chain, &child->val, list) {
962 if (chain->ip >= PERF_CONTEXT_MAX)
963 continue;
964 ret += ipchain__fprintf_graph(fp, chain, depth,
965 new_depth_mask, i++,
966 new_total,
967 cumul);
969 ret += callchain__fprintf_graph(fp, child, new_total,
970 depth + 1,
971 new_depth_mask | (1 << depth));
972 node = next;
975 if (callchain_param.mode == CHAIN_GRAPH_REL &&
976 remaining && remaining != new_total) {
978 if (!rem_sq_bracket)
979 return ret;
981 new_depth_mask &= ~(1 << (depth - 1));
983 ret += ipchain__fprintf_graph(fp, &rem_hits, depth,
984 new_depth_mask, 0, new_total,
985 remaining);
988 return ret;
991 static size_t
992 callchain__fprintf_flat(FILE *fp, struct callchain_node *self,
993 u64 total_samples)
995 struct callchain_list *chain;
996 size_t ret = 0;
998 if (!self)
999 return 0;
1001 ret += callchain__fprintf_flat(fp, self->parent, total_samples);
1004 list_for_each_entry(chain, &self->val, list) {
1005 if (chain->ip >= PERF_CONTEXT_MAX)
1006 continue;
1007 if (chain->sym)
1008 ret += fprintf(fp, " %s\n", chain->sym->name);
1009 else
1010 ret += fprintf(fp, " %p\n",
1011 (void *)(long)chain->ip);
1014 return ret;
1017 static size_t
1018 hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self,
1019 u64 total_samples)
1021 struct rb_node *rb_node;
1022 struct callchain_node *chain;
1023 size_t ret = 0;
1025 rb_node = rb_first(&self->sorted_chain);
1026 while (rb_node) {
1027 double percent;
1029 chain = rb_entry(rb_node, struct callchain_node, rb_node);
1030 percent = chain->hit * 100.0 / total_samples;
1031 switch (callchain_param.mode) {
1032 case CHAIN_FLAT:
1033 ret += percent_color_fprintf(fp, " %6.2f%%\n",
1034 percent);
1035 ret += callchain__fprintf_flat(fp, chain, total_samples);
1036 break;
1037 case CHAIN_GRAPH_ABS: /* Falldown */
1038 case CHAIN_GRAPH_REL:
1039 ret += callchain__fprintf_graph(fp, chain,
1040 total_samples, 1, 1);
1041 default:
1042 break;
1044 ret += fprintf(fp, "\n");
1045 rb_node = rb_next(rb_node);
1048 return ret;
1052 static size_t
1053 hist_entry__fprintf(FILE *fp, struct hist_entry *self, u64 total_samples)
1055 struct sort_entry *se;
1056 size_t ret;
1058 if (exclude_other && !self->parent)
1059 return 0;
1061 if (total_samples)
1062 ret = percent_color_fprintf(fp,
1063 field_sep ? "%.2f" : " %6.2f%%",
1064 (self->count * 100.0) / total_samples);
1065 else
1066 ret = fprintf(fp, field_sep ? "%lld" : "%12lld ", self->count);
1068 if (show_nr_samples) {
1069 if (field_sep)
1070 fprintf(fp, "%c%lld", *field_sep, self->count);
1071 else
1072 fprintf(fp, "%11lld", self->count);
1075 list_for_each_entry(se, &hist_entry__sort_list, list) {
1076 if (se->elide)
1077 continue;
1079 fprintf(fp, "%s", field_sep ?: " ");
1080 ret += se->print(fp, self, se->width ? *se->width : 0);
1083 ret += fprintf(fp, "\n");
1085 if (callchain)
1086 hist_entry_callchain__fprintf(fp, self, total_samples);
1088 return ret;
1095 static void dso__calc_col_width(struct dso *self)
1097 if (!col_width_list_str && !field_sep &&
1098 (!dso_list || strlist__has_entry(dso_list, self->name))) {
1099 unsigned int slen = strlen(self->name);
1100 if (slen > dsos__col_width)
1101 dsos__col_width = slen;
1104 self->slen_calculated = 1;
1107 static struct symbol *
1108 resolve_symbol(struct thread *thread, struct map **mapp,
1109 struct dso **dsop, u64 *ipp)
1111 struct dso *dso = dsop ? *dsop : NULL;
1112 struct map *map = mapp ? *mapp : NULL;
1113 u64 ip = *ipp;
1115 if (!thread)
1116 return NULL;
1118 if (dso)
1119 goto got_dso;
1121 if (map)
1122 goto got_map;
1124 map = thread__find_map(thread, ip);
1125 if (map != NULL) {
1127 * We have to do this here as we may have a dso
1128 * with no symbol hit that has a name longer than
1129 * the ones with symbols sampled.
1131 if (!sort_dso.elide && !map->dso->slen_calculated)
1132 dso__calc_col_width(map->dso);
1134 if (mapp)
1135 *mapp = map;
1136 got_map:
1137 ip = map->map_ip(map, ip);
1139 dso = map->dso;
1140 } else {
1142 * If this is outside of all known maps,
1143 * and is a negative address, try to look it
1144 * up in the kernel dso, as it might be a
1145 * vsyscall (which executes in user-mode):
1147 if ((long long)ip < 0)
1148 dso = kernel_dso;
1150 dprintf(" ...... dso: %s\n", dso ? dso->name : "<not found>");
1151 dprintf(" ...... map: %Lx -> %Lx\n", *ipp, ip);
1152 *ipp = ip;
1154 if (dsop)
1155 *dsop = dso;
1157 if (!dso)
1158 return NULL;
1159 got_dso:
1160 return dso->find_symbol(dso, ip);
1163 static int call__match(struct symbol *sym)
1165 if (sym->name && !regexec(&parent_regex, sym->name, 0, NULL, 0))
1166 return 1;
1168 return 0;
1171 static struct symbol **
1172 resolve_callchain(struct thread *thread, struct map *map __used,
1173 struct ip_callchain *chain, struct hist_entry *entry)
1175 u64 context = PERF_CONTEXT_MAX;
1176 struct symbol **syms = NULL;
1177 unsigned int i;
1179 if (callchain) {
1180 syms = calloc(chain->nr, sizeof(*syms));
1181 if (!syms) {
1182 fprintf(stderr, "Can't allocate memory for symbols\n");
1183 exit(-1);
1187 for (i = 0; i < chain->nr; i++) {
1188 u64 ip = chain->ips[i];
1189 struct dso *dso = NULL;
1190 struct symbol *sym;
1192 if (ip >= PERF_CONTEXT_MAX) {
1193 context = ip;
1194 continue;
1197 switch (context) {
1198 case PERF_CONTEXT_HV:
1199 dso = hypervisor_dso;
1200 break;
1201 case PERF_CONTEXT_KERNEL:
1202 dso = kernel_dso;
1203 break;
1204 default:
1205 break;
1208 sym = resolve_symbol(thread, NULL, &dso, &ip);
1210 if (sym) {
1211 if (sort__has_parent && call__match(sym) &&
1212 !entry->parent)
1213 entry->parent = sym;
1214 if (!callchain)
1215 break;
1216 syms[i] = sym;
1220 return syms;
1224 * collect histogram counts
1227 static int
1228 hist_entry__add(struct thread *thread, struct map *map, struct dso *dso,
1229 struct symbol *sym, u64 ip, struct ip_callchain *chain,
1230 char level, u64 count)
1232 struct rb_node **p = &hist.rb_node;
1233 struct rb_node *parent = NULL;
1234 struct hist_entry *he;
1235 struct symbol **syms = NULL;
1236 struct hist_entry entry = {
1237 .thread = thread,
1238 .map = map,
1239 .dso = dso,
1240 .sym = sym,
1241 .ip = ip,
1242 .level = level,
1243 .count = count,
1244 .parent = NULL,
1245 .sorted_chain = RB_ROOT
1247 int cmp;
1249 if ((sort__has_parent || callchain) && chain)
1250 syms = resolve_callchain(thread, map, chain, &entry);
1252 while (*p != NULL) {
1253 parent = *p;
1254 he = rb_entry(parent, struct hist_entry, rb_node);
1256 cmp = hist_entry__cmp(&entry, he);
1258 if (!cmp) {
1259 he->count += count;
1260 if (callchain) {
1261 append_chain(&he->callchain, chain, syms);
1262 free(syms);
1264 return 0;
1267 if (cmp < 0)
1268 p = &(*p)->rb_left;
1269 else
1270 p = &(*p)->rb_right;
1273 he = malloc(sizeof(*he));
1274 if (!he)
1275 return -ENOMEM;
1276 *he = entry;
1277 if (callchain) {
1278 callchain_init(&he->callchain);
1279 append_chain(&he->callchain, chain, syms);
1280 free(syms);
1282 rb_link_node(&he->rb_node, parent, p);
1283 rb_insert_color(&he->rb_node, &hist);
1285 return 0;
1288 static void hist_entry__free(struct hist_entry *he)
1290 free(he);
1294 * collapse the histogram
1297 static struct rb_root collapse_hists;
1299 static void collapse__insert_entry(struct hist_entry *he)
1301 struct rb_node **p = &collapse_hists.rb_node;
1302 struct rb_node *parent = NULL;
1303 struct hist_entry *iter;
1304 int64_t cmp;
1306 while (*p != NULL) {
1307 parent = *p;
1308 iter = rb_entry(parent, struct hist_entry, rb_node);
1310 cmp = hist_entry__collapse(iter, he);
1312 if (!cmp) {
1313 iter->count += he->count;
1314 hist_entry__free(he);
1315 return;
1318 if (cmp < 0)
1319 p = &(*p)->rb_left;
1320 else
1321 p = &(*p)->rb_right;
1324 rb_link_node(&he->rb_node, parent, p);
1325 rb_insert_color(&he->rb_node, &collapse_hists);
1328 static void collapse__resort(void)
1330 struct rb_node *next;
1331 struct hist_entry *n;
1333 if (!sort__need_collapse)
1334 return;
1336 next = rb_first(&hist);
1337 while (next) {
1338 n = rb_entry(next, struct hist_entry, rb_node);
1339 next = rb_next(&n->rb_node);
1341 rb_erase(&n->rb_node, &hist);
1342 collapse__insert_entry(n);
1347 * reverse the map, sort on count.
1350 static struct rb_root output_hists;
1352 static void output__insert_entry(struct hist_entry *he, u64 min_callchain_hits)
1354 struct rb_node **p = &output_hists.rb_node;
1355 struct rb_node *parent = NULL;
1356 struct hist_entry *iter;
1358 if (callchain)
1359 callchain_param.sort(&he->sorted_chain, &he->callchain,
1360 min_callchain_hits, &callchain_param);
1362 while (*p != NULL) {
1363 parent = *p;
1364 iter = rb_entry(parent, struct hist_entry, rb_node);
1366 if (he->count > iter->count)
1367 p = &(*p)->rb_left;
1368 else
1369 p = &(*p)->rb_right;
1372 rb_link_node(&he->rb_node, parent, p);
1373 rb_insert_color(&he->rb_node, &output_hists);
1376 static void output__resort(u64 total_samples)
1378 struct rb_node *next;
1379 struct hist_entry *n;
1380 struct rb_root *tree = &hist;
1381 u64 min_callchain_hits;
1383 min_callchain_hits = total_samples * (callchain_param.min_percent / 100);
1385 if (sort__need_collapse)
1386 tree = &collapse_hists;
1388 next = rb_first(tree);
1390 while (next) {
1391 n = rb_entry(next, struct hist_entry, rb_node);
1392 next = rb_next(&n->rb_node);
1394 rb_erase(&n->rb_node, tree);
1395 output__insert_entry(n, min_callchain_hits);
1399 static size_t output__fprintf(FILE *fp, u64 total_samples)
1401 struct hist_entry *pos;
1402 struct sort_entry *se;
1403 struct rb_node *nd;
1404 size_t ret = 0;
1405 unsigned int width;
1406 char *col_width = col_width_list_str;
1407 int raw_printing_style;
1409 raw_printing_style = !strcmp(pretty_printing_style, "raw");
1411 init_rem_hits();
1413 fprintf(fp, "# Samples: %Ld\n", (u64)total_samples);
1414 fprintf(fp, "#\n");
1416 fprintf(fp, "# Overhead");
1417 if (show_nr_samples) {
1418 if (field_sep)
1419 fprintf(fp, "%cSamples", *field_sep);
1420 else
1421 fputs(" Samples ", fp);
1423 list_for_each_entry(se, &hist_entry__sort_list, list) {
1424 if (se->elide)
1425 continue;
1426 if (field_sep) {
1427 fprintf(fp, "%c%s", *field_sep, se->header);
1428 continue;
1430 width = strlen(se->header);
1431 if (se->width) {
1432 if (col_width_list_str) {
1433 if (col_width) {
1434 *se->width = atoi(col_width);
1435 col_width = strchr(col_width, ',');
1436 if (col_width)
1437 ++col_width;
1440 width = *se->width = max(*se->width, width);
1442 fprintf(fp, " %*s", width, se->header);
1444 fprintf(fp, "\n");
1446 if (field_sep)
1447 goto print_entries;
1449 fprintf(fp, "# ........");
1450 if (show_nr_samples)
1451 fprintf(fp, " ..........");
1452 list_for_each_entry(se, &hist_entry__sort_list, list) {
1453 unsigned int i;
1455 if (se->elide)
1456 continue;
1458 fprintf(fp, " ");
1459 if (se->width)
1460 width = *se->width;
1461 else
1462 width = strlen(se->header);
1463 for (i = 0; i < width; i++)
1464 fprintf(fp, ".");
1466 fprintf(fp, "\n");
1468 fprintf(fp, "#\n");
1470 print_entries:
1471 for (nd = rb_first(&output_hists); nd; nd = rb_next(nd)) {
1472 pos = rb_entry(nd, struct hist_entry, rb_node);
1473 ret += hist_entry__fprintf(fp, pos, total_samples);
1476 if (sort_order == default_sort_order &&
1477 parent_pattern == default_parent_pattern) {
1478 fprintf(fp, "#\n");
1479 fprintf(fp, "# (For a higher level overview, try: perf report --sort comm,dso)\n");
1480 fprintf(fp, "#\n");
1482 fprintf(fp, "\n");
1484 free(rem_sq_bracket);
1486 if (show_threads)
1487 perf_read_values_display(fp, &show_threads_values,
1488 raw_printing_style);
1490 return ret;
1493 static void register_idle_thread(void)
1495 struct thread *thread = threads__findnew(0);
1497 if (thread == NULL ||
1498 thread__set_comm(thread, "[idle]")) {
1499 fprintf(stderr, "problem inserting idle task.\n");
1500 exit(-1);
1504 static unsigned long total = 0,
1505 total_mmap = 0,
1506 total_comm = 0,
1507 total_fork = 0,
1508 total_unknown = 0,
1509 total_lost = 0;
1511 static int validate_chain(struct ip_callchain *chain, event_t *event)
1513 unsigned int chain_size;
1515 chain_size = event->header.size;
1516 chain_size -= (unsigned long)&event->ip.__more_data - (unsigned long)event;
1518 if (chain->nr*sizeof(u64) > chain_size)
1519 return -1;
1521 return 0;
1524 static int
1525 process_sample_event(event_t *event, unsigned long offset, unsigned long head)
1527 char level;
1528 int show = 0;
1529 struct dso *dso = NULL;
1530 struct thread *thread = threads__findnew(event->ip.pid);
1531 u64 ip = event->ip.ip;
1532 u64 period = 1;
1533 struct map *map = NULL;
1534 void *more_data = event->ip.__more_data;
1535 struct ip_callchain *chain = NULL;
1536 int cpumode;
1538 if (sample_type & PERF_SAMPLE_PERIOD) {
1539 period = *(u64 *)more_data;
1540 more_data += sizeof(u64);
1543 dprintf("%p [%p]: PERF_EVENT_SAMPLE (IP, %d): %d: %p period: %Ld\n",
1544 (void *)(offset + head),
1545 (void *)(long)(event->header.size),
1546 event->header.misc,
1547 event->ip.pid,
1548 (void *)(long)ip,
1549 (long long)period);
1551 if (sample_type & PERF_SAMPLE_CALLCHAIN) {
1552 unsigned int i;
1554 chain = (void *)more_data;
1556 dprintf("... chain: nr:%Lu\n", chain->nr);
1558 if (validate_chain(chain, event) < 0) {
1559 eprintf("call-chain problem with event, skipping it.\n");
1560 return 0;
1563 if (dump_trace) {
1564 for (i = 0; i < chain->nr; i++)
1565 dprintf("..... %2d: %016Lx\n", i, chain->ips[i]);
1569 dprintf(" ... thread: %s:%d\n", thread->comm, thread->pid);
1571 if (thread == NULL) {
1572 eprintf("problem processing %d event, skipping it.\n",
1573 event->header.type);
1574 return -1;
1577 if (comm_list && !strlist__has_entry(comm_list, thread->comm))
1578 return 0;
1580 cpumode = event->header.misc & PERF_EVENT_MISC_CPUMODE_MASK;
1582 if (cpumode == PERF_EVENT_MISC_KERNEL) {
1583 show = SHOW_KERNEL;
1584 level = 'k';
1586 dso = kernel_dso;
1588 dprintf(" ...... dso: %s\n", dso->name);
1590 } else if (cpumode == PERF_EVENT_MISC_USER) {
1592 show = SHOW_USER;
1593 level = '.';
1595 } else {
1596 show = SHOW_HV;
1597 level = 'H';
1599 dso = hypervisor_dso;
1601 dprintf(" ...... dso: [hypervisor]\n");
1604 if (show & show_mask) {
1605 struct symbol *sym = resolve_symbol(thread, &map, &dso, &ip);
1607 if (dso_list && dso && dso->name && !strlist__has_entry(dso_list, dso->name))
1608 return 0;
1610 if (sym_list && sym && !strlist__has_entry(sym_list, sym->name))
1611 return 0;
1613 if (hist_entry__add(thread, map, dso, sym, ip, chain, level, period)) {
1614 eprintf("problem incrementing symbol count, skipping event\n");
1615 return -1;
1618 total += period;
1620 return 0;
1623 static int
1624 process_mmap_event(event_t *event, unsigned long offset, unsigned long head)
1626 struct thread *thread = threads__findnew(event->mmap.pid);
1627 struct map *map = map__new(&event->mmap);
1629 dprintf("%p [%p]: PERF_EVENT_MMAP %d: [%p(%p) @ %p]: %s\n",
1630 (void *)(offset + head),
1631 (void *)(long)(event->header.size),
1632 event->mmap.pid,
1633 (void *)(long)event->mmap.start,
1634 (void *)(long)event->mmap.len,
1635 (void *)(long)event->mmap.pgoff,
1636 event->mmap.filename);
1638 if (thread == NULL || map == NULL) {
1639 dprintf("problem processing PERF_EVENT_MMAP, skipping event.\n");
1640 return 0;
1643 thread__insert_map(thread, map);
1644 total_mmap++;
1646 return 0;
1649 static int
1650 process_comm_event(event_t *event, unsigned long offset, unsigned long head)
1652 struct thread *thread = threads__findnew(event->comm.pid);
1654 dprintf("%p [%p]: PERF_EVENT_COMM: %s:%d\n",
1655 (void *)(offset + head),
1656 (void *)(long)(event->header.size),
1657 event->comm.comm, event->comm.pid);
1659 if (thread == NULL ||
1660 thread__set_comm(thread, event->comm.comm)) {
1661 dprintf("problem processing PERF_EVENT_COMM, skipping event.\n");
1662 return -1;
1664 total_comm++;
1666 return 0;
1669 static int
1670 process_task_event(event_t *event, unsigned long offset, unsigned long head)
1672 struct thread *thread = threads__findnew(event->fork.pid);
1673 struct thread *parent = threads__findnew(event->fork.ppid);
1675 dprintf("%p [%p]: PERF_EVENT_%s: (%d:%d):(%d:%d)\n",
1676 (void *)(offset + head),
1677 (void *)(long)(event->header.size),
1678 event->header.type == PERF_EVENT_FORK ? "FORK" : "EXIT",
1679 event->fork.pid, event->fork.tid,
1680 event->fork.ppid, event->fork.ptid);
1683 * A thread clone will have the same PID for both
1684 * parent and child.
1686 if (thread == parent)
1687 return 0;
1689 if (event->header.type == PERF_EVENT_EXIT)
1690 return 0;
1692 if (!thread || !parent || thread__fork(thread, parent)) {
1693 dprintf("problem processing PERF_EVENT_FORK, skipping event.\n");
1694 return -1;
1696 total_fork++;
1698 return 0;
1701 static int
1702 process_lost_event(event_t *event, unsigned long offset, unsigned long head)
1704 dprintf("%p [%p]: PERF_EVENT_LOST: id:%Ld: lost:%Ld\n",
1705 (void *)(offset + head),
1706 (void *)(long)(event->header.size),
1707 event->lost.id,
1708 event->lost.lost);
1710 total_lost += event->lost.lost;
1712 return 0;
1715 static void trace_event(event_t *event)
1717 unsigned char *raw_event = (void *)event;
1718 char *color = PERF_COLOR_BLUE;
1719 int i, j;
1721 if (!dump_trace)
1722 return;
1724 dprintf(".");
1725 cdprintf("\n. ... raw event: size %d bytes\n", event->header.size);
1727 for (i = 0; i < event->header.size; i++) {
1728 if ((i & 15) == 0) {
1729 dprintf(".");
1730 cdprintf(" %04x: ", i);
1733 cdprintf(" %02x", raw_event[i]);
1735 if (((i & 15) == 15) || i == event->header.size-1) {
1736 cdprintf(" ");
1737 for (j = 0; j < 15-(i & 15); j++)
1738 cdprintf(" ");
1739 for (j = 0; j < (i & 15); j++) {
1740 if (isprint(raw_event[i-15+j]))
1741 cdprintf("%c", raw_event[i-15+j]);
1742 else
1743 cdprintf(".");
1745 cdprintf("\n");
1748 dprintf(".\n");
1751 static struct perf_header *header;
1753 static struct perf_counter_attr *perf_header__find_attr(u64 id)
1755 int i;
1757 for (i = 0; i < header->attrs; i++) {
1758 struct perf_header_attr *attr = header->attr[i];
1759 int j;
1761 for (j = 0; j < attr->ids; j++) {
1762 if (attr->id[j] == id)
1763 return &attr->attr;
1767 return NULL;
1770 static int
1771 process_read_event(event_t *event, unsigned long offset, unsigned long head)
1773 struct perf_counter_attr *attr = perf_header__find_attr(event->read.id);
1775 if (show_threads) {
1776 char *name = attr ? __event_name(attr->type, attr->config)
1777 : "unknown";
1778 perf_read_values_add_value(&show_threads_values,
1779 event->read.pid, event->read.tid,
1780 event->read.id,
1781 name,
1782 event->read.value);
1785 dprintf("%p [%p]: PERF_EVENT_READ: %d %d %s %Lu\n",
1786 (void *)(offset + head),
1787 (void *)(long)(event->header.size),
1788 event->read.pid,
1789 event->read.tid,
1790 attr ? __event_name(attr->type, attr->config)
1791 : "FAIL",
1792 event->read.value);
1794 return 0;
1797 static int
1798 process_event(event_t *event, unsigned long offset, unsigned long head)
1800 trace_event(event);
1802 switch (event->header.type) {
1803 case PERF_EVENT_SAMPLE:
1804 return process_sample_event(event, offset, head);
1806 case PERF_EVENT_MMAP:
1807 return process_mmap_event(event, offset, head);
1809 case PERF_EVENT_COMM:
1810 return process_comm_event(event, offset, head);
1812 case PERF_EVENT_FORK:
1813 case PERF_EVENT_EXIT:
1814 return process_task_event(event, offset, head);
1816 case PERF_EVENT_LOST:
1817 return process_lost_event(event, offset, head);
1819 case PERF_EVENT_READ:
1820 return process_read_event(event, offset, head);
1823 * We dont process them right now but they are fine:
1826 case PERF_EVENT_THROTTLE:
1827 case PERF_EVENT_UNTHROTTLE:
1828 return 0;
1830 default:
1831 return -1;
1834 return 0;
1837 static u64 perf_header__sample_type(void)
1839 u64 sample_type = 0;
1840 int i;
1842 for (i = 0; i < header->attrs; i++) {
1843 struct perf_header_attr *attr = header->attr[i];
1845 if (!sample_type)
1846 sample_type = attr->attr.sample_type;
1847 else if (sample_type != attr->attr.sample_type)
1848 die("non matching sample_type");
1851 return sample_type;
1854 static int __cmd_report(void)
1856 int ret, rc = EXIT_FAILURE;
1857 unsigned long offset = 0;
1858 unsigned long head, shift;
1859 struct stat stat;
1860 event_t *event;
1861 uint32_t size;
1862 char *buf;
1864 register_idle_thread();
1866 if (show_threads)
1867 perf_read_values_init(&show_threads_values);
1869 input = open(input_name, O_RDONLY);
1870 if (input < 0) {
1871 fprintf(stderr, " failed to open file: %s", input_name);
1872 if (!strcmp(input_name, "perf.data"))
1873 fprintf(stderr, " (try 'perf record' first)");
1874 fprintf(stderr, "\n");
1875 exit(-1);
1878 ret = fstat(input, &stat);
1879 if (ret < 0) {
1880 perror("failed to stat file");
1881 exit(-1);
1884 if (!stat.st_size) {
1885 fprintf(stderr, "zero-sized file, nothing to do!\n");
1886 exit(0);
1889 header = perf_header__read(input);
1890 head = header->data_offset;
1892 sample_type = perf_header__sample_type();
1894 if (!(sample_type & PERF_SAMPLE_CALLCHAIN)) {
1895 if (sort__has_parent) {
1896 fprintf(stderr, "selected --sort parent, but no"
1897 " callchain data. Did you call"
1898 " perf record without -g?\n");
1899 exit(-1);
1901 if (callchain) {
1902 fprintf(stderr, "selected -c but no callchain data."
1903 " Did you call perf record without"
1904 " -g?\n");
1905 exit(-1);
1907 } else if (callchain_param.mode != CHAIN_NONE && !callchain) {
1908 callchain = 1;
1909 if (register_callchain_param(&callchain_param) < 0) {
1910 fprintf(stderr, "Can't register callchain"
1911 " params\n");
1912 exit(-1);
1916 if (load_kernel() < 0) {
1917 perror("failed to load kernel symbols");
1918 return EXIT_FAILURE;
1921 if (!full_paths) {
1922 if (getcwd(__cwd, sizeof(__cwd)) == NULL) {
1923 perror("failed to get the current directory");
1924 return EXIT_FAILURE;
1926 cwdlen = strlen(cwd);
1927 } else {
1928 cwd = NULL;
1929 cwdlen = 0;
1932 shift = page_size * (head / page_size);
1933 offset += shift;
1934 head -= shift;
1936 remap:
1937 buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ,
1938 MAP_SHARED, input, offset);
1939 if (buf == MAP_FAILED) {
1940 perror("failed to mmap file");
1941 exit(-1);
1944 more:
1945 event = (event_t *)(buf + head);
1947 size = event->header.size;
1948 if (!size)
1949 size = 8;
1951 if (head + event->header.size >= page_size * mmap_window) {
1952 int ret;
1954 shift = page_size * (head / page_size);
1956 ret = munmap(buf, page_size * mmap_window);
1957 assert(ret == 0);
1959 offset += shift;
1960 head -= shift;
1961 goto remap;
1964 size = event->header.size;
1966 dprintf("\n%p [%p]: event: %d\n",
1967 (void *)(offset + head),
1968 (void *)(long)event->header.size,
1969 event->header.type);
1971 if (!size || process_event(event, offset, head) < 0) {
1973 dprintf("%p [%p]: skipping unknown header type: %d\n",
1974 (void *)(offset + head),
1975 (void *)(long)(event->header.size),
1976 event->header.type);
1978 total_unknown++;
1981 * assume we lost track of the stream, check alignment, and
1982 * increment a single u64 in the hope to catch on again 'soon'.
1985 if (unlikely(head & 7))
1986 head &= ~7ULL;
1988 size = 8;
1991 head += size;
1993 if (offset + head >= header->data_offset + header->data_size)
1994 goto done;
1996 if (offset + head < (unsigned long)stat.st_size)
1997 goto more;
1999 done:
2000 rc = EXIT_SUCCESS;
2001 close(input);
2003 dprintf(" IP events: %10ld\n", total);
2004 dprintf(" mmap events: %10ld\n", total_mmap);
2005 dprintf(" comm events: %10ld\n", total_comm);
2006 dprintf(" fork events: %10ld\n", total_fork);
2007 dprintf(" lost events: %10ld\n", total_lost);
2008 dprintf(" unknown events: %10ld\n", total_unknown);
2010 if (dump_trace)
2011 return 0;
2013 if (verbose >= 3)
2014 threads__fprintf(stdout);
2016 if (verbose >= 2)
2017 dsos__fprintf(stdout);
2019 collapse__resort();
2020 output__resort(total);
2021 output__fprintf(stdout, total);
2023 if (show_threads)
2024 perf_read_values_destroy(&show_threads_values);
2026 return rc;
2029 static int
2030 parse_callchain_opt(const struct option *opt __used, const char *arg,
2031 int unset __used)
2033 char *tok;
2034 char *endptr;
2036 callchain = 1;
2038 if (!arg)
2039 return 0;
2041 tok = strtok((char *)arg, ",");
2042 if (!tok)
2043 return -1;
2045 /* get the output mode */
2046 if (!strncmp(tok, "graph", strlen(arg)))
2047 callchain_param.mode = CHAIN_GRAPH_ABS;
2049 else if (!strncmp(tok, "flat", strlen(arg)))
2050 callchain_param.mode = CHAIN_FLAT;
2052 else if (!strncmp(tok, "fractal", strlen(arg)))
2053 callchain_param.mode = CHAIN_GRAPH_REL;
2055 else if (!strncmp(tok, "none", strlen(arg))) {
2056 callchain_param.mode = CHAIN_NONE;
2057 callchain = 0;
2059 return 0;
2062 else
2063 return -1;
2065 /* get the min percentage */
2066 tok = strtok(NULL, ",");
2067 if (!tok)
2068 goto setup;
2070 callchain_param.min_percent = strtod(tok, &endptr);
2071 if (tok == endptr)
2072 return -1;
2074 setup:
2075 if (register_callchain_param(&callchain_param) < 0) {
2076 fprintf(stderr, "Can't register callchain params\n");
2077 return -1;
2079 return 0;
2082 static const char * const report_usage[] = {
2083 "perf report [<options>] <command>",
2084 NULL
2087 static const struct option options[] = {
2088 OPT_STRING('i', "input", &input_name, "file",
2089 "input file name"),
2090 OPT_BOOLEAN('v', "verbose", &verbose,
2091 "be more verbose (show symbol address, etc)"),
2092 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
2093 "dump raw trace in ASCII"),
2094 OPT_STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"),
2095 OPT_BOOLEAN('m', "modules", &modules,
2096 "load module symbols - WARNING: use only with -k and LIVE kernel"),
2097 OPT_BOOLEAN('n', "show-nr-samples", &show_nr_samples,
2098 "Show a column with the number of samples"),
2099 OPT_BOOLEAN('T', "threads", &show_threads,
2100 "Show per-thread event counters"),
2101 OPT_STRING(0, "pretty", &pretty_printing_style, "key",
2102 "pretty printing style key: normal raw"),
2103 OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
2104 "sort by key(s): pid, comm, dso, symbol, parent"),
2105 OPT_BOOLEAN('P', "full-paths", &full_paths,
2106 "Don't shorten the pathnames taking into account the cwd"),
2107 OPT_STRING('p', "parent", &parent_pattern, "regex",
2108 "regex filter to identify parent, see: '--sort parent'"),
2109 OPT_BOOLEAN('x', "exclude-other", &exclude_other,
2110 "Only display entries with parent-match"),
2111 OPT_CALLBACK_DEFAULT('g', "call-graph", NULL, "output_type,min_percent",
2112 "Display callchains using output_type and min percent threshold. "
2113 "Default: fractal,0.5", &parse_callchain_opt, callchain_default_opt),
2114 OPT_STRING('d', "dsos", &dso_list_str, "dso[,dso...]",
2115 "only consider symbols in these dsos"),
2116 OPT_STRING('C', "comms", &comm_list_str, "comm[,comm...]",
2117 "only consider symbols in these comms"),
2118 OPT_STRING('S', "symbols", &sym_list_str, "symbol[,symbol...]",
2119 "only consider these symbols"),
2120 OPT_STRING('w', "column-widths", &col_width_list_str,
2121 "width[,width...]",
2122 "don't try to adjust column width, use these fixed values"),
2123 OPT_STRING('t', "field-separator", &field_sep, "separator",
2124 "separator for columns, no spaces will be added between "
2125 "columns '.' is reserved."),
2126 OPT_END()
2129 static void setup_sorting(void)
2131 char *tmp, *tok, *str = strdup(sort_order);
2133 for (tok = strtok_r(str, ", ", &tmp);
2134 tok; tok = strtok_r(NULL, ", ", &tmp)) {
2135 if (sort_dimension__add(tok) < 0) {
2136 error("Unknown --sort key: `%s'", tok);
2137 usage_with_options(report_usage, options);
2141 free(str);
2144 static void setup_list(struct strlist **list, const char *list_str,
2145 struct sort_entry *se, const char *list_name,
2146 FILE *fp)
2148 if (list_str) {
2149 *list = strlist__new(true, list_str);
2150 if (!*list) {
2151 fprintf(stderr, "problems parsing %s list\n",
2152 list_name);
2153 exit(129);
2155 if (strlist__nr_entries(*list) == 1) {
2156 fprintf(fp, "# %s: %s\n", list_name,
2157 strlist__entry(*list, 0)->s);
2158 se->elide = true;
2163 int cmd_report(int argc, const char **argv, const char *prefix __used)
2165 symbol__init();
2167 page_size = getpagesize();
2169 argc = parse_options(argc, argv, options, report_usage, 0);
2171 setup_sorting();
2173 if (parent_pattern != default_parent_pattern) {
2174 sort_dimension__add("parent");
2175 sort_parent.elide = 1;
2176 } else
2177 exclude_other = 0;
2180 * Any (unrecognized) arguments left?
2182 if (argc)
2183 usage_with_options(report_usage, options);
2185 setup_pager();
2187 setup_list(&dso_list, dso_list_str, &sort_dso, "dso", stdout);
2188 setup_list(&comm_list, comm_list_str, &sort_comm, "comm", stdout);
2189 setup_list(&sym_list, sym_list_str, &sort_sym, "symbol", stdout);
2191 if (field_sep && *field_sep == '.') {
2192 fputs("'.' is the only non valid --field-separator argument\n",
2193 stderr);
2194 exit(129);
2197 return __cmd_report();