aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/perf_counter
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/perf_counter')
-rw-r--r--Documentation/perf_counter/builtin-report.c103
-rw-r--r--Documentation/perf_counter/builtin-top.c21
2 files changed, 93 insertions, 31 deletions
diff --git a/Documentation/perf_counter/builtin-report.c b/Documentation/perf_counter/builtin-report.c
index 389ae2569f49..5d191216c80a 100644
--- a/Documentation/perf_counter/builtin-report.c
+++ b/Documentation/perf_counter/builtin-report.c
@@ -43,12 +43,6 @@ static int full_paths;
43static unsigned long page_size; 43static unsigned long page_size;
44static unsigned long mmap_window = 32; 44static unsigned long mmap_window = 32;
45 45
46const char *perf_event_names[] = {
47 [PERF_EVENT_MMAP] = " PERF_EVENT_MMAP",
48 [PERF_EVENT_MUNMAP] = " PERF_EVENT_MUNMAP",
49 [PERF_EVENT_COMM] = " PERF_EVENT_COMM",
50};
51
52struct ip_event { 46struct ip_event {
53 struct perf_event_header header; 47 struct perf_event_header header;
54 __u64 ip; 48 __u64 ip;
@@ -70,11 +64,17 @@ struct comm_event {
70 char comm[16]; 64 char comm[16];
71}; 65};
72 66
67struct fork_event {
68 struct perf_event_header header;
69 __u32 pid, ppid;
70};
71
73typedef union event_union { 72typedef union event_union {
74 struct perf_event_header header; 73 struct perf_event_header header;
75 struct ip_event ip; 74 struct ip_event ip;
76 struct mmap_event mmap; 75 struct mmap_event mmap;
77 struct comm_event comm; 76 struct comm_event comm;
77 struct fork_event fork;
78} event_t; 78} event_t;
79 79
80static LIST_HEAD(dsos); 80static LIST_HEAD(dsos);
@@ -208,7 +208,31 @@ out_delete:
208 return NULL; 208 return NULL;
209} 209}
210 210
211struct thread; 211static struct map *map__clone(struct map *self)
212{
213 struct map *map = malloc(sizeof(*self));
214
215 if (!map)
216 return NULL;
217
218 memcpy(map, self, sizeof(*self));
219
220 return map;
221}
222
223static int map__overlap(struct map *l, struct map *r)
224{
225 if (l->start > r->start) {
226 struct map *t = l;
227 l = r;
228 r = t;
229 }
230
231 if (l->end > r->start)
232 return 1;
233
234 return 0;
235}
212 236
213struct thread { 237struct thread {
214 struct rb_node rb_node; 238 struct rb_node rb_node;
@@ -284,9 +308,39 @@ static struct thread *threads__findnew(pid_t pid)
284 308
285static void thread__insert_map(struct thread *self, struct map *map) 309static void thread__insert_map(struct thread *self, struct map *map)
286{ 310{
311 struct map *pos, *tmp;
312
313 list_for_each_entry_safe(pos, tmp, &self->maps, node) {
314 if (map__overlap(pos, map)) {
315 list_del_init(&pos->node);
316 /* XXX leaks dsos */
317 free(pos);
318 }
319 }
320
287 list_add_tail(&map->node, &self->maps); 321 list_add_tail(&map->node, &self->maps);
288} 322}
289 323
324static int thread__fork(struct thread *self, struct thread *parent)
325{
326 struct map *map;
327
328 if (self->comm)
329 free(self->comm);
330 self->comm = strdup(parent->comm);
331 if (!self->comm)
332 return -ENOMEM;
333
334 list_for_each_entry(map, &parent->maps, node) {
335 struct map *new = map__clone(map);
336 if (!new)
337 return -ENOMEM;
338 thread__insert_map(self, new);
339 }
340
341 return 0;
342}
343
290static struct map *thread__find_map(struct thread *self, uint64_t ip) 344static struct map *thread__find_map(struct thread *self, uint64_t ip)
291{ 345{
292 struct map *pos; 346 struct map *pos;
@@ -784,7 +838,11 @@ static void register_idle_thread(void)
784 } 838 }
785} 839}
786 840
787static unsigned long total = 0, total_mmap = 0, total_comm = 0, total_unknown = 0; 841static unsigned long total = 0,
842 total_mmap = 0,
843 total_comm = 0,
844 total_fork = 0,
845 total_unknown = 0;
788 846
789static int 847static int
790process_overflow_event(event_t *event, unsigned long offset, unsigned long head) 848process_overflow_event(event_t *event, unsigned long offset, unsigned long head)
@@ -866,9 +924,10 @@ process_mmap_event(event_t *event, unsigned long offset, unsigned long head)
866 struct thread *thread = threads__findnew(event->mmap.pid); 924 struct thread *thread = threads__findnew(event->mmap.pid);
867 struct map *map = map__new(&event->mmap); 925 struct map *map = map__new(&event->mmap);
868 926
869 dprintf("%p [%p]: PERF_EVENT_MMAP: [%p(%p) @ %p]: %s\n", 927 dprintf("%p [%p]: PERF_EVENT_MMAP %d: [%p(%p) @ %p]: %s\n",
870 (void *)(offset + head), 928 (void *)(offset + head),
871 (void *)(long)(event->header.size), 929 (void *)(long)(event->header.size),
930 event->mmap.pid,
872 (void *)(long)event->mmap.start, 931 (void *)(long)event->mmap.start,
873 (void *)(long)event->mmap.len, 932 (void *)(long)event->mmap.len,
874 (void *)(long)event->mmap.pgoff, 933 (void *)(long)event->mmap.pgoff,
@@ -906,6 +965,26 @@ process_comm_event(event_t *event, unsigned long offset, unsigned long head)
906} 965}
907 966
908static int 967static int
968process_fork_event(event_t *event, unsigned long offset, unsigned long head)
969{
970 struct thread *thread = threads__findnew(event->fork.pid);
971 struct thread *parent = threads__findnew(event->fork.ppid);
972
973 dprintf("%p [%p]: PERF_EVENT_FORK: %d:%d\n",
974 (void *)(offset + head),
975 (void *)(long)(event->header.size),
976 event->fork.pid, event->fork.ppid);
977
978 if (!thread || !parent || thread__fork(thread, parent)) {
979 dprintf("problem processing PERF_EVENT_FORK, skipping event.\n");
980 return -1;
981 }
982 total_fork++;
983
984 return 0;
985}
986
987static int
909process_event(event_t *event, unsigned long offset, unsigned long head) 988process_event(event_t *event, unsigned long offset, unsigned long head)
910{ 989{
911 if (event->header.misc & PERF_EVENT_MISC_OVERFLOW) 990 if (event->header.misc & PERF_EVENT_MISC_OVERFLOW)
@@ -918,10 +997,13 @@ process_event(event_t *event, unsigned long offset, unsigned long head)
918 case PERF_EVENT_COMM: 997 case PERF_EVENT_COMM:
919 return process_comm_event(event, offset, head); 998 return process_comm_event(event, offset, head);
920 999
1000 case PERF_EVENT_FORK:
1001 return process_fork_event(event, offset, head);
1002
921 /* 1003 /*
922 * We dont process them right now but they are fine: 1004 * We dont process them right now but they are fine:
923 */ 1005 */
924 case PERF_EVENT_MUNMAP: 1006
925 case PERF_EVENT_PERIOD: 1007 case PERF_EVENT_PERIOD:
926 case PERF_EVENT_THROTTLE: 1008 case PERF_EVENT_THROTTLE:
927 case PERF_EVENT_UNTHROTTLE: 1009 case PERF_EVENT_UNTHROTTLE:
@@ -1038,6 +1120,7 @@ more:
1038 dprintf(" IP events: %10ld\n", total); 1120 dprintf(" IP events: %10ld\n", total);
1039 dprintf(" mmap events: %10ld\n", total_mmap); 1121 dprintf(" mmap events: %10ld\n", total_mmap);
1040 dprintf(" comm events: %10ld\n", total_comm); 1122 dprintf(" comm events: %10ld\n", total_comm);
1123 dprintf(" fork events: %10ld\n", total_fork);
1041 dprintf(" unknown events: %10ld\n", total_unknown); 1124 dprintf(" unknown events: %10ld\n", total_unknown);
1042 1125
1043 if (dump_trace) 1126 if (dump_trace)
diff --git a/Documentation/perf_counter/builtin-top.c b/Documentation/perf_counter/builtin-top.c
index 20e5b1200959..31c00ba99b14 100644
--- a/Documentation/perf_counter/builtin-top.c
+++ b/Documentation/perf_counter/builtin-top.c
@@ -75,8 +75,6 @@ static unsigned int realtime_prio = 0;
75static int group = 0; 75static int group = 0;
76static unsigned int page_size; 76static unsigned int page_size;
77static unsigned int mmap_pages = 16; 77static unsigned int mmap_pages = 16;
78static int use_mmap = 0;
79static int use_munmap = 0;
80static int freq = 0; 78static int freq = 0;
81 79
82static char *sym_filter; 80static char *sym_filter;
@@ -527,19 +525,6 @@ static void mmap_read(struct mmap_data *md)
527 if (event->header.misc & PERF_EVENT_MISC_OVERFLOW) { 525 if (event->header.misc & PERF_EVENT_MISC_OVERFLOW) {
528 if (event->header.type & PERF_SAMPLE_IP) 526 if (event->header.type & PERF_SAMPLE_IP)
529 process_event(event->ip.ip, md->counter); 527 process_event(event->ip.ip, md->counter);
530 } else {
531 switch (event->header.type) {
532 case PERF_EVENT_MMAP:
533 case PERF_EVENT_MUNMAP:
534 printf("%s: %Lu %Lu %Lu %s\n",
535 event->header.type == PERF_EVENT_MMAP
536 ? "mmap" : "munmap",
537 event->mmap.start,
538 event->mmap.len,
539 event->mmap.pgoff,
540 event->mmap.filename);
541 break;
542 }
543 } 528 }
544 } 529 }
545 530
@@ -569,8 +554,6 @@ static int __cmd_top(void)
569 attr.config = event_id[counter]; 554 attr.config = event_id[counter];
570 attr.sample_period = event_count[counter]; 555 attr.sample_period = event_count[counter];
571 attr.sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID; 556 attr.sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID;
572 attr.mmap = use_mmap;
573 attr.munmap = use_munmap;
574 attr.freq = freq; 557 attr.freq = freq;
575 558
576 fd[i][counter] = sys_perf_counter_open(&attr, target_pid, cpu, group_fd, 0); 559 fd[i][counter] = sys_perf_counter_open(&attr, target_pid, cpu, group_fd, 0);
@@ -670,10 +653,6 @@ static const struct option options[] = {
670 "only display symbols matchig this pattern"), 653 "only display symbols matchig this pattern"),
671 OPT_BOOLEAN('z', "zero", &group, 654 OPT_BOOLEAN('z', "zero", &group,
672 "zero history across updates"), 655 "zero history across updates"),
673 OPT_BOOLEAN('M', "use-mmap", &use_mmap,
674 "track mmap events"),
675 OPT_BOOLEAN('U', "use-munmap", &use_munmap,
676 "track munmap events"),
677 OPT_INTEGER('F', "freq", &freq, 656 OPT_INTEGER('F', "freq", &freq,
678 "profile at this frequency"), 657 "profile at this frequency"),
679 OPT_INTEGER('E', "entries", &print_entries, 658 OPT_INTEGER('E', "entries", &print_entries,