aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/perf_counter/builtin-report.c
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2009-06-04 10:53:49 -0400
committerIngo Molnar <mingo@elte.hu>2009-06-04 11:51:39 -0400
commit62fc44536c14b5787531bac7417580fca54c88b4 (patch)
tree6b43ae4d32a1087f5e1bfa04d323fae8067a8ce4 /Documentation/perf_counter/builtin-report.c
parentd99e9446200c1ffab28cb0e39b76c34a2bfafd06 (diff)
perf_counter tools: Use fork and remove munmap events
Use fork events to clone comm and map data and remove everything munmap related Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> LKML-Reference: <new-submission> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'Documentation/perf_counter/builtin-report.c')
-rw-r--r--Documentation/perf_counter/builtin-report.c103
1 files changed, 93 insertions, 10 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)