aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2009-11-27 13:29:22 -0500
committerIngo Molnar <mingo@elte.hu>2009-11-27 14:22:01 -0500
commit62daacb51a2bf8480e6f6b3696b03f102fc15eb0 (patch)
tree5b9ed87005a5e59bcc95dd9a42e3d09d6481362d
parent1de8e24520ffdcf2a90c842eed937f59079a2abd (diff)
perf tools: Reorganize event processing routines, lotsa dups killed
While implementing event__preprocess_sample, that will do all of the symbol lookup in one convenient function, I noticed that util/process_event.[ch] were not being used at all, then started looking if there were other functions that could be shared and... All those functions really don't need to receive offset + head, the only thing they did was common to all of them, so do it at one place instead. Stats about number of each type of event processed now is done in a central place. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Frédéric Weisbecker <fweisbec@gmail.com> Cc: John Kacur <jkacur@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Paul Mackerras <paulus@samba.org> LKML-Reference: <1259346563-12568-11-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--tools/perf/Makefile2
-rw-r--r--tools/perf/builtin-annotate.c63
-rw-r--r--tools/perf/builtin-kmem.c33
-rw-r--r--tools/perf/builtin-report.c72
-rw-r--r--tools/perf/builtin-sched.c42
-rw-r--r--tools/perf/builtin-top.c19
-rw-r--r--tools/perf/builtin-trace.c40
-rw-r--r--tools/perf/util/data_map.c56
-rw-r--r--tools/perf/util/data_map.h2
-rw-r--r--tools/perf/util/event.c74
-rw-r--r--tools/perf/util/event.h17
-rw-r--r--tools/perf/util/hist.c7
-rw-r--r--tools/perf/util/process_event.c53
-rw-r--r--tools/perf/util/process_event.h29
-rw-r--r--tools/perf/util/process_events.c64
-rw-r--r--tools/perf/util/process_events.h35
16 files changed, 183 insertions, 425 deletions
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index de37d492e10f..f1537a94a05f 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -369,7 +369,6 @@ LIB_H += util/sort.h
369LIB_H += util/hist.h 369LIB_H += util/hist.h
370LIB_H += util/thread.h 370LIB_H += util/thread.h
371LIB_H += util/data_map.h 371LIB_H += util/data_map.h
372LIB_H += util/process_events.h
373 372
374LIB_OBJS += util/abspath.o 373LIB_OBJS += util/abspath.o
375LIB_OBJS += util/alias.o 374LIB_OBJS += util/alias.o
@@ -412,7 +411,6 @@ LIB_OBJS += util/svghelper.o
412LIB_OBJS += util/sort.o 411LIB_OBJS += util/sort.o
413LIB_OBJS += util/hist.o 412LIB_OBJS += util/hist.o
414LIB_OBJS += util/data_map.o 413LIB_OBJS += util/data_map.o
415LIB_OBJS += util/process_events.o
416 414
417BUILTIN_OBJS += builtin-annotate.o 415BUILTIN_OBJS += builtin-annotate.o
418 416
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 3ebd70b1ef93..7d39bd2b19b8 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -19,12 +19,12 @@
19#include "perf.h" 19#include "perf.h"
20#include "util/debug.h" 20#include "util/debug.h"
21 21
22#include "util/event.h"
22#include "util/parse-options.h" 23#include "util/parse-options.h"
23#include "util/parse-events.h" 24#include "util/parse-events.h"
24#include "util/thread.h" 25#include "util/thread.h"
25#include "util/sort.h" 26#include "util/sort.h"
26#include "util/hist.h" 27#include "util/hist.h"
27#include "util/process_events.h"
28 28
29static char const *input_name = "perf.data"; 29static char const *input_name = "perf.data";
30 30
@@ -136,8 +136,7 @@ static int hist_entry__add(struct thread *thread, struct map *map,
136 return 0; 136 return 0;
137} 137}
138 138
139static int 139static int process_sample_event(event_t *event)
140process_sample_event(event_t *event, unsigned long offset, unsigned long head)
141{ 140{
142 char level; 141 char level;
143 u64 ip = event->ip.ip; 142 u64 ip = event->ip.ip;
@@ -145,12 +144,8 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
145 struct symbol *sym = NULL; 144 struct symbol *sym = NULL;
146 struct thread *thread = threads__findnew(event->ip.pid); 145 struct thread *thread = threads__findnew(event->ip.pid);
147 146
148 dump_printf("%p [%p]: PERF_EVENT (IP, %d): %d: %p\n", 147 dump_printf("(IP, %d): %d: %p\n", event->header.misc,
149 (void *)(offset + head), 148 event->ip.pid, (void *)(long)ip);
150 (void *)(long)(event->header.size),
151 event->header.misc,
152 event->ip.pid,
153 (void *)(long)ip);
154 149
155 if (thread == NULL) { 150 if (thread == NULL) {
156 fprintf(stderr, "problem processing %d event, skipping it.\n", 151 fprintf(stderr, "problem processing %d event, skipping it.\n",
@@ -198,46 +193,24 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
198 "skipping event\n"); 193 "skipping event\n");
199 return -1; 194 return -1;
200 } 195 }
201 total++;
202 196
203 return 0; 197 return 0;
204} 198}
205 199
206static int 200static int event__process(event_t *self)
207process_comm_event(event_t *event, unsigned long offset, unsigned long head)
208{ 201{
209 struct thread *thread = threads__findnew(event->comm.pid); 202 switch (self->header.type) {
210
211 dump_printf("%p [%p]: PERF_RECORD_COMM: %s:%d\n",
212 (void *)(offset + head),
213 (void *)(long)(event->header.size),
214 event->comm.comm, event->comm.pid);
215
216 if (thread == NULL ||
217 thread__set_comm(thread, event->comm.comm)) {
218 dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
219 return -1;
220 }
221 total_comm++;
222
223 return 0;
224}
225
226static int
227process_event(event_t *event, unsigned long offset, unsigned long head)
228{
229 switch (event->header.type) {
230 case PERF_RECORD_SAMPLE: 203 case PERF_RECORD_SAMPLE:
231 return process_sample_event(event, offset, head); 204 return process_sample_event(self);
232 205
233 case PERF_RECORD_MMAP: 206 case PERF_RECORD_MMAP:
234 return process_mmap_event(event, offset, head); 207 return event__process_mmap(self);
235 208
236 case PERF_RECORD_COMM: 209 case PERF_RECORD_COMM:
237 return process_comm_event(event, offset, head); 210 return event__process_comm(self);
238 211
239 case PERF_RECORD_FORK: 212 case PERF_RECORD_FORK:
240 return process_task_event(event, offset, head); 213 return event__process_task(self);
241 /* 214 /*
242 * We dont process them right now but they are fine: 215 * We dont process them right now but they are fine:
243 */ 216 */
@@ -621,15 +594,12 @@ more:
621 (void *)(long)event->header.size, 594 (void *)(long)event->header.size,
622 event->header.type); 595 event->header.type);
623 596
624 if (!size || process_event(event, offset, head) < 0) { 597 if (!size || event__process(event) < 0) {
625 598
626 dump_printf("%p [%p]: skipping unknown header type: %d\n", 599 dump_printf("%p [%p]: skipping unknown header type: %d\n",
627 (void *)(offset + head), 600 (void *)(offset + head),
628 (void *)(long)(event->header.size), 601 (void *)(long)(event->header.size),
629 event->header.type); 602 event->header.type);
630
631 total_unknown++;
632
633 /* 603 /*
634 * assume we lost track of the stream, check alignment, and 604 * assume we lost track of the stream, check alignment, and
635 * increment a single u64 in the hope to catch on again 'soon'. 605 * increment a single u64 in the hope to catch on again 'soon'.
@@ -649,14 +619,11 @@ more:
649 rc = EXIT_SUCCESS; 619 rc = EXIT_SUCCESS;
650 close(input); 620 close(input);
651 621
652 dump_printf(" IP events: %10ld\n", total);
653 dump_printf(" mmap events: %10ld\n", total_mmap);
654 dump_printf(" comm events: %10ld\n", total_comm);
655 dump_printf(" fork events: %10ld\n", total_fork);
656 dump_printf(" unknown events: %10ld\n", total_unknown);
657 622
658 if (dump_trace) 623 if (dump_trace) {
624 event__print_totals();
659 return 0; 625 return 0;
626 }
660 627
661 if (verbose > 3) 628 if (verbose > 3)
662 threads__fprintf(stdout); 629 threads__fprintf(stdout);
@@ -665,7 +632,7 @@ more:
665 dsos__fprintf(stdout); 632 dsos__fprintf(stdout);
666 633
667 collapse__resort(); 634 collapse__resort();
668 output__resort(total); 635 output__resort(event__total[0]);
669 636
670 find_annotations(); 637 find_annotations();
671 638
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index 35722fafc4d1..e7294c8fc620 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -33,9 +33,6 @@ static bool raw_ip;
33 33
34static char default_sort_order[] = "frag,hit,bytes"; 34static char default_sort_order[] = "frag,hit,bytes";
35 35
36static char *cwd;
37static int cwdlen;
38
39static int *cpunode_map; 36static int *cpunode_map;
40static int max_cpu_num; 37static int max_cpu_num;
41 38
@@ -126,25 +123,6 @@ static void setup_cpunode_map(void)
126 } 123 }
127} 124}
128 125
129static int
130process_comm_event(event_t *event, unsigned long offset, unsigned long head)
131{
132 struct thread *thread = threads__findnew(event->comm.pid);
133
134 dump_printf("%p [%p]: PERF_RECORD_COMM: %s:%d\n",
135 (void *)(offset + head),
136 (void *)(long)(event->header.size),
137 event->comm.comm, event->comm.pid);
138
139 if (thread == NULL ||
140 thread__set_comm(thread, event->comm.comm)) {
141 dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
142 return -1;
143 }
144
145 return 0;
146}
147
148static void insert_alloc_stat(unsigned long call_site, unsigned long ptr, 126static void insert_alloc_stat(unsigned long call_site, unsigned long ptr,
149 int bytes_req, int bytes_alloc, int cpu) 127 int bytes_req, int bytes_alloc, int cpu)
150{ 128{
@@ -340,8 +318,7 @@ process_raw_event(event_t *raw_event __used, void *more_data,
340 } 318 }
341} 319}
342 320
343static int 321static int process_sample_event(event_t *event)
344process_sample_event(event_t *event, unsigned long offset, unsigned long head)
345{ 322{
346 u64 ip = event->ip.ip; 323 u64 ip = event->ip.ip;
347 u64 timestamp = -1; 324 u64 timestamp = -1;
@@ -366,9 +343,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
366 more_data += sizeof(u64); 343 more_data += sizeof(u64);
367 } 344 }
368 345
369 dump_printf("%p [%p]: PERF_RECORD_SAMPLE (IP, %d): %d/%d: %p period: %Ld\n", 346 dump_printf("(IP, %d): %d/%d: %p period: %Ld\n",
370 (void *)(offset + head),
371 (void *)(long)(event->header.size),
372 event->header.misc, 347 event->header.misc,
373 event->ip.pid, event->ip.tid, 348 event->ip.pid, event->ip.tid,
374 (void *)(long)ip, 349 (void *)(long)ip,
@@ -403,7 +378,7 @@ static int sample_type_check(u64 type)
403 378
404static struct perf_file_handler file_handler = { 379static struct perf_file_handler file_handler = {
405 .process_sample_event = process_sample_event, 380 .process_sample_event = process_sample_event,
406 .process_comm_event = process_comm_event, 381 .process_comm_event = event__process_comm,
407 .sample_type_check = sample_type_check, 382 .sample_type_check = sample_type_check,
408}; 383};
409 384
@@ -413,7 +388,7 @@ static int read_events(void)
413 register_perf_file_handler(&file_handler); 388 register_perf_file_handler(&file_handler);
414 389
415 return mmap_dispatch_perf_file(&header, input_name, 0, 0, 390 return mmap_dispatch_perf_file(&header, input_name, 0, 0,
416 &cwdlen, &cwd); 391 &event__cwdlen, &event__cwd);
417} 392}
418 393
419static double fragmentation(unsigned long n_req, unsigned long n_alloc) 394static double fragmentation(unsigned long n_req, unsigned long n_alloc)
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 9bd20c2ee3dd..01ef35cac5f9 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -30,7 +30,6 @@
30#include "util/thread.h" 30#include "util/thread.h"
31#include "util/sort.h" 31#include "util/sort.h"
32#include "util/hist.h" 32#include "util/hist.h"
33#include "util/process_events.h"
34 33
35static char const *input_name = "perf.data"; 34static char const *input_name = "perf.data";
36 35
@@ -655,8 +654,7 @@ static int validate_chain(struct ip_callchain *chain, event_t *event)
655 return 0; 654 return 0;
656} 655}
657 656
658static int 657static int process_sample_event(event_t *event)
659process_sample_event(event_t *event, unsigned long offset, unsigned long head)
660{ 658{
661 char level; 659 char level;
662 struct symbol *sym = NULL; 660 struct symbol *sym = NULL;
@@ -673,9 +671,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
673 more_data += sizeof(u64); 671 more_data += sizeof(u64);
674 } 672 }
675 673
676 dump_printf("%p [%p]: PERF_RECORD_SAMPLE (IP, %d): %d/%d: %p period: %Ld\n", 674 dump_printf("(IP, %d): %d/%d: %p period: %Ld\n",
677 (void *)(offset + head),
678 (void *)(long)(event->header.size),
679 event->header.misc, 675 event->header.misc,
680 event->ip.pid, event->ip.tid, 676 event->ip.pid, event->ip.tid,
681 (void *)(long)ip, 677 (void *)(long)ip,
@@ -743,47 +739,27 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
743 return -1; 739 return -1;
744 } 740 }
745 741
746 total += period; 742 event__stats.total += period;
747 743
748 return 0; 744 return 0;
749} 745}
750 746
751static int 747static int process_comm_event(event_t *event)
752process_comm_event(event_t *event, unsigned long offset, unsigned long head)
753{ 748{
754 struct thread *thread = threads__findnew(event->comm.pid); 749 struct thread *thread = threads__findnew(event->comm.pid);
755 750
756 dump_printf("%p [%p]: PERF_RECORD_COMM: %s:%d\n", 751 dump_printf(": %s:%d\n", event->comm.comm, event->comm.pid);
757 (void *)(offset + head),
758 (void *)(long)(event->header.size),
759 event->comm.comm, event->comm.pid);
760 752
761 if (thread == NULL || 753 if (thread == NULL ||
762 thread__set_comm_adjust(thread, event->comm.comm)) { 754 thread__set_comm_adjust(thread, event->comm.comm)) {
763 dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n"); 755 dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
764 return -1; 756 return -1;
765 } 757 }
766 total_comm++;
767
768 return 0;
769}
770
771static int
772process_lost_event(event_t *event, unsigned long offset, unsigned long head)
773{
774 dump_printf("%p [%p]: PERF_RECORD_LOST: id:%Ld: lost:%Ld\n",
775 (void *)(offset + head),
776 (void *)(long)(event->header.size),
777 event->lost.id,
778 event->lost.lost);
779
780 total_lost += event->lost.lost;
781 758
782 return 0; 759 return 0;
783} 760}
784 761
785static int 762static int process_read_event(event_t *event)
786process_read_event(event_t *event, unsigned long offset, unsigned long head)
787{ 763{
788 struct perf_event_attr *attr; 764 struct perf_event_attr *attr;
789 765
@@ -799,14 +775,9 @@ process_read_event(event_t *event, unsigned long offset, unsigned long head)
799 event->read.value); 775 event->read.value);
800 } 776 }
801 777
802 dump_printf("%p [%p]: PERF_RECORD_READ: %d %d %s %Lu\n", 778 dump_printf(": %d %d %s %Lu\n", event->read.pid, event->read.tid,
803 (void *)(offset + head), 779 attr ? __event_name(attr->type, attr->config) : "FAIL",
804 (void *)(long)(event->header.size), 780 event->read.value);
805 event->read.pid,
806 event->read.tid,
807 attr ? __event_name(attr->type, attr->config)
808 : "FAIL",
809 event->read.value);
810 781
811 return 0; 782 return 0;
812} 783}
@@ -842,11 +813,11 @@ static int sample_type_check(u64 type)
842 813
843static struct perf_file_handler file_handler = { 814static struct perf_file_handler file_handler = {
844 .process_sample_event = process_sample_event, 815 .process_sample_event = process_sample_event,
845 .process_mmap_event = process_mmap_event, 816 .process_mmap_event = event__process_mmap,
846 .process_comm_event = process_comm_event, 817 .process_comm_event = process_comm_event,
847 .process_exit_event = process_task_event, 818 .process_exit_event = event__process_task,
848 .process_fork_event = process_task_event, 819 .process_fork_event = event__process_task,
849 .process_lost_event = process_lost_event, 820 .process_lost_event = event__process_lost,
850 .process_read_event = process_read_event, 821 .process_read_event = process_read_event,
851 .sample_type_check = sample_type_check, 822 .sample_type_check = sample_type_check,
852}; 823};
@@ -866,19 +837,14 @@ static int __cmd_report(void)
866 register_perf_file_handler(&file_handler); 837 register_perf_file_handler(&file_handler);
867 838
868 ret = mmap_dispatch_perf_file(&header, input_name, force, 839 ret = mmap_dispatch_perf_file(&header, input_name, force,
869 full_paths, &cwdlen, &cwd); 840 full_paths, &event__cwdlen, &event__cwd);
870 if (ret) 841 if (ret)
871 return ret; 842 return ret;
872 843
873 dump_printf(" IP events: %10ld\n", total); 844 if (dump_trace) {
874 dump_printf(" mmap events: %10ld\n", total_mmap); 845 event__print_totals();
875 dump_printf(" comm events: %10ld\n", total_comm);
876 dump_printf(" fork events: %10ld\n", total_fork);
877 dump_printf(" lost events: %10ld\n", total_lost);
878 dump_printf(" unknown events: %10ld\n", file_handler.total_unknown);
879
880 if (dump_trace)
881 return 0; 846 return 0;
847 }
882 848
883 if (verbose > 3) 849 if (verbose > 3)
884 threads__fprintf(stdout); 850 threads__fprintf(stdout);
@@ -887,8 +853,8 @@ static int __cmd_report(void)
887 dsos__fprintf(stdout); 853 dsos__fprintf(stdout);
888 854
889 collapse__resort(); 855 collapse__resort();
890 output__resort(total); 856 output__resort(event__stats.total);
891 output__fprintf(stdout, total); 857 output__fprintf(stdout, event__stats.total);
892 858
893 if (show_threads) 859 if (show_threads)
894 perf_read_values_destroy(&show_threads_values); 860 perf_read_values_destroy(&show_threads_values);
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 19eb708a706b..26b782f26ee1 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -22,8 +22,6 @@
22 22
23static char const *input_name = "perf.data"; 23static char const *input_name = "perf.data";
24 24
25static unsigned long total_comm = 0;
26
27static struct perf_header *header; 25static struct perf_header *header;
28static u64 sample_type; 26static u64 sample_type;
29 27
@@ -32,9 +30,6 @@ static char *sort_order = default_sort_order;
32 30
33static int profile_cpu = -1; 31static int profile_cpu = -1;
34 32
35static char *cwd;
36static int cwdlen;
37
38#define PR_SET_NAME 15 /* Set process name */ 33#define PR_SET_NAME 15 /* Set process name */
39#define MAX_CPUS 4096 34#define MAX_CPUS 4096
40 35
@@ -633,27 +628,6 @@ static void test_calibrations(void)
633 printf("the sleep test took %Ld nsecs\n", T1-T0); 628 printf("the sleep test took %Ld nsecs\n", T1-T0);
634} 629}
635 630
636static int
637process_comm_event(event_t *event, unsigned long offset, unsigned long head)
638{
639 struct thread *thread = threads__findnew(event->comm.tid);
640
641 dump_printf("%p [%p]: perf_event_comm: %s:%d\n",
642 (void *)(offset + head),
643 (void *)(long)(event->header.size),
644 event->comm.comm, event->comm.pid);
645
646 if (thread == NULL ||
647 thread__set_comm(thread, event->comm.comm)) {
648 dump_printf("problem processing perf_event_comm, skipping event.\n");
649 return -1;
650 }
651 total_comm++;
652
653 return 0;
654}
655
656
657struct raw_event_sample { 631struct raw_event_sample {
658 u32 size; 632 u32 size;
659 char data[0]; 633 char data[0];
@@ -1622,8 +1596,7 @@ process_raw_event(event_t *raw_event __used, void *more_data,
1622 process_sched_migrate_task_event(raw, event, cpu, timestamp, thread); 1596 process_sched_migrate_task_event(raw, event, cpu, timestamp, thread);
1623} 1597}
1624 1598
1625static int 1599static int process_sample_event(event_t *event)
1626process_sample_event(event_t *event, unsigned long offset, unsigned long head)
1627{ 1600{
1628 struct thread *thread; 1601 struct thread *thread;
1629 u64 ip = event->ip.ip; 1602 u64 ip = event->ip.ip;
@@ -1653,9 +1626,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
1653 more_data += sizeof(u64); 1626 more_data += sizeof(u64);
1654 } 1627 }
1655 1628
1656 dump_printf("%p [%p]: PERF_RECORD_SAMPLE (IP, %d): %d/%d: %p period: %Ld\n", 1629 dump_printf("(IP, %d): %d/%d: %p period: %Ld\n",
1657 (void *)(offset + head),
1658 (void *)(long)(event->header.size),
1659 event->header.misc, 1630 event->header.misc,
1660 event->ip.pid, event->ip.tid, 1631 event->ip.pid, event->ip.tid,
1661 (void *)(long)ip, 1632 (void *)(long)ip,
@@ -1677,10 +1648,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
1677 return 0; 1648 return 0;
1678} 1649}
1679 1650
1680static int 1651static int process_lost_event(event_t *event __used)
1681process_lost_event(event_t *event __used,
1682 unsigned long offset __used,
1683 unsigned long head __used)
1684{ 1652{
1685 nr_lost_chunks++; 1653 nr_lost_chunks++;
1686 nr_lost_events += event->lost.lost; 1654 nr_lost_events += event->lost.lost;
@@ -1704,7 +1672,7 @@ static int sample_type_check(u64 type)
1704 1672
1705static struct perf_file_handler file_handler = { 1673static struct perf_file_handler file_handler = {
1706 .process_sample_event = process_sample_event, 1674 .process_sample_event = process_sample_event,
1707 .process_comm_event = process_comm_event, 1675 .process_comm_event = event__process_comm,
1708 .process_lost_event = process_lost_event, 1676 .process_lost_event = process_lost_event,
1709 .sample_type_check = sample_type_check, 1677 .sample_type_check = sample_type_check,
1710}; 1678};
@@ -1715,7 +1683,7 @@ static int read_events(void)
1715 register_perf_file_handler(&file_handler); 1683 register_perf_file_handler(&file_handler);
1716 1684
1717 return mmap_dispatch_perf_file(&header, input_name, 0, 0, 1685 return mmap_dispatch_perf_file(&header, input_name, 0, 0,
1718 &cwdlen, &cwd); 1686 &event__cwdlen, &event__cwd);
1719} 1687}
1720 1688
1721static void print_bad_events(void) 1689static void print_bad_events(void)
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index bf6730c76033..7a3c0c7aad3d 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -991,25 +991,6 @@ static void event__process_sample(const event_t *self, int counter)
991 } 991 }
992} 992}
993 993
994static void event__process_mmap(event_t *self)
995{
996 struct thread *thread = threads__findnew(self->mmap.pid);
997
998 if (thread != NULL) {
999 struct map *map = map__new(&self->mmap, MAP__FUNCTION, NULL, 0);
1000 if (map != NULL)
1001 thread__insert_map(thread, map);
1002 }
1003}
1004
1005static void event__process_comm(event_t *self)
1006{
1007 struct thread *thread = threads__findnew(self->comm.pid);
1008
1009 if (thread != NULL)
1010 thread__set_comm(thread, self->comm.comm);
1011}
1012
1013static int event__process(event_t *event) 994static int event__process(event_t *event)
1014{ 995{
1015 switch (event->header.type) { 996 switch (event->header.type) {
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 75972fd073df..a7750256c408 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -16,38 +16,10 @@
16 16
17static char const *input_name = "perf.data"; 17static char const *input_name = "perf.data";
18 18
19static unsigned long total = 0;
20static unsigned long total_comm = 0;
21
22static struct perf_header *header; 19static struct perf_header *header;
23static u64 sample_type; 20static u64 sample_type;
24 21
25static char *cwd; 22static int process_sample_event(event_t *event)
26static int cwdlen;
27
28
29static int
30process_comm_event(event_t *event, unsigned long offset, unsigned long head)
31{
32 struct thread *thread = threads__findnew(event->comm.pid);
33
34 dump_printf("%p [%p]: PERF_RECORD_COMM: %s:%d\n",
35 (void *)(offset + head),
36 (void *)(long)(event->header.size),
37 event->comm.comm, event->comm.pid);
38
39 if (thread == NULL ||
40 thread__set_comm(thread, event->comm.comm)) {
41 dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
42 return -1;
43 }
44 total_comm++;
45
46 return 0;
47}
48
49static int
50process_sample_event(event_t *event, unsigned long offset, unsigned long head)
51{ 23{
52 u64 ip = event->ip.ip; 24 u64 ip = event->ip.ip;
53 u64 timestamp = -1; 25 u64 timestamp = -1;
@@ -72,9 +44,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
72 more_data += sizeof(u64); 44 more_data += sizeof(u64);
73 } 45 }
74 46
75 dump_printf("%p [%p]: PERF_RECORD_SAMPLE (IP, %d): %d/%d: %p period: %Ld\n", 47 dump_printf("(IP, %d): %d/%d: %p period: %Ld\n",
76 (void *)(offset + head),
77 (void *)(long)(event->header.size),
78 event->header.misc, 48 event->header.misc,
79 event->ip.pid, event->ip.tid, 49 event->ip.pid, event->ip.tid,
80 (void *)(long)ip, 50 (void *)(long)ip,
@@ -101,7 +71,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head)
101 */ 71 */
102 print_event(cpu, raw->data, raw->size, timestamp, thread->comm); 72 print_event(cpu, raw->data, raw->size, timestamp, thread->comm);
103 } 73 }
104 total += period; 74 event__stats.total += period;
105 75
106 return 0; 76 return 0;
107} 77}
@@ -122,7 +92,7 @@ static int sample_type_check(u64 type)
122 92
123static struct perf_file_handler file_handler = { 93static struct perf_file_handler file_handler = {
124 .process_sample_event = process_sample_event, 94 .process_sample_event = process_sample_event,
125 .process_comm_event = process_comm_event, 95 .process_comm_event = event__process_comm,
126 .sample_type_check = sample_type_check, 96 .sample_type_check = sample_type_check,
127}; 97};
128 98
@@ -132,7 +102,7 @@ static int __cmd_trace(void)
132 register_perf_file_handler(&file_handler); 102 register_perf_file_handler(&file_handler);
133 103
134 return mmap_dispatch_perf_file(&header, input_name, 104 return mmap_dispatch_perf_file(&header, input_name,
135 0, 0, &cwdlen, &cwd); 105 0, 0, &event__cwdlen, &event__cwd);
136} 106}
137 107
138static const char * const annotate_usage[] = { 108static const char * const annotate_usage[] = {
diff --git a/tools/perf/util/data_map.c b/tools/perf/util/data_map.c
index b238462b8983..ca0bedf637c2 100644
--- a/tools/perf/util/data_map.c
+++ b/tools/perf/util/data_map.c
@@ -8,11 +8,9 @@ static struct perf_file_handler *curr_handler;
8static unsigned long mmap_window = 32; 8static unsigned long mmap_window = 32;
9static char __cwd[PATH_MAX]; 9static char __cwd[PATH_MAX];
10 10
11static int 11static int process_event_stub(event_t *event __used)
12process_event_stub(event_t *event __used,
13 unsigned long offset __used,
14 unsigned long head __used)
15{ 12{
13 dump_printf(": unhandled!\n");
16 return 0; 14 return 0;
17} 15}
18 16
@@ -40,30 +38,62 @@ void register_perf_file_handler(struct perf_file_handler *handler)
40 curr_handler = handler; 38 curr_handler = handler;
41} 39}
42 40
41static const char *event__name[] = {
42 [0] = "TOTAL",
43 [PERF_RECORD_MMAP] = "MMAP",
44 [PERF_RECORD_LOST] = "LOST",
45 [PERF_RECORD_COMM] = "COMM",
46 [PERF_RECORD_EXIT] = "EXIT",
47 [PERF_RECORD_THROTTLE] = "THROTTLE",
48 [PERF_RECORD_UNTHROTTLE] = "UNTHROTTLE",
49 [PERF_RECORD_FORK] = "FORK",
50 [PERF_RECORD_READ] = "READ",
51 [PERF_RECORD_SAMPLE] = "SAMPLE",
52};
53
54unsigned long event__total[PERF_RECORD_MAX];
55
56void event__print_totals(void)
57{
58 int i;
59 for (i = 0; i < PERF_RECORD_MAX; ++i)
60 pr_info("%10s events: %10ld\n",
61 event__name[i], event__total[i]);
62}
63
43static int 64static int
44process_event(event_t *event, unsigned long offset, unsigned long head) 65process_event(event_t *event, unsigned long offset, unsigned long head)
45{ 66{
46 trace_event(event); 67 trace_event(event);
47 68
69 if (event->header.type < PERF_RECORD_MAX) {
70 dump_printf("%p [%p]: PERF_RECORD_%s",
71 (void *)(offset + head),
72 (void *)(long)(event->header.size),
73 event__name[event->header.type]);
74 ++event__total[0];
75 ++event__total[event->header.type];
76 }
77
48 switch (event->header.type) { 78 switch (event->header.type) {
49 case PERF_RECORD_SAMPLE: 79 case PERF_RECORD_SAMPLE:
50 return curr_handler->process_sample_event(event, offset, head); 80 return curr_handler->process_sample_event(event);
51 case PERF_RECORD_MMAP: 81 case PERF_RECORD_MMAP:
52 return curr_handler->process_mmap_event(event, offset, head); 82 return curr_handler->process_mmap_event(event);
53 case PERF_RECORD_COMM: 83 case PERF_RECORD_COMM:
54 return curr_handler->process_comm_event(event, offset, head); 84 return curr_handler->process_comm_event(event);
55 case PERF_RECORD_FORK: 85 case PERF_RECORD_FORK:
56 return curr_handler->process_fork_event(event, offset, head); 86 return curr_handler->process_fork_event(event);
57 case PERF_RECORD_EXIT: 87 case PERF_RECORD_EXIT:
58 return curr_handler->process_exit_event(event, offset, head); 88 return curr_handler->process_exit_event(event);
59 case PERF_RECORD_LOST: 89 case PERF_RECORD_LOST:
60 return curr_handler->process_lost_event(event, offset, head); 90 return curr_handler->process_lost_event(event);
61 case PERF_RECORD_READ: 91 case PERF_RECORD_READ:
62 return curr_handler->process_read_event(event, offset, head); 92 return curr_handler->process_read_event(event);
63 case PERF_RECORD_THROTTLE: 93 case PERF_RECORD_THROTTLE:
64 return curr_handler->process_throttle_event(event, offset, head); 94 return curr_handler->process_throttle_event(event);
65 case PERF_RECORD_UNTHROTTLE: 95 case PERF_RECORD_UNTHROTTLE:
66 return curr_handler->process_unthrottle_event(event, offset, head); 96 return curr_handler->process_unthrottle_event(event);
67 default: 97 default:
68 curr_handler->total_unknown++; 98 curr_handler->total_unknown++;
69 return -1; 99 return -1;
diff --git a/tools/perf/util/data_map.h b/tools/perf/util/data_map.h
index ae036ecd7625..3180ff7e3633 100644
--- a/tools/perf/util/data_map.h
+++ b/tools/perf/util/data_map.h
@@ -4,7 +4,7 @@
4#include "event.h" 4#include "event.h"
5#include "header.h" 5#include "header.h"
6 6
7typedef int (*event_type_handler_t)(event_t *, unsigned long, unsigned long); 7typedef int (*event_type_handler_t)(event_t *);
8 8
9struct perf_file_handler { 9struct perf_file_handler {
10 event_type_handler_t process_sample_event; 10 event_type_handler_t process_sample_event;
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 1dae7e3b400d..70b4aa03b472 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -2,6 +2,7 @@
2#include "event.h" 2#include "event.h"
3#include "debug.h" 3#include "debug.h"
4#include "string.h" 4#include "string.h"
5#include "thread.h"
5 6
6static pid_t event__synthesize_comm(pid_t pid, int full, 7static pid_t event__synthesize_comm(pid_t pid, int full,
7 int (*process)(event_t *event)) 8 int (*process)(event_t *event))
@@ -175,3 +176,76 @@ void event__synthesize_threads(int (*process)(event_t *event))
175 176
176 closedir(proc); 177 closedir(proc);
177} 178}
179
180char *event__cwd;
181int event__cwdlen;
182
183struct events_stats event__stats;
184
185int event__process_comm(event_t *self)
186{
187 struct thread *thread = threads__findnew(self->comm.pid);
188
189 dump_printf("PERF_RECORD_COMM: %s:%d\n",
190 self->comm.comm, self->comm.pid);
191
192 if (thread == NULL || thread__set_comm(thread, self->comm.comm)) {
193 dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
194 return -1;
195 }
196
197 return 0;
198}
199
200int event__process_lost(event_t *self)
201{
202 dump_printf(": id:%Ld: lost:%Ld\n", self->lost.id, self->lost.lost);
203 event__stats.lost += self->lost.lost;
204 return 0;
205}
206
207int event__process_mmap(event_t *self)
208{
209 struct thread *thread = threads__findnew(self->mmap.pid);
210 struct map *map = map__new(&self->mmap, MAP__FUNCTION,
211 event__cwd, event__cwdlen);
212
213 dump_printf(" %d/%d: [%p(%p) @ %p]: %s\n",
214 self->mmap.pid, self->mmap.tid,
215 (void *)(long)self->mmap.start,
216 (void *)(long)self->mmap.len,
217 (void *)(long)self->mmap.pgoff,
218 self->mmap.filename);
219
220 if (thread == NULL || map == NULL)
221 dump_printf("problem processing PERF_RECORD_MMAP, skipping event.\n");
222 else
223 thread__insert_map(thread, map);
224
225 return 0;
226}
227
228int event__process_task(event_t *self)
229{
230 struct thread *thread = threads__findnew(self->fork.pid);
231 struct thread *parent = threads__findnew(self->fork.ppid);
232
233 dump_printf("(%d:%d):(%d:%d)\n", self->fork.pid, self->fork.tid,
234 self->fork.ppid, self->fork.ptid);
235 /*
236 * A thread clone will have the same PID for both parent and child.
237 */
238 if (thread == parent)
239 return 0;
240
241 if (self->header.type == PERF_RECORD_EXIT)
242 return 0;
243
244 if (thread == NULL || parent == NULL ||
245 thread__fork(thread, parent) < 0) {
246 dump_printf("problem processing PERF_RECORD_FORK, skipping event.\n");
247 return -1;
248 }
249
250 return 0;
251}
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 3ae3c964c901..13c12c75f970 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -80,6 +80,13 @@ typedef union event_union {
80 struct sample_event sample; 80 struct sample_event sample;
81} event_t; 81} event_t;
82 82
83struct events_stats {
84 unsigned long total;
85 unsigned long lost;
86};
87
88void event__print_totals(void);
89
83enum map_type { 90enum map_type {
84 MAP__FUNCTION = 0, 91 MAP__FUNCTION = 0,
85 92
@@ -135,4 +142,14 @@ void map__fixup_end(struct map *self);
135int event__synthesize_thread(pid_t pid, int (*process)(event_t *event)); 142int event__synthesize_thread(pid_t pid, int (*process)(event_t *event));
136void event__synthesize_threads(int (*process)(event_t *event)); 143void event__synthesize_threads(int (*process)(event_t *event));
137 144
145extern char *event__cwd;
146extern int event__cwdlen;
147extern struct events_stats event__stats;
148extern unsigned long event__total[PERF_RECORD_MAX];
149
150int event__process_comm(event_t *self);
151int event__process_lost(event_t *self);
152int event__process_mmap(event_t *self);
153int event__process_task(event_t *self);
154
138#endif /* __PERF_RECORD_H */ 155#endif /* __PERF_RECORD_H */
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 7393a02fd8d4..f26cd9ba00fd 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -10,13 +10,6 @@ struct callchain_param callchain_param = {
10 .min_percent = 0.5 10 .min_percent = 0.5
11}; 11};
12 12
13unsigned long total;
14unsigned long total_mmap;
15unsigned long total_comm;
16unsigned long total_fork;
17unsigned long total_unknown;
18unsigned long total_lost;
19
20/* 13/*
21 * histogram, sorted on item, collects counts 14 * histogram, sorted on item, collects counts
22 */ 15 */
diff --git a/tools/perf/util/process_event.c b/tools/perf/util/process_event.c
deleted file mode 100644
index a970789581a2..000000000000
--- a/tools/perf/util/process_event.c
+++ /dev/null
@@ -1,53 +0,0 @@
1#include "process_event.h"
2
3char *cwd;
4int cwdlen;
5
6int
7process_mmap_event(event_t *event, unsigned long offset, unsigned long head)
8{
9 struct map *map = map__new(&event->mmap, cwd, cwdlen);
10 struct thread *thread = threads__findnew(event->mmap.pid);
11
12 dump_printf("%p [%p]: PERF_RECORD_MMAP %d/%d: [%p(%p) @ %p]: %s\n",
13 (void *)(offset + head),
14 (void *)(long)(event->header.size),
15 event->mmap.pid,
16 event->mmap.tid,
17 (void *)(long)event->mmap.start,
18 (void *)(long)event->mmap.len,
19 (void *)(long)event->mmap.pgoff,
20 event->mmap.filename);
21
22 if (thread == NULL || map == NULL) {
23 dump_printf("problem processing PERF_RECORD_MMAP, skipping event.\n");
24 return 0;
25 }
26
27 thread__insert_map(thread, map);
28 total_mmap++;
29
30 return 0;
31
32}
33
34int
35process_comm_event(event_t *event, unsigned long offset, unsigned long head)
36{
37 struct thread *thread = threads__findnew(event->comm.pid);
38
39 dump_printf("%p [%p]: PERF_RECORD_COMM: %s:%d\n",
40 (void *)(offset + head),
41 (void *)(long)(event->header.size),
42 event->comm.comm, event->comm.pid);
43
44 if (thread == NULL ||
45 thread__set_comm_adjust(thread, event->comm.comm)) {
46 dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
47 return -1;
48 }
49 total_comm++;
50
51 return 0;
52}
53
diff --git a/tools/perf/util/process_event.h b/tools/perf/util/process_event.h
deleted file mode 100644
index 6f68c69736cd..000000000000
--- a/tools/perf/util/process_event.h
+++ /dev/null
@@ -1,29 +0,0 @@
1#ifndef __PROCESS_EVENT_H
2#define __PROCESS_EVENT_H
3
4#include "../builtin.h"
5#include "util.h"
6
7#include "color.h"
8#include <linux/list.h>
9#include "cache.h"
10#include <linux/rbtree.h>
11#include "symbol.h"
12#include "string.h"
13
14#include "../perf.h"
15#include "debug.h"
16
17#include "parse-options.h"
18#include "parse-events.h"
19
20#include "thread.h"
21#include "sort.h"
22#include "hist.h"
23
24extern char *cwd;
25extern int cwdlen;
26extern int process_mmap_event(event_t *, unsigned long, unsigned long);
27extern int process_comm_event(event_t *, unsigned long , unsigned long);
28
29#endif /* __PROCESS_H */
diff --git a/tools/perf/util/process_events.c b/tools/perf/util/process_events.c
deleted file mode 100644
index 53778684641c..000000000000
--- a/tools/perf/util/process_events.c
+++ /dev/null
@@ -1,64 +0,0 @@
1#include "process_events.h"
2
3char *cwd;
4int cwdlen;
5
6int
7process_mmap_event(event_t *event, unsigned long offset, unsigned long head)
8{
9 struct map *map = map__new(&event->mmap, MAP__FUNCTION, cwd, cwdlen);
10 struct thread *thread = threads__findnew(event->mmap.pid);
11
12 dump_printf("%p [%p]: PERF_RECORD_MMAP %d/%d: [%p(%p) @ %p]: %s\n",
13 (void *)(offset + head),
14 (void *)(long)(event->header.size),
15 event->mmap.pid,
16 event->mmap.tid,
17 (void *)(long)event->mmap.start,
18 (void *)(long)event->mmap.len,
19 (void *)(long)event->mmap.pgoff,
20 event->mmap.filename);
21
22 if (thread == NULL || map == NULL) {
23 dump_printf("problem processing PERF_RECORD_MMAP, skipping event.\n");
24 return 0;
25 }
26
27 thread__insert_map(thread, map);
28 total_mmap++;
29
30 return 0;
31}
32
33int
34process_task_event(event_t *event, unsigned long offset, unsigned long head)
35{
36 struct thread *thread = threads__findnew(event->fork.pid);
37 struct thread *parent = threads__findnew(event->fork.ppid);
38
39 dump_printf("%p [%p]: PERF_RECORD_%s: (%d:%d):(%d:%d)\n",
40 (void *)(offset + head),
41 (void *)(long)(event->header.size),
42 event->header.type == PERF_RECORD_FORK ? "FORK" : "EXIT",
43 event->fork.pid, event->fork.tid,
44 event->fork.ppid, event->fork.ptid);
45
46 /*
47 * A thread clone will have the same PID for both
48 * parent and child.
49 */
50 if (thread == parent)
51 return 0;
52
53 if (event->header.type == PERF_RECORD_EXIT)
54 return 0;
55
56 if (!thread || !parent || thread__fork(thread, parent)) {
57 dump_printf("problem processing PERF_RECORD_FORK, skipping event.\n");
58 return -1;
59 }
60 total_fork++;
61
62 return 0;
63}
64
diff --git a/tools/perf/util/process_events.h b/tools/perf/util/process_events.h
deleted file mode 100644
index 73d092f83283..000000000000
--- a/tools/perf/util/process_events.h
+++ /dev/null
@@ -1,35 +0,0 @@
1#ifndef __PROCESS_EVENTS_H
2#define __PROCESS_EVENTS_H
3
4#include "../builtin.h"
5
6#include "util.h"
7#include "color.h"
8#include <linux/list.h>
9#include "cache.h"
10#include <linux/rbtree.h>
11#include "symbol.h"
12#include "string.h"
13#include "callchain.h"
14#include "strlist.h"
15#include "values.h"
16
17#include "../perf.h"
18#include "debug.h"
19#include "header.h"
20
21#include "parse-options.h"
22#include "parse-events.h"
23
24#include "data_map.h"
25#include "thread.h"
26#include "sort.h"
27#include "hist.h"
28
29extern char *cwd;
30extern int cwdlen;
31
32extern int process_mmap_event(event_t *, unsigned long , unsigned long);
33extern int process_task_event(event_t *, unsigned long, unsigned long);
34
35#endif /* __PROCESS_EVENTS_H */