xref: /linux/tools/perf/builtin-report.c (revision 2277ab4a1df50e05bc732fe9488d4e902bb8399a)
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 <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 
21 #include "perf.h"
22 #include "util/header.h"
23 
24 #include "util/parse-options.h"
25 #include "util/parse-events.h"
26 
27 #define SHOW_KERNEL	1
28 #define SHOW_USER	2
29 #define SHOW_HV		4
30 
31 static char		const *input_name = "perf.data";
32 static char		*vmlinux = NULL;
33 
34 static char		default_sort_order[] = "comm,dso";
35 static char		*sort_order = default_sort_order;
36 static char		*dso_list_str, *comm_list_str, *sym_list_str;
37 static struct strlist	*dso_list, *comm_list, *sym_list;
38 
39 static int		input;
40 static int		show_mask = SHOW_KERNEL | SHOW_USER | SHOW_HV;
41 
42 static int		dump_trace = 0;
43 #define dprintf(x...)	do { if (dump_trace) printf(x); } while (0)
44 #define cdprintf(x...)	do { if (dump_trace) color_fprintf(stdout, color, x); } while (0)
45 
46 static int		verbose;
47 #define eprintf(x...)	do { if (verbose) fprintf(stderr, x); } while (0)
48 
49 static int		modules;
50 
51 static int		full_paths;
52 
53 static unsigned long	page_size;
54 static unsigned long	mmap_window = 32;
55 
56 static char		default_parent_pattern[] = "^sys_|^do_page_fault";
57 static char		*parent_pattern = default_parent_pattern;
58 static regex_t		parent_regex;
59 
60 static int		exclude_other = 1;
61 
62 static char		callchain_default_opt[] = "fractal,0.5";
63 
64 static int		callchain;
65 
66 static
67 struct callchain_param	callchain_param = {
68 	.mode	= CHAIN_GRAPH_ABS,
69 	.min_percent = 0.5
70 };
71 
72 static u64		sample_type;
73 
74 struct ip_event {
75 	struct perf_event_header header;
76 	u64 ip;
77 	u32 pid, tid;
78 	unsigned char __more_data[];
79 };
80 
81 struct mmap_event {
82 	struct perf_event_header header;
83 	u32 pid, tid;
84 	u64 start;
85 	u64 len;
86 	u64 pgoff;
87 	char filename[PATH_MAX];
88 };
89 
90 struct comm_event {
91 	struct perf_event_header header;
92 	u32 pid, tid;
93 	char comm[16];
94 };
95 
96 struct fork_event {
97 	struct perf_event_header header;
98 	u32 pid, ppid;
99 };
100 
101 struct period_event {
102 	struct perf_event_header header;
103 	u64 time;
104 	u64 id;
105 	u64 sample_period;
106 };
107 
108 struct lost_event {
109 	struct perf_event_header header;
110 	u64 id;
111 	u64 lost;
112 };
113 
114 struct read_event {
115 	struct perf_event_header header;
116 	u32 pid,tid;
117 	u64 value;
118 	u64 format[3];
119 };
120 
121 typedef union event_union {
122 	struct perf_event_header	header;
123 	struct ip_event			ip;
124 	struct mmap_event		mmap;
125 	struct comm_event		comm;
126 	struct fork_event		fork;
127 	struct period_event		period;
128 	struct lost_event		lost;
129 	struct read_event		read;
130 } event_t;
131 
132 static LIST_HEAD(dsos);
133 static struct dso *kernel_dso;
134 static struct dso *vdso;
135 static struct dso *hypervisor_dso;
136 
137 static void dsos__add(struct dso *dso)
138 {
139 	list_add_tail(&dso->node, &dsos);
140 }
141 
142 static struct dso *dsos__find(const char *name)
143 {
144 	struct dso *pos;
145 
146 	list_for_each_entry(pos, &dsos, node)
147 		if (strcmp(pos->name, name) == 0)
148 			return pos;
149 	return NULL;
150 }
151 
152 static struct dso *dsos__findnew(const char *name)
153 {
154 	struct dso *dso = dsos__find(name);
155 	int nr;
156 
157 	if (dso)
158 		return dso;
159 
160 	dso = dso__new(name, 0);
161 	if (!dso)
162 		goto out_delete_dso;
163 
164 	nr = dso__load(dso, NULL, verbose);
165 	if (nr < 0) {
166 		eprintf("Failed to open: %s\n", name);
167 		goto out_delete_dso;
168 	}
169 	if (!nr)
170 		eprintf("No symbols found in: %s, maybe install a debug package?\n", name);
171 
172 	dsos__add(dso);
173 
174 	return dso;
175 
176 out_delete_dso:
177 	dso__delete(dso);
178 	return NULL;
179 }
180 
181 static void dsos__fprintf(FILE *fp)
182 {
183 	struct dso *pos;
184 
185 	list_for_each_entry(pos, &dsos, node)
186 		dso__fprintf(pos, fp);
187 }
188 
189 static struct symbol *vdso__find_symbol(struct dso *dso, u64 ip)
190 {
191 	return dso__find_symbol(dso, ip);
192 }
193 
194 static int load_kernel(void)
195 {
196 	int err;
197 
198 	kernel_dso = dso__new("[kernel]", 0);
199 	if (!kernel_dso)
200 		return -1;
201 
202 	err = dso__load_kernel(kernel_dso, vmlinux, NULL, verbose, modules);
203 	if (err <= 0) {
204 		dso__delete(kernel_dso);
205 		kernel_dso = NULL;
206 	} else
207 		dsos__add(kernel_dso);
208 
209 	vdso = dso__new("[vdso]", 0);
210 	if (!vdso)
211 		return -1;
212 
213 	vdso->find_symbol = vdso__find_symbol;
214 
215 	dsos__add(vdso);
216 
217 	hypervisor_dso = dso__new("[hypervisor]", 0);
218 	if (!hypervisor_dso)
219 		return -1;
220 	dsos__add(hypervisor_dso);
221 
222 	return err;
223 }
224 
225 static char __cwd[PATH_MAX];
226 static char *cwd = __cwd;
227 static int cwdlen;
228 
229 static int strcommon(const char *pathname)
230 {
231 	int n = 0;
232 
233 	while (pathname[n] == cwd[n] && n < cwdlen)
234 		++n;
235 
236 	return n;
237 }
238 
239 struct map {
240 	struct list_head node;
241 	u64	 start;
242 	u64	 end;
243 	u64	 pgoff;
244 	u64	 (*map_ip)(struct map *, u64);
245 	struct dso	 *dso;
246 };
247 
248 static u64 map__map_ip(struct map *map, u64 ip)
249 {
250 	return ip - map->start + map->pgoff;
251 }
252 
253 static u64 vdso__map_ip(struct map *map __used, u64 ip)
254 {
255 	return ip;
256 }
257 
258 static inline int is_anon_memory(const char *filename)
259 {
260 	return strcmp(filename, "//anon") == 0;
261 }
262 
263 static struct map *map__new(struct mmap_event *event)
264 {
265 	struct map *self = malloc(sizeof(*self));
266 
267 	if (self != NULL) {
268 		const char *filename = event->filename;
269 		char newfilename[PATH_MAX];
270 		int anon;
271 
272 		if (cwd) {
273 			int n = strcommon(filename);
274 
275 			if (n == cwdlen) {
276 				snprintf(newfilename, sizeof(newfilename),
277 					 ".%s", filename + n);
278 				filename = newfilename;
279 			}
280 		}
281 
282 		anon = is_anon_memory(filename);
283 
284 		if (anon) {
285 			snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", event->pid);
286 			filename = newfilename;
287 		}
288 
289 		self->start = event->start;
290 		self->end   = event->start + event->len;
291 		self->pgoff = event->pgoff;
292 
293 		self->dso = dsos__findnew(filename);
294 		if (self->dso == NULL)
295 			goto out_delete;
296 
297 		if (self->dso == vdso || anon)
298 			self->map_ip = vdso__map_ip;
299 		else
300 			self->map_ip = map__map_ip;
301 	}
302 	return self;
303 out_delete:
304 	free(self);
305 	return NULL;
306 }
307 
308 static struct map *map__clone(struct map *self)
309 {
310 	struct map *map = malloc(sizeof(*self));
311 
312 	if (!map)
313 		return NULL;
314 
315 	memcpy(map, self, sizeof(*self));
316 
317 	return map;
318 }
319 
320 static int map__overlap(struct map *l, struct map *r)
321 {
322 	if (l->start > r->start) {
323 		struct map *t = l;
324 		l = r;
325 		r = t;
326 	}
327 
328 	if (l->end > r->start)
329 		return 1;
330 
331 	return 0;
332 }
333 
334 static size_t map__fprintf(struct map *self, FILE *fp)
335 {
336 	return fprintf(fp, " %Lx-%Lx %Lx %s\n",
337 		       self->start, self->end, self->pgoff, self->dso->name);
338 }
339 
340 
341 struct thread {
342 	struct rb_node	 rb_node;
343 	struct list_head maps;
344 	pid_t		 pid;
345 	char		 *comm;
346 };
347 
348 static struct thread *thread__new(pid_t pid)
349 {
350 	struct thread *self = malloc(sizeof(*self));
351 
352 	if (self != NULL) {
353 		self->pid = pid;
354 		self->comm = malloc(32);
355 		if (self->comm)
356 			snprintf(self->comm, 32, ":%d", self->pid);
357 		INIT_LIST_HEAD(&self->maps);
358 	}
359 
360 	return self;
361 }
362 
363 static int thread__set_comm(struct thread *self, const char *comm)
364 {
365 	if (self->comm)
366 		free(self->comm);
367 	self->comm = strdup(comm);
368 	return self->comm ? 0 : -ENOMEM;
369 }
370 
371 static size_t thread__fprintf(struct thread *self, FILE *fp)
372 {
373 	struct map *pos;
374 	size_t ret = fprintf(fp, "Thread %d %s\n", self->pid, self->comm);
375 
376 	list_for_each_entry(pos, &self->maps, node)
377 		ret += map__fprintf(pos, fp);
378 
379 	return ret;
380 }
381 
382 
383 static struct rb_root threads;
384 static struct thread *last_match;
385 
386 static struct thread *threads__findnew(pid_t pid)
387 {
388 	struct rb_node **p = &threads.rb_node;
389 	struct rb_node *parent = NULL;
390 	struct thread *th;
391 
392 	/*
393 	 * Font-end cache - PID lookups come in blocks,
394 	 * so most of the time we dont have to look up
395 	 * the full rbtree:
396 	 */
397 	if (last_match && last_match->pid == pid)
398 		return last_match;
399 
400 	while (*p != NULL) {
401 		parent = *p;
402 		th = rb_entry(parent, struct thread, rb_node);
403 
404 		if (th->pid == pid) {
405 			last_match = th;
406 			return th;
407 		}
408 
409 		if (pid < th->pid)
410 			p = &(*p)->rb_left;
411 		else
412 			p = &(*p)->rb_right;
413 	}
414 
415 	th = thread__new(pid);
416 	if (th != NULL) {
417 		rb_link_node(&th->rb_node, parent, p);
418 		rb_insert_color(&th->rb_node, &threads);
419 		last_match = th;
420 	}
421 
422 	return th;
423 }
424 
425 static void thread__insert_map(struct thread *self, struct map *map)
426 {
427 	struct map *pos, *tmp;
428 
429 	list_for_each_entry_safe(pos, tmp, &self->maps, node) {
430 		if (map__overlap(pos, map)) {
431 			if (verbose >= 2) {
432 				printf("overlapping maps:\n");
433 				map__fprintf(map, stdout);
434 				map__fprintf(pos, stdout);
435 			}
436 
437 			if (map->start <= pos->start && map->end > pos->start)
438 				pos->start = map->end;
439 
440 			if (map->end >= pos->end && map->start < pos->end)
441 				pos->end = map->start;
442 
443 			if (verbose >= 2) {
444 				printf("after collision:\n");
445 				map__fprintf(pos, stdout);
446 			}
447 
448 			if (pos->start >= pos->end) {
449 				list_del_init(&pos->node);
450 				free(pos);
451 			}
452 		}
453 	}
454 
455 	list_add_tail(&map->node, &self->maps);
456 }
457 
458 static int thread__fork(struct thread *self, struct thread *parent)
459 {
460 	struct map *map;
461 
462 	if (self->comm)
463 		free(self->comm);
464 	self->comm = strdup(parent->comm);
465 	if (!self->comm)
466 		return -ENOMEM;
467 
468 	list_for_each_entry(map, &parent->maps, node) {
469 		struct map *new = map__clone(map);
470 		if (!new)
471 			return -ENOMEM;
472 		thread__insert_map(self, new);
473 	}
474 
475 	return 0;
476 }
477 
478 static struct map *thread__find_map(struct thread *self, u64 ip)
479 {
480 	struct map *pos;
481 
482 	if (self == NULL)
483 		return NULL;
484 
485 	list_for_each_entry(pos, &self->maps, node)
486 		if (ip >= pos->start && ip <= pos->end)
487 			return pos;
488 
489 	return NULL;
490 }
491 
492 static size_t threads__fprintf(FILE *fp)
493 {
494 	size_t ret = 0;
495 	struct rb_node *nd;
496 
497 	for (nd = rb_first(&threads); nd; nd = rb_next(nd)) {
498 		struct thread *pos = rb_entry(nd, struct thread, rb_node);
499 
500 		ret += thread__fprintf(pos, fp);
501 	}
502 
503 	return ret;
504 }
505 
506 /*
507  * histogram, sorted on item, collects counts
508  */
509 
510 static struct rb_root hist;
511 
512 struct hist_entry {
513 	struct rb_node		rb_node;
514 
515 	struct thread		*thread;
516 	struct map		*map;
517 	struct dso		*dso;
518 	struct symbol		*sym;
519 	struct symbol		*parent;
520 	u64			ip;
521 	char			level;
522 	struct callchain_node	callchain;
523 	struct rb_root		sorted_chain;
524 
525 	u64			count;
526 };
527 
528 /*
529  * configurable sorting bits
530  */
531 
532 struct sort_entry {
533 	struct list_head list;
534 
535 	char *header;
536 
537 	int64_t (*cmp)(struct hist_entry *, struct hist_entry *);
538 	int64_t (*collapse)(struct hist_entry *, struct hist_entry *);
539 	size_t	(*print)(FILE *fp, struct hist_entry *);
540 };
541 
542 static int64_t cmp_null(void *l, void *r)
543 {
544 	if (!l && !r)
545 		return 0;
546 	else if (!l)
547 		return -1;
548 	else
549 		return 1;
550 }
551 
552 /* --sort pid */
553 
554 static int64_t
555 sort__thread_cmp(struct hist_entry *left, struct hist_entry *right)
556 {
557 	return right->thread->pid - left->thread->pid;
558 }
559 
560 static size_t
561 sort__thread_print(FILE *fp, struct hist_entry *self)
562 {
563 	return fprintf(fp, "%16s:%5d", self->thread->comm ?: "", self->thread->pid);
564 }
565 
566 static struct sort_entry sort_thread = {
567 	.header = "         Command:  Pid",
568 	.cmp	= sort__thread_cmp,
569 	.print	= sort__thread_print,
570 };
571 
572 /* --sort comm */
573 
574 static int64_t
575 sort__comm_cmp(struct hist_entry *left, struct hist_entry *right)
576 {
577 	return right->thread->pid - left->thread->pid;
578 }
579 
580 static int64_t
581 sort__comm_collapse(struct hist_entry *left, struct hist_entry *right)
582 {
583 	char *comm_l = left->thread->comm;
584 	char *comm_r = right->thread->comm;
585 
586 	if (!comm_l || !comm_r)
587 		return cmp_null(comm_l, comm_r);
588 
589 	return strcmp(comm_l, comm_r);
590 }
591 
592 static size_t
593 sort__comm_print(FILE *fp, struct hist_entry *self)
594 {
595 	return fprintf(fp, "%16s", self->thread->comm);
596 }
597 
598 static struct sort_entry sort_comm = {
599 	.header		= "         Command",
600 	.cmp		= sort__comm_cmp,
601 	.collapse	= sort__comm_collapse,
602 	.print		= sort__comm_print,
603 };
604 
605 /* --sort dso */
606 
607 static int64_t
608 sort__dso_cmp(struct hist_entry *left, struct hist_entry *right)
609 {
610 	struct dso *dso_l = left->dso;
611 	struct dso *dso_r = right->dso;
612 
613 	if (!dso_l || !dso_r)
614 		return cmp_null(dso_l, dso_r);
615 
616 	return strcmp(dso_l->name, dso_r->name);
617 }
618 
619 static size_t
620 sort__dso_print(FILE *fp, struct hist_entry *self)
621 {
622 	if (self->dso)
623 		return fprintf(fp, "%-25s", self->dso->name);
624 
625 	return fprintf(fp, "%016llx         ", (u64)self->ip);
626 }
627 
628 static struct sort_entry sort_dso = {
629 	.header = "Shared Object            ",
630 	.cmp	= sort__dso_cmp,
631 	.print	= sort__dso_print,
632 };
633 
634 /* --sort symbol */
635 
636 static int64_t
637 sort__sym_cmp(struct hist_entry *left, struct hist_entry *right)
638 {
639 	u64 ip_l, ip_r;
640 
641 	if (left->sym == right->sym)
642 		return 0;
643 
644 	ip_l = left->sym ? left->sym->start : left->ip;
645 	ip_r = right->sym ? right->sym->start : right->ip;
646 
647 	return (int64_t)(ip_r - ip_l);
648 }
649 
650 static size_t
651 sort__sym_print(FILE *fp, struct hist_entry *self)
652 {
653 	size_t ret = 0;
654 
655 	if (verbose)
656 		ret += fprintf(fp, "%#018llx  ", (u64)self->ip);
657 
658 	if (self->sym) {
659 		ret += fprintf(fp, "[%c] %s",
660 			self->dso == kernel_dso ? 'k' :
661 			self->dso == hypervisor_dso ? 'h' : '.', self->sym->name);
662 
663 		if (self->sym->module)
664 			ret += fprintf(fp, "\t[%s]", self->sym->module->name);
665 	} else {
666 		ret += fprintf(fp, "%#016llx", (u64)self->ip);
667 	}
668 
669 	return ret;
670 }
671 
672 static struct sort_entry sort_sym = {
673 	.header = "Symbol",
674 	.cmp	= sort__sym_cmp,
675 	.print	= sort__sym_print,
676 };
677 
678 /* --sort parent */
679 
680 static int64_t
681 sort__parent_cmp(struct hist_entry *left, struct hist_entry *right)
682 {
683 	struct symbol *sym_l = left->parent;
684 	struct symbol *sym_r = right->parent;
685 
686 	if (!sym_l || !sym_r)
687 		return cmp_null(sym_l, sym_r);
688 
689 	return strcmp(sym_l->name, sym_r->name);
690 }
691 
692 static size_t
693 sort__parent_print(FILE *fp, struct hist_entry *self)
694 {
695 	size_t ret = 0;
696 
697 	ret += fprintf(fp, "%-20s", self->parent ? self->parent->name : "[other]");
698 
699 	return ret;
700 }
701 
702 static struct sort_entry sort_parent = {
703 	.header = "Parent symbol       ",
704 	.cmp	= sort__parent_cmp,
705 	.print	= sort__parent_print,
706 };
707 
708 static int sort__need_collapse = 0;
709 static int sort__has_parent = 0;
710 
711 struct sort_dimension {
712 	char			*name;
713 	struct sort_entry	*entry;
714 	int			taken;
715 };
716 
717 static struct sort_dimension sort_dimensions[] = {
718 	{ .name = "pid",	.entry = &sort_thread,	},
719 	{ .name = "comm",	.entry = &sort_comm,	},
720 	{ .name = "dso",	.entry = &sort_dso,	},
721 	{ .name = "symbol",	.entry = &sort_sym,	},
722 	{ .name = "parent",	.entry = &sort_parent,	},
723 };
724 
725 static LIST_HEAD(hist_entry__sort_list);
726 
727 static int sort_dimension__add(char *tok)
728 {
729 	unsigned int i;
730 
731 	for (i = 0; i < ARRAY_SIZE(sort_dimensions); i++) {
732 		struct sort_dimension *sd = &sort_dimensions[i];
733 
734 		if (sd->taken)
735 			continue;
736 
737 		if (strncasecmp(tok, sd->name, strlen(tok)))
738 			continue;
739 
740 		if (sd->entry->collapse)
741 			sort__need_collapse = 1;
742 
743 		if (sd->entry == &sort_parent) {
744 			int ret = regcomp(&parent_regex, parent_pattern, REG_EXTENDED);
745 			if (ret) {
746 				char err[BUFSIZ];
747 
748 				regerror(ret, &parent_regex, err, sizeof(err));
749 				fprintf(stderr, "Invalid regex: %s\n%s",
750 					parent_pattern, err);
751 				exit(-1);
752 			}
753 			sort__has_parent = 1;
754 		}
755 
756 		list_add_tail(&sd->entry->list, &hist_entry__sort_list);
757 		sd->taken = 1;
758 
759 		return 0;
760 	}
761 
762 	return -ESRCH;
763 }
764 
765 static int64_t
766 hist_entry__cmp(struct hist_entry *left, struct hist_entry *right)
767 {
768 	struct sort_entry *se;
769 	int64_t cmp = 0;
770 
771 	list_for_each_entry(se, &hist_entry__sort_list, list) {
772 		cmp = se->cmp(left, right);
773 		if (cmp)
774 			break;
775 	}
776 
777 	return cmp;
778 }
779 
780 static int64_t
781 hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
782 {
783 	struct sort_entry *se;
784 	int64_t cmp = 0;
785 
786 	list_for_each_entry(se, &hist_entry__sort_list, list) {
787 		int64_t (*f)(struct hist_entry *, struct hist_entry *);
788 
789 		f = se->collapse ?: se->cmp;
790 
791 		cmp = f(left, right);
792 		if (cmp)
793 			break;
794 	}
795 
796 	return cmp;
797 }
798 
799 static size_t ipchain__fprintf_graph_line(FILE *fp, int depth, int depth_mask)
800 {
801 	int i;
802 	size_t ret = 0;
803 
804 	ret += fprintf(fp, "%s", "                ");
805 
806 	for (i = 0; i < depth; i++)
807 		if (depth_mask & (1 << i))
808 			ret += fprintf(fp, "|          ");
809 		else
810 			ret += fprintf(fp, "           ");
811 
812 	ret += fprintf(fp, "\n");
813 
814 	return ret;
815 }
816 static size_t
817 ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain, int depth,
818 		       int depth_mask, int count, u64 total_samples,
819 		       int hits)
820 {
821 	int i;
822 	size_t ret = 0;
823 
824 	ret += fprintf(fp, "%s", "                ");
825 	for (i = 0; i < depth; i++) {
826 		if (depth_mask & (1 << i))
827 			ret += fprintf(fp, "|");
828 		else
829 			ret += fprintf(fp, " ");
830 		if (!count && i == depth - 1) {
831 			double percent;
832 
833 			percent = hits * 100.0 / total_samples;
834 			ret += percent_color_fprintf(fp, "--%2.2f%%-- ", percent);
835 		} else
836 			ret += fprintf(fp, "%s", "          ");
837 	}
838 	if (chain->sym)
839 		ret += fprintf(fp, "%s\n", chain->sym->name);
840 	else
841 		ret += fprintf(fp, "%p\n", (void *)(long)chain->ip);
842 
843 	return ret;
844 }
845 
846 static size_t
847 callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
848 			u64 total_samples, int depth, int depth_mask)
849 {
850 	struct rb_node *node, *next;
851 	struct callchain_node *child;
852 	struct callchain_list *chain;
853 	int new_depth_mask = depth_mask;
854 	u64 new_total;
855 	size_t ret = 0;
856 	int i;
857 
858 	if (callchain_param.mode == CHAIN_GRAPH_REL)
859 		new_total = self->cumul_hit;
860 	else
861 		new_total = total_samples;
862 
863 	node = rb_first(&self->rb_root);
864 	while (node) {
865 		child = rb_entry(node, struct callchain_node, rb_node);
866 
867 		/*
868 		 * The depth mask manages the output of pipes that show
869 		 * the depth. We don't want to keep the pipes of the current
870 		 * level for the last child of this depth
871 		 */
872 		next = rb_next(node);
873 		if (!next)
874 			new_depth_mask &= ~(1 << (depth - 1));
875 
876 		/*
877 		 * But we keep the older depth mask for the line seperator
878 		 * to keep the level link until we reach the last child
879 		 */
880 		ret += ipchain__fprintf_graph_line(fp, depth, depth_mask);
881 		i = 0;
882 		list_for_each_entry(chain, &child->val, list) {
883 			if (chain->ip >= PERF_CONTEXT_MAX)
884 				continue;
885 			ret += ipchain__fprintf_graph(fp, chain, depth,
886 						      new_depth_mask, i++,
887 						      new_total,
888 						      child->cumul_hit);
889 		}
890 		ret += callchain__fprintf_graph(fp, child, new_total,
891 						depth + 1,
892 						new_depth_mask | (1 << depth));
893 		node = next;
894 	}
895 
896 	return ret;
897 }
898 
899 static size_t
900 callchain__fprintf_flat(FILE *fp, struct callchain_node *self,
901 			u64 total_samples)
902 {
903 	struct callchain_list *chain;
904 	size_t ret = 0;
905 
906 	if (!self)
907 		return 0;
908 
909 	ret += callchain__fprintf_flat(fp, self->parent, total_samples);
910 
911 
912 	list_for_each_entry(chain, &self->val, list) {
913 		if (chain->ip >= PERF_CONTEXT_MAX)
914 			continue;
915 		if (chain->sym)
916 			ret += fprintf(fp, "                %s\n", chain->sym->name);
917 		else
918 			ret += fprintf(fp, "                %p\n",
919 					(void *)(long)chain->ip);
920 	}
921 
922 	return ret;
923 }
924 
925 static size_t
926 hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self,
927 			      u64 total_samples)
928 {
929 	struct rb_node *rb_node;
930 	struct callchain_node *chain;
931 	size_t ret = 0;
932 
933 	rb_node = rb_first(&self->sorted_chain);
934 	while (rb_node) {
935 		double percent;
936 
937 		chain = rb_entry(rb_node, struct callchain_node, rb_node);
938 		percent = chain->hit * 100.0 / total_samples;
939 		switch (callchain_param.mode) {
940 		case CHAIN_FLAT:
941 			ret += percent_color_fprintf(fp, "           %6.2f%%\n",
942 						     percent);
943 			ret += callchain__fprintf_flat(fp, chain, total_samples);
944 			break;
945 		case CHAIN_GRAPH_ABS: /* Falldown */
946 		case CHAIN_GRAPH_REL:
947 			ret += callchain__fprintf_graph(fp, chain,
948 							total_samples, 1, 1);
949 		default:
950 			break;
951 		}
952 		ret += fprintf(fp, "\n");
953 		rb_node = rb_next(rb_node);
954 	}
955 
956 	return ret;
957 }
958 
959 
960 static size_t
961 hist_entry__fprintf(FILE *fp, struct hist_entry *self, u64 total_samples)
962 {
963 	struct sort_entry *se;
964 	size_t ret;
965 
966 	if (exclude_other && !self->parent)
967 		return 0;
968 
969 	if (total_samples)
970 		ret = percent_color_fprintf(fp, "   %6.2f%%",
971 				(self->count * 100.0) / total_samples);
972 	else
973 		ret = fprintf(fp, "%12Ld ", self->count);
974 
975 	list_for_each_entry(se, &hist_entry__sort_list, list) {
976 		if (exclude_other && (se == &sort_parent))
977 			continue;
978 
979 		fprintf(fp, "  ");
980 		ret += se->print(fp, self);
981 	}
982 
983 	ret += fprintf(fp, "\n");
984 
985 	if (callchain)
986 		hist_entry_callchain__fprintf(fp, self, total_samples);
987 
988 	return ret;
989 }
990 
991 /*
992  *
993  */
994 
995 static struct symbol *
996 resolve_symbol(struct thread *thread, struct map **mapp,
997 	       struct dso **dsop, u64 *ipp)
998 {
999 	struct dso *dso = dsop ? *dsop : NULL;
1000 	struct map *map = mapp ? *mapp : NULL;
1001 	u64 ip = *ipp;
1002 
1003 	if (!thread)
1004 		return NULL;
1005 
1006 	if (dso)
1007 		goto got_dso;
1008 
1009 	if (map)
1010 		goto got_map;
1011 
1012 	map = thread__find_map(thread, ip);
1013 	if (map != NULL) {
1014 		if (mapp)
1015 			*mapp = map;
1016 got_map:
1017 		ip = map->map_ip(map, ip);
1018 
1019 		dso = map->dso;
1020 	} else {
1021 		/*
1022 		 * If this is outside of all known maps,
1023 		 * and is a negative address, try to look it
1024 		 * up in the kernel dso, as it might be a
1025 		 * vsyscall (which executes in user-mode):
1026 		 */
1027 		if ((long long)ip < 0)
1028 		dso = kernel_dso;
1029 	}
1030 	dprintf(" ...... dso: %s\n", dso ? dso->name : "<not found>");
1031 	dprintf(" ...... map: %Lx -> %Lx\n", *ipp, ip);
1032 	*ipp  = ip;
1033 
1034 	if (dsop)
1035 		*dsop = dso;
1036 
1037 	if (!dso)
1038 		return NULL;
1039 got_dso:
1040 	return dso->find_symbol(dso, ip);
1041 }
1042 
1043 static int call__match(struct symbol *sym)
1044 {
1045 	if (sym->name && !regexec(&parent_regex, sym->name, 0, NULL, 0))
1046 		return 1;
1047 
1048 	return 0;
1049 }
1050 
1051 static struct symbol **
1052 resolve_callchain(struct thread *thread, struct map *map __used,
1053 		    struct ip_callchain *chain, struct hist_entry *entry)
1054 {
1055 	u64 context = PERF_CONTEXT_MAX;
1056 	struct symbol **syms = NULL;
1057 	unsigned int i;
1058 
1059 	if (callchain) {
1060 		syms = calloc(chain->nr, sizeof(*syms));
1061 		if (!syms) {
1062 			fprintf(stderr, "Can't allocate memory for symbols\n");
1063 			exit(-1);
1064 		}
1065 	}
1066 
1067 	for (i = 0; i < chain->nr; i++) {
1068 		u64 ip = chain->ips[i];
1069 		struct dso *dso = NULL;
1070 		struct symbol *sym;
1071 
1072 		if (ip >= PERF_CONTEXT_MAX) {
1073 			context = ip;
1074 			continue;
1075 		}
1076 
1077 		switch (context) {
1078 		case PERF_CONTEXT_HV:
1079 			dso = hypervisor_dso;
1080 			break;
1081 		case PERF_CONTEXT_KERNEL:
1082 			dso = kernel_dso;
1083 			break;
1084 		default:
1085 			break;
1086 		}
1087 
1088 		sym = resolve_symbol(thread, NULL, &dso, &ip);
1089 
1090 		if (sym) {
1091 			if (sort__has_parent && call__match(sym) &&
1092 			    !entry->parent)
1093 				entry->parent = sym;
1094 			if (!callchain)
1095 				break;
1096 			syms[i] = sym;
1097 		}
1098 	}
1099 
1100 	return syms;
1101 }
1102 
1103 /*
1104  * collect histogram counts
1105  */
1106 
1107 static int
1108 hist_entry__add(struct thread *thread, struct map *map, struct dso *dso,
1109 		struct symbol *sym, u64 ip, struct ip_callchain *chain,
1110 		char level, u64 count)
1111 {
1112 	struct rb_node **p = &hist.rb_node;
1113 	struct rb_node *parent = NULL;
1114 	struct hist_entry *he;
1115 	struct symbol **syms = NULL;
1116 	struct hist_entry entry = {
1117 		.thread	= thread,
1118 		.map	= map,
1119 		.dso	= dso,
1120 		.sym	= sym,
1121 		.ip	= ip,
1122 		.level	= level,
1123 		.count	= count,
1124 		.parent = NULL,
1125 		.sorted_chain = RB_ROOT
1126 	};
1127 	int cmp;
1128 
1129 	if ((sort__has_parent || callchain) && chain)
1130 		syms = resolve_callchain(thread, map, chain, &entry);
1131 
1132 	while (*p != NULL) {
1133 		parent = *p;
1134 		he = rb_entry(parent, struct hist_entry, rb_node);
1135 
1136 		cmp = hist_entry__cmp(&entry, he);
1137 
1138 		if (!cmp) {
1139 			he->count += count;
1140 			if (callchain) {
1141 				append_chain(&he->callchain, chain, syms);
1142 				free(syms);
1143 			}
1144 			return 0;
1145 		}
1146 
1147 		if (cmp < 0)
1148 			p = &(*p)->rb_left;
1149 		else
1150 			p = &(*p)->rb_right;
1151 	}
1152 
1153 	he = malloc(sizeof(*he));
1154 	if (!he)
1155 		return -ENOMEM;
1156 	*he = entry;
1157 	if (callchain) {
1158 		callchain_init(&he->callchain);
1159 		append_chain(&he->callchain, chain, syms);
1160 		free(syms);
1161 	}
1162 	rb_link_node(&he->rb_node, parent, p);
1163 	rb_insert_color(&he->rb_node, &hist);
1164 
1165 	return 0;
1166 }
1167 
1168 static void hist_entry__free(struct hist_entry *he)
1169 {
1170 	free(he);
1171 }
1172 
1173 /*
1174  * collapse the histogram
1175  */
1176 
1177 static struct rb_root collapse_hists;
1178 
1179 static void collapse__insert_entry(struct hist_entry *he)
1180 {
1181 	struct rb_node **p = &collapse_hists.rb_node;
1182 	struct rb_node *parent = NULL;
1183 	struct hist_entry *iter;
1184 	int64_t cmp;
1185 
1186 	while (*p != NULL) {
1187 		parent = *p;
1188 		iter = rb_entry(parent, struct hist_entry, rb_node);
1189 
1190 		cmp = hist_entry__collapse(iter, he);
1191 
1192 		if (!cmp) {
1193 			iter->count += he->count;
1194 			hist_entry__free(he);
1195 			return;
1196 		}
1197 
1198 		if (cmp < 0)
1199 			p = &(*p)->rb_left;
1200 		else
1201 			p = &(*p)->rb_right;
1202 	}
1203 
1204 	rb_link_node(&he->rb_node, parent, p);
1205 	rb_insert_color(&he->rb_node, &collapse_hists);
1206 }
1207 
1208 static void collapse__resort(void)
1209 {
1210 	struct rb_node *next;
1211 	struct hist_entry *n;
1212 
1213 	if (!sort__need_collapse)
1214 		return;
1215 
1216 	next = rb_first(&hist);
1217 	while (next) {
1218 		n = rb_entry(next, struct hist_entry, rb_node);
1219 		next = rb_next(&n->rb_node);
1220 
1221 		rb_erase(&n->rb_node, &hist);
1222 		collapse__insert_entry(n);
1223 	}
1224 }
1225 
1226 /*
1227  * reverse the map, sort on count.
1228  */
1229 
1230 static struct rb_root output_hists;
1231 
1232 static void output__insert_entry(struct hist_entry *he, u64 min_callchain_hits)
1233 {
1234 	struct rb_node **p = &output_hists.rb_node;
1235 	struct rb_node *parent = NULL;
1236 	struct hist_entry *iter;
1237 
1238 	if (callchain)
1239 		callchain_param.sort(&he->sorted_chain, &he->callchain,
1240 				      min_callchain_hits, &callchain_param);
1241 
1242 	while (*p != NULL) {
1243 		parent = *p;
1244 		iter = rb_entry(parent, struct hist_entry, rb_node);
1245 
1246 		if (he->count > iter->count)
1247 			p = &(*p)->rb_left;
1248 		else
1249 			p = &(*p)->rb_right;
1250 	}
1251 
1252 	rb_link_node(&he->rb_node, parent, p);
1253 	rb_insert_color(&he->rb_node, &output_hists);
1254 }
1255 
1256 static void output__resort(u64 total_samples)
1257 {
1258 	struct rb_node *next;
1259 	struct hist_entry *n;
1260 	struct rb_root *tree = &hist;
1261 	u64 min_callchain_hits;
1262 
1263 	min_callchain_hits = total_samples * (callchain_param.min_percent / 100);
1264 
1265 	if (sort__need_collapse)
1266 		tree = &collapse_hists;
1267 
1268 	next = rb_first(tree);
1269 
1270 	while (next) {
1271 		n = rb_entry(next, struct hist_entry, rb_node);
1272 		next = rb_next(&n->rb_node);
1273 
1274 		rb_erase(&n->rb_node, tree);
1275 		output__insert_entry(n, min_callchain_hits);
1276 	}
1277 }
1278 
1279 static size_t output__fprintf(FILE *fp, u64 total_samples)
1280 {
1281 	struct hist_entry *pos;
1282 	struct sort_entry *se;
1283 	struct rb_node *nd;
1284 	size_t ret = 0;
1285 
1286 	fprintf(fp, "\n");
1287 	fprintf(fp, "#\n");
1288 	fprintf(fp, "# (%Ld samples)\n", (u64)total_samples);
1289 	fprintf(fp, "#\n");
1290 
1291 	fprintf(fp, "# Overhead");
1292 	list_for_each_entry(se, &hist_entry__sort_list, list) {
1293 		if (exclude_other && (se == &sort_parent))
1294 			continue;
1295 		fprintf(fp, "  %s", se->header);
1296 	}
1297 	fprintf(fp, "\n");
1298 
1299 	fprintf(fp, "# ........");
1300 	list_for_each_entry(se, &hist_entry__sort_list, list) {
1301 		unsigned int i;
1302 
1303 		if (exclude_other && (se == &sort_parent))
1304 			continue;
1305 
1306 		fprintf(fp, "  ");
1307 		for (i = 0; i < strlen(se->header); i++)
1308 			fprintf(fp, ".");
1309 	}
1310 	fprintf(fp, "\n");
1311 
1312 	fprintf(fp, "#\n");
1313 
1314 	for (nd = rb_first(&output_hists); nd; nd = rb_next(nd)) {
1315 		pos = rb_entry(nd, struct hist_entry, rb_node);
1316 		ret += hist_entry__fprintf(fp, pos, total_samples);
1317 	}
1318 
1319 	if (sort_order == default_sort_order &&
1320 			parent_pattern == default_parent_pattern) {
1321 		fprintf(fp, "#\n");
1322 		fprintf(fp, "# (For more details, try: perf report --sort comm,dso,symbol)\n");
1323 		fprintf(fp, "#\n");
1324 	}
1325 	fprintf(fp, "\n");
1326 
1327 	return ret;
1328 }
1329 
1330 static void register_idle_thread(void)
1331 {
1332 	struct thread *thread = threads__findnew(0);
1333 
1334 	if (thread == NULL ||
1335 			thread__set_comm(thread, "[idle]")) {
1336 		fprintf(stderr, "problem inserting idle task.\n");
1337 		exit(-1);
1338 	}
1339 }
1340 
1341 static unsigned long total = 0,
1342 		     total_mmap = 0,
1343 		     total_comm = 0,
1344 		     total_fork = 0,
1345 		     total_unknown = 0,
1346 		     total_lost = 0;
1347 
1348 static int validate_chain(struct ip_callchain *chain, event_t *event)
1349 {
1350 	unsigned int chain_size;
1351 
1352 	chain_size = event->header.size;
1353 	chain_size -= (unsigned long)&event->ip.__more_data - (unsigned long)event;
1354 
1355 	if (chain->nr*sizeof(u64) > chain_size)
1356 		return -1;
1357 
1358 	return 0;
1359 }
1360 
1361 static int
1362 process_sample_event(event_t *event, unsigned long offset, unsigned long head)
1363 {
1364 	char level;
1365 	int show = 0;
1366 	struct dso *dso = NULL;
1367 	struct thread *thread = threads__findnew(event->ip.pid);
1368 	u64 ip = event->ip.ip;
1369 	u64 period = 1;
1370 	struct map *map = NULL;
1371 	void *more_data = event->ip.__more_data;
1372 	struct ip_callchain *chain = NULL;
1373 	int cpumode;
1374 
1375 	if (sample_type & PERF_SAMPLE_PERIOD) {
1376 		period = *(u64 *)more_data;
1377 		more_data += sizeof(u64);
1378 	}
1379 
1380 	dprintf("%p [%p]: PERF_EVENT_SAMPLE (IP, %d): %d: %p period: %Ld\n",
1381 		(void *)(offset + head),
1382 		(void *)(long)(event->header.size),
1383 		event->header.misc,
1384 		event->ip.pid,
1385 		(void *)(long)ip,
1386 		(long long)period);
1387 
1388 	if (sample_type & PERF_SAMPLE_CALLCHAIN) {
1389 		unsigned int i;
1390 
1391 		chain = (void *)more_data;
1392 
1393 		dprintf("... chain: nr:%Lu\n", chain->nr);
1394 
1395 		if (validate_chain(chain, event) < 0) {
1396 			eprintf("call-chain problem with event, skipping it.\n");
1397 			return 0;
1398 		}
1399 
1400 		if (dump_trace) {
1401 			for (i = 0; i < chain->nr; i++)
1402 				dprintf("..... %2d: %016Lx\n", i, chain->ips[i]);
1403 		}
1404 	}
1405 
1406 	dprintf(" ... thread: %s:%d\n", thread->comm, thread->pid);
1407 
1408 	if (thread == NULL) {
1409 		eprintf("problem processing %d event, skipping it.\n",
1410 			event->header.type);
1411 		return -1;
1412 	}
1413 
1414 	if (comm_list && !strlist__has_entry(comm_list, thread->comm))
1415 		return 0;
1416 
1417 	cpumode = event->header.misc & PERF_EVENT_MISC_CPUMODE_MASK;
1418 
1419 	if (cpumode == PERF_EVENT_MISC_KERNEL) {
1420 		show = SHOW_KERNEL;
1421 		level = 'k';
1422 
1423 		dso = kernel_dso;
1424 
1425 		dprintf(" ...... dso: %s\n", dso->name);
1426 
1427 	} else if (cpumode == PERF_EVENT_MISC_USER) {
1428 
1429 		show = SHOW_USER;
1430 		level = '.';
1431 
1432 	} else {
1433 		show = SHOW_HV;
1434 		level = 'H';
1435 
1436 		dso = hypervisor_dso;
1437 
1438 		dprintf(" ...... dso: [hypervisor]\n");
1439 	}
1440 
1441 	if (show & show_mask) {
1442 		struct symbol *sym = resolve_symbol(thread, &map, &dso, &ip);
1443 
1444 		if (dso_list && dso && dso->name && !strlist__has_entry(dso_list, dso->name))
1445 			return 0;
1446 
1447 		if (sym_list && sym && !strlist__has_entry(sym_list, sym->name))
1448 			return 0;
1449 
1450 		if (hist_entry__add(thread, map, dso, sym, ip, chain, level, period)) {
1451 			eprintf("problem incrementing symbol count, skipping event\n");
1452 			return -1;
1453 		}
1454 	}
1455 	total += period;
1456 
1457 	return 0;
1458 }
1459 
1460 static int
1461 process_mmap_event(event_t *event, unsigned long offset, unsigned long head)
1462 {
1463 	struct thread *thread = threads__findnew(event->mmap.pid);
1464 	struct map *map = map__new(&event->mmap);
1465 
1466 	dprintf("%p [%p]: PERF_EVENT_MMAP %d: [%p(%p) @ %p]: %s\n",
1467 		(void *)(offset + head),
1468 		(void *)(long)(event->header.size),
1469 		event->mmap.pid,
1470 		(void *)(long)event->mmap.start,
1471 		(void *)(long)event->mmap.len,
1472 		(void *)(long)event->mmap.pgoff,
1473 		event->mmap.filename);
1474 
1475 	if (thread == NULL || map == NULL) {
1476 		dprintf("problem processing PERF_EVENT_MMAP, skipping event.\n");
1477 		return 0;
1478 	}
1479 
1480 	thread__insert_map(thread, map);
1481 	total_mmap++;
1482 
1483 	return 0;
1484 }
1485 
1486 static int
1487 process_comm_event(event_t *event, unsigned long offset, unsigned long head)
1488 {
1489 	struct thread *thread = threads__findnew(event->comm.pid);
1490 
1491 	dprintf("%p [%p]: PERF_EVENT_COMM: %s:%d\n",
1492 		(void *)(offset + head),
1493 		(void *)(long)(event->header.size),
1494 		event->comm.comm, event->comm.pid);
1495 
1496 	if (thread == NULL ||
1497 	    thread__set_comm(thread, event->comm.comm)) {
1498 		dprintf("problem processing PERF_EVENT_COMM, skipping event.\n");
1499 		return -1;
1500 	}
1501 	total_comm++;
1502 
1503 	return 0;
1504 }
1505 
1506 static int
1507 process_fork_event(event_t *event, unsigned long offset, unsigned long head)
1508 {
1509 	struct thread *thread = threads__findnew(event->fork.pid);
1510 	struct thread *parent = threads__findnew(event->fork.ppid);
1511 
1512 	dprintf("%p [%p]: PERF_EVENT_FORK: %d:%d\n",
1513 		(void *)(offset + head),
1514 		(void *)(long)(event->header.size),
1515 		event->fork.pid, event->fork.ppid);
1516 
1517 	if (!thread || !parent || thread__fork(thread, parent)) {
1518 		dprintf("problem processing PERF_EVENT_FORK, skipping event.\n");
1519 		return -1;
1520 	}
1521 	total_fork++;
1522 
1523 	return 0;
1524 }
1525 
1526 static int
1527 process_period_event(event_t *event, unsigned long offset, unsigned long head)
1528 {
1529 	dprintf("%p [%p]: PERF_EVENT_PERIOD: time:%Ld, id:%Ld: period:%Ld\n",
1530 		(void *)(offset + head),
1531 		(void *)(long)(event->header.size),
1532 		event->period.time,
1533 		event->period.id,
1534 		event->period.sample_period);
1535 
1536 	return 0;
1537 }
1538 
1539 static int
1540 process_lost_event(event_t *event, unsigned long offset, unsigned long head)
1541 {
1542 	dprintf("%p [%p]: PERF_EVENT_LOST: id:%Ld: lost:%Ld\n",
1543 		(void *)(offset + head),
1544 		(void *)(long)(event->header.size),
1545 		event->lost.id,
1546 		event->lost.lost);
1547 
1548 	total_lost += event->lost.lost;
1549 
1550 	return 0;
1551 }
1552 
1553 static void trace_event(event_t *event)
1554 {
1555 	unsigned char *raw_event = (void *)event;
1556 	char *color = PERF_COLOR_BLUE;
1557 	int i, j;
1558 
1559 	if (!dump_trace)
1560 		return;
1561 
1562 	dprintf(".");
1563 	cdprintf("\n. ... raw event: size %d bytes\n", event->header.size);
1564 
1565 	for (i = 0; i < event->header.size; i++) {
1566 		if ((i & 15) == 0) {
1567 			dprintf(".");
1568 			cdprintf("  %04x: ", i);
1569 		}
1570 
1571 		cdprintf(" %02x", raw_event[i]);
1572 
1573 		if (((i & 15) == 15) || i == event->header.size-1) {
1574 			cdprintf("  ");
1575 			for (j = 0; j < 15-(i & 15); j++)
1576 				cdprintf("   ");
1577 			for (j = 0; j < (i & 15); j++) {
1578 				if (isprint(raw_event[i-15+j]))
1579 					cdprintf("%c", raw_event[i-15+j]);
1580 				else
1581 					cdprintf(".");
1582 			}
1583 			cdprintf("\n");
1584 		}
1585 	}
1586 	dprintf(".\n");
1587 }
1588 
1589 static int
1590 process_read_event(event_t *event, unsigned long offset, unsigned long head)
1591 {
1592 	dprintf("%p [%p]: PERF_EVENT_READ: %d %d %Lu\n",
1593 			(void *)(offset + head),
1594 			(void *)(long)(event->header.size),
1595 			event->read.pid,
1596 			event->read.tid,
1597 			event->read.value);
1598 
1599 	return 0;
1600 }
1601 
1602 static int
1603 process_event(event_t *event, unsigned long offset, unsigned long head)
1604 {
1605 	trace_event(event);
1606 
1607 	switch (event->header.type) {
1608 	case PERF_EVENT_SAMPLE:
1609 		return process_sample_event(event, offset, head);
1610 
1611 	case PERF_EVENT_MMAP:
1612 		return process_mmap_event(event, offset, head);
1613 
1614 	case PERF_EVENT_COMM:
1615 		return process_comm_event(event, offset, head);
1616 
1617 	case PERF_EVENT_FORK:
1618 		return process_fork_event(event, offset, head);
1619 
1620 	case PERF_EVENT_PERIOD:
1621 		return process_period_event(event, offset, head);
1622 
1623 	case PERF_EVENT_LOST:
1624 		return process_lost_event(event, offset, head);
1625 
1626 	case PERF_EVENT_READ:
1627 		return process_read_event(event, offset, head);
1628 
1629 	/*
1630 	 * We dont process them right now but they are fine:
1631 	 */
1632 
1633 	case PERF_EVENT_THROTTLE:
1634 	case PERF_EVENT_UNTHROTTLE:
1635 		return 0;
1636 
1637 	default:
1638 		return -1;
1639 	}
1640 
1641 	return 0;
1642 }
1643 
1644 static struct perf_header	*header;
1645 
1646 static u64 perf_header__sample_type(void)
1647 {
1648 	u64 sample_type = 0;
1649 	int i;
1650 
1651 	for (i = 0; i < header->attrs; i++) {
1652 		struct perf_header_attr *attr = header->attr[i];
1653 
1654 		if (!sample_type)
1655 			sample_type = attr->attr.sample_type;
1656 		else if (sample_type != attr->attr.sample_type)
1657 			die("non matching sample_type");
1658 	}
1659 
1660 	return sample_type;
1661 }
1662 
1663 static int __cmd_report(void)
1664 {
1665 	int ret, rc = EXIT_FAILURE;
1666 	unsigned long offset = 0;
1667 	unsigned long head, shift;
1668 	struct stat stat;
1669 	event_t *event;
1670 	uint32_t size;
1671 	char *buf;
1672 
1673 	register_idle_thread();
1674 
1675 	input = open(input_name, O_RDONLY);
1676 	if (input < 0) {
1677 		fprintf(stderr, " failed to open file: %s", input_name);
1678 		if (!strcmp(input_name, "perf.data"))
1679 			fprintf(stderr, "  (try 'perf record' first)");
1680 		fprintf(stderr, "\n");
1681 		exit(-1);
1682 	}
1683 
1684 	ret = fstat(input, &stat);
1685 	if (ret < 0) {
1686 		perror("failed to stat file");
1687 		exit(-1);
1688 	}
1689 
1690 	if (!stat.st_size) {
1691 		fprintf(stderr, "zero-sized file, nothing to do!\n");
1692 		exit(0);
1693 	}
1694 
1695 	header = perf_header__read(input);
1696 	head = header->data_offset;
1697 
1698 	sample_type = perf_header__sample_type();
1699 
1700 	if (!(sample_type & PERF_SAMPLE_CALLCHAIN)) {
1701 		if (sort__has_parent) {
1702 			fprintf(stderr, "selected --sort parent, but no"
1703 					" callchain data. Did you call"
1704 					" perf record without -g?\n");
1705 			exit(-1);
1706 		}
1707 		if (callchain) {
1708 			fprintf(stderr, "selected -c but no callchain data."
1709 					" Did you call perf record without"
1710 					" -g?\n");
1711 			exit(-1);
1712 		}
1713 	}
1714 
1715 	if (load_kernel() < 0) {
1716 		perror("failed to load kernel symbols");
1717 		return EXIT_FAILURE;
1718 	}
1719 
1720 	if (!full_paths) {
1721 		if (getcwd(__cwd, sizeof(__cwd)) == NULL) {
1722 			perror("failed to get the current directory");
1723 			return EXIT_FAILURE;
1724 		}
1725 		cwdlen = strlen(cwd);
1726 	} else {
1727 		cwd = NULL;
1728 		cwdlen = 0;
1729 	}
1730 
1731 	shift = page_size * (head / page_size);
1732 	offset += shift;
1733 	head -= shift;
1734 
1735 remap:
1736 	buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ,
1737 			   MAP_SHARED, input, offset);
1738 	if (buf == MAP_FAILED) {
1739 		perror("failed to mmap file");
1740 		exit(-1);
1741 	}
1742 
1743 more:
1744 	event = (event_t *)(buf + head);
1745 
1746 	size = event->header.size;
1747 	if (!size)
1748 		size = 8;
1749 
1750 	if (head + event->header.size >= page_size * mmap_window) {
1751 		int ret;
1752 
1753 		shift = page_size * (head / page_size);
1754 
1755 		ret = munmap(buf, page_size * mmap_window);
1756 		assert(ret == 0);
1757 
1758 		offset += shift;
1759 		head -= shift;
1760 		goto remap;
1761 	}
1762 
1763 	size = event->header.size;
1764 
1765 	dprintf("\n%p [%p]: event: %d\n",
1766 			(void *)(offset + head),
1767 			(void *)(long)event->header.size,
1768 			event->header.type);
1769 
1770 	if (!size || process_event(event, offset, head) < 0) {
1771 
1772 		dprintf("%p [%p]: skipping unknown header type: %d\n",
1773 			(void *)(offset + head),
1774 			(void *)(long)(event->header.size),
1775 			event->header.type);
1776 
1777 		total_unknown++;
1778 
1779 		/*
1780 		 * assume we lost track of the stream, check alignment, and
1781 		 * increment a single u64 in the hope to catch on again 'soon'.
1782 		 */
1783 
1784 		if (unlikely(head & 7))
1785 			head &= ~7ULL;
1786 
1787 		size = 8;
1788 	}
1789 
1790 	head += size;
1791 
1792 	if (offset + head >= header->data_offset + header->data_size)
1793 		goto done;
1794 
1795 	if (offset + head < (unsigned long)stat.st_size)
1796 		goto more;
1797 
1798 done:
1799 	rc = EXIT_SUCCESS;
1800 	close(input);
1801 
1802 	dprintf("      IP events: %10ld\n", total);
1803 	dprintf("    mmap events: %10ld\n", total_mmap);
1804 	dprintf("    comm events: %10ld\n", total_comm);
1805 	dprintf("    fork events: %10ld\n", total_fork);
1806 	dprintf("    lost events: %10ld\n", total_lost);
1807 	dprintf(" unknown events: %10ld\n", total_unknown);
1808 
1809 	if (dump_trace)
1810 		return 0;
1811 
1812 	if (verbose >= 3)
1813 		threads__fprintf(stdout);
1814 
1815 	if (verbose >= 2)
1816 		dsos__fprintf(stdout);
1817 
1818 	collapse__resort();
1819 	output__resort(total);
1820 	output__fprintf(stdout, total);
1821 
1822 	return rc;
1823 }
1824 
1825 static int
1826 parse_callchain_opt(const struct option *opt __used, const char *arg,
1827 		    int unset __used)
1828 {
1829 	char *tok;
1830 	char *endptr;
1831 
1832 	callchain = 1;
1833 
1834 	if (!arg)
1835 		return 0;
1836 
1837 	tok = strtok((char *)arg, ",");
1838 	if (!tok)
1839 		return -1;
1840 
1841 	/* get the output mode */
1842 	if (!strncmp(tok, "graph", strlen(arg)))
1843 		callchain_param.mode = CHAIN_GRAPH_ABS;
1844 
1845 	else if (!strncmp(tok, "flat", strlen(arg)))
1846 		callchain_param.mode = CHAIN_FLAT;
1847 
1848 	else if (!strncmp(tok, "fractal", strlen(arg)))
1849 		callchain_param.mode = CHAIN_GRAPH_REL;
1850 
1851 	else
1852 		return -1;
1853 
1854 	/* get the min percentage */
1855 	tok = strtok(NULL, ",");
1856 	if (!tok)
1857 		goto setup;
1858 
1859 	callchain_param.min_percent = strtod(tok, &endptr);
1860 	if (tok == endptr)
1861 		return -1;
1862 
1863 setup:
1864 	if (register_callchain_param(&callchain_param) < 0) {
1865 		fprintf(stderr, "Can't register callchain params\n");
1866 		return -1;
1867 	}
1868 	return 0;
1869 }
1870 
1871 static const char * const report_usage[] = {
1872 	"perf report [<options>] <command>",
1873 	NULL
1874 };
1875 
1876 static const struct option options[] = {
1877 	OPT_STRING('i', "input", &input_name, "file",
1878 		    "input file name"),
1879 	OPT_BOOLEAN('v', "verbose", &verbose,
1880 		    "be more verbose (show symbol address, etc)"),
1881 	OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
1882 		    "dump raw trace in ASCII"),
1883 	OPT_STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"),
1884 	OPT_BOOLEAN('m', "modules", &modules,
1885 		    "load module symbols - WARNING: use only with -k and LIVE kernel"),
1886 	OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
1887 		   "sort by key(s): pid, comm, dso, symbol, parent"),
1888 	OPT_BOOLEAN('P', "full-paths", &full_paths,
1889 		    "Don't shorten the pathnames taking into account the cwd"),
1890 	OPT_STRING('p', "parent", &parent_pattern, "regex",
1891 		   "regex filter to identify parent, see: '--sort parent'"),
1892 	OPT_BOOLEAN('x', "exclude-other", &exclude_other,
1893 		    "Only display entries with parent-match"),
1894 	OPT_CALLBACK_DEFAULT('c', "callchain", NULL, "output_type,min_percent",
1895 		     "Display callchains using output_type and min percent threshold. "
1896 		     "Default: flat,0", &parse_callchain_opt, callchain_default_opt),
1897 	OPT_STRING('d', "dsos", &dso_list_str, "dso[,dso...]",
1898 		   "only consider symbols in these dsos"),
1899 	OPT_STRING('C', "comms", &comm_list_str, "comm[,comm...]",
1900 		   "only consider symbols in these comms"),
1901 	OPT_STRING('S', "symbols", &sym_list_str, "symbol[,symbol...]",
1902 		   "only consider these symbols"),
1903 	OPT_END()
1904 };
1905 
1906 static void setup_sorting(void)
1907 {
1908 	char *tmp, *tok, *str = strdup(sort_order);
1909 
1910 	for (tok = strtok_r(str, ", ", &tmp);
1911 			tok; tok = strtok_r(NULL, ", ", &tmp)) {
1912 		if (sort_dimension__add(tok) < 0) {
1913 			error("Unknown --sort key: `%s'", tok);
1914 			usage_with_options(report_usage, options);
1915 		}
1916 	}
1917 
1918 	free(str);
1919 }
1920 
1921 static void setup_list(struct strlist **list, const char *list_str,
1922 		       const char *list_name)
1923 {
1924 	if (list_str) {
1925 		*list = strlist__new(true, list_str);
1926 		if (!*list) {
1927 			fprintf(stderr, "problems parsing %s list\n",
1928 				list_name);
1929 			exit(129);
1930 		}
1931 	}
1932 }
1933 
1934 int cmd_report(int argc, const char **argv, const char *prefix __used)
1935 {
1936 	symbol__init();
1937 
1938 	page_size = getpagesize();
1939 
1940 	argc = parse_options(argc, argv, options, report_usage, 0);
1941 
1942 	setup_sorting();
1943 
1944 	if (parent_pattern != default_parent_pattern)
1945 		sort_dimension__add("parent");
1946 	else
1947 		exclude_other = 0;
1948 
1949 	/*
1950 	 * Any (unrecognized) arguments left?
1951 	 */
1952 	if (argc)
1953 		usage_with_options(report_usage, options);
1954 
1955 	setup_list(&dso_list, dso_list_str, "dso");
1956 	setup_list(&comm_list, comm_list_str, "comm");
1957 	setup_list(&sym_list, sym_list_str, "symbol");
1958 
1959 	setup_pager();
1960 
1961 	return __cmd_report();
1962 }
1963