aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/builtin-annotate.c6
-rw-r--r--tools/perf/builtin-diff.c11
-rw-r--r--tools/perf/builtin-inject.c39
-rw-r--r--tools/perf/builtin-kmem.c21
-rw-r--r--tools/perf/builtin-lock.c12
-rw-r--r--tools/perf/builtin-record.c7
-rw-r--r--tools/perf/builtin-report.c15
-rw-r--r--tools/perf/builtin-sched.c21
-rw-r--r--tools/perf/builtin-script.c34
-rw-r--r--tools/perf/builtin-timechart.c40
-rw-r--r--tools/perf/builtin-top.c4
-rw-r--r--tools/perf/util/build-id.c7
-rw-r--r--tools/perf/util/event.c66
-rw-r--r--tools/perf/util/event.h20
-rw-r--r--tools/perf/util/header.c11
-rw-r--r--tools/perf/util/hist.h2
-rw-r--r--tools/perf/util/session.c103
-rw-r--r--tools/perf/util/session.h9
18 files changed, 236 insertions, 192 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 6d5604d8df95..569a2761b90a 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -58,12 +58,12 @@ static int hists__add_entry(struct hists *self, struct addr_location *al)
58 return hist_entry__inc_addr_samples(he, al->addr); 58 return hist_entry__inc_addr_samples(he, al->addr);
59} 59}
60 60
61static int process_sample_event(event_t *event, struct perf_session *session) 61static int process_sample_event(event_t *event, struct sample_data *sample,
62 struct perf_session *session)
62{ 63{
63 struct addr_location al; 64 struct addr_location al;
64 struct sample_data data;
65 65
66 if (event__preprocess_sample(event, session, &al, &data, NULL) < 0) { 66 if (event__preprocess_sample(event, session, &al, sample, NULL) < 0) {
67 pr_warning("problem processing %d event, skipping it.\n", 67 pr_warning("problem processing %d event, skipping it.\n",
68 event->header.type); 68 event->header.type);
69 return -1; 69 return -1;
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 221b823bc26f..5e1a043aae03 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -30,12 +30,13 @@ static int hists__add_entry(struct hists *self,
30 return -ENOMEM; 30 return -ENOMEM;
31} 31}
32 32
33static int diff__process_sample_event(event_t *event, struct perf_session *session) 33static int diff__process_sample_event(event_t *event,
34 struct sample_data *sample,
35 struct perf_session *session)
34{ 36{
35 struct addr_location al; 37 struct addr_location al;
36 struct sample_data data = { .period = 1, };
37 38
38 if (event__preprocess_sample(event, session, &al, &data, NULL) < 0) { 39 if (event__preprocess_sample(event, session, &al, sample, NULL) < 0) {
39 pr_warning("problem processing %d event, skipping it.\n", 40 pr_warning("problem processing %d event, skipping it.\n",
40 event->header.type); 41 event->header.type);
41 return -1; 42 return -1;
@@ -44,12 +45,12 @@ static int diff__process_sample_event(event_t *event, struct perf_session *sessi
44 if (al.filtered || al.sym == NULL) 45 if (al.filtered || al.sym == NULL)
45 return 0; 46 return 0;
46 47
47 if (hists__add_entry(&session->hists, &al, data.period)) { 48 if (hists__add_entry(&session->hists, &al, sample->period)) {
48 pr_warning("problem incrementing symbol period, skipping event\n"); 49 pr_warning("problem incrementing symbol period, skipping event\n");
49 return -1; 50 return -1;
50 } 51 }
51 52
52 session->hists.stats.total_period += data.period; 53 session->hists.stats.total_period += sample->period;
53 return 0; 54 return 0;
54} 55}
55 56
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index 8e3e47b064ce..4b66b8579410 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -16,8 +16,8 @@
16static char const *input_name = "-"; 16static char const *input_name = "-";
17static bool inject_build_ids; 17static bool inject_build_ids;
18 18
19static int event__repipe(event_t *event __used, 19static int event__repipe_synth(event_t *event,
20 struct perf_session *session __used) 20 struct perf_session *session __used)
21{ 21{
22 uint32_t size; 22 uint32_t size;
23 void *buf = event; 23 void *buf = event;
@@ -36,22 +36,30 @@ static int event__repipe(event_t *event __used,
36 return 0; 36 return 0;
37} 37}
38 38
39static int event__repipe_mmap(event_t *self, struct perf_session *session) 39static int event__repipe(event_t *event, struct sample_data *sample __used,
40 struct perf_session *session)
41{
42 return event__repipe_synth(event, session);
43}
44
45static int event__repipe_mmap(event_t *self, struct sample_data *sample,
46 struct perf_session *session)
40{ 47{
41 int err; 48 int err;
42 49
43 err = event__process_mmap(self, session); 50 err = event__process_mmap(self, sample, session);
44 event__repipe(self, session); 51 event__repipe(self, sample, session);
45 52
46 return err; 53 return err;
47} 54}
48 55
49static int event__repipe_task(event_t *self, struct perf_session *session) 56static int event__repipe_task(event_t *self, struct sample_data *sample,
57 struct perf_session *session)
50{ 58{
51 int err; 59 int err;
52 60
53 err = event__process_task(self, session); 61 err = event__process_task(self, sample, session);
54 event__repipe(self, session); 62 event__repipe(self, sample, session);
55 63
56 return err; 64 return err;
57} 65}
@@ -61,7 +69,7 @@ static int event__repipe_tracing_data(event_t *self,
61{ 69{
62 int err; 70 int err;
63 71
64 event__repipe(self, session); 72 event__repipe_synth(self, session);
65 err = event__process_tracing_data(self, session); 73 err = event__process_tracing_data(self, session);
66 74
67 return err; 75 return err;
@@ -111,7 +119,8 @@ static int dso__inject_build_id(struct dso *self, struct perf_session *session)
111 return 0; 119 return 0;
112} 120}
113 121
114static int event__inject_buildid(event_t *event, struct perf_session *session) 122static int event__inject_buildid(event_t *event, struct sample_data *sample,
123 struct perf_session *session)
115{ 124{
116 struct addr_location al; 125 struct addr_location al;
117 struct thread *thread; 126 struct thread *thread;
@@ -146,7 +155,7 @@ static int event__inject_buildid(event_t *event, struct perf_session *session)
146 } 155 }
147 156
148repipe: 157repipe:
149 event__repipe(event, session); 158 event__repipe(event, sample, session);
150 return 0; 159 return 0;
151} 160}
152 161
@@ -160,10 +169,10 @@ struct perf_event_ops inject_ops = {
160 .read = event__repipe, 169 .read = event__repipe,
161 .throttle = event__repipe, 170 .throttle = event__repipe,
162 .unthrottle = event__repipe, 171 .unthrottle = event__repipe,
163 .attr = event__repipe, 172 .attr = event__repipe_synth,
164 .event_type = event__repipe, 173 .event_type = event__repipe_synth,
165 .tracing_data = event__repipe, 174 .tracing_data = event__repipe_synth,
166 .build_id = event__repipe, 175 .build_id = event__repipe_synth,
167}; 176};
168 177
169extern volatile int session_done; 178extern volatile int session_done;
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index 31f60a2535e0..d0a652e9c708 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -304,22 +304,11 @@ process_raw_event(event_t *raw_event __used, void *data,
304 } 304 }
305} 305}
306 306
307static int process_sample_event(event_t *event, struct perf_session *session) 307static int process_sample_event(event_t *event, struct sample_data *sample,
308 struct perf_session *session)
308{ 309{
309 struct sample_data data; 310 struct thread *thread = perf_session__findnew(session, event->ip.pid);
310 struct thread *thread;
311 311
312 memset(&data, 0, sizeof(data));
313 data.time = -1;
314 data.cpu = -1;
315 data.period = 1;
316
317 event__parse_sample(event, session->sample_type, &data);
318
319 dump_printf("(IP, %d): %d/%d: %#Lx period: %Ld\n", event->header.misc,
320 data.pid, data.tid, data.ip, data.period);
321
322 thread = perf_session__findnew(session, event->ip.pid);
323 if (thread == NULL) { 312 if (thread == NULL) {
324 pr_debug("problem processing %d event, skipping it.\n", 313 pr_debug("problem processing %d event, skipping it.\n",
325 event->header.type); 314 event->header.type);
@@ -328,8 +317,8 @@ static int process_sample_event(event_t *event, struct perf_session *session)
328 317
329 dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); 318 dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
330 319
331 process_raw_event(event, data.raw_data, data.cpu, 320 process_raw_event(event, sample->raw_data, sample->cpu,
332 data.time, thread); 321 sample->time, thread);
333 322
334 return 0; 323 return 0;
335} 324}
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c
index 8452a2ae2191..92d3da52a5cf 100644
--- a/tools/perf/builtin-lock.c
+++ b/tools/perf/builtin-lock.c
@@ -834,22 +834,18 @@ static void dump_info(void)
834 die("Unknown type of information\n"); 834 die("Unknown type of information\n");
835} 835}
836 836
837static int process_sample_event(event_t *self, struct perf_session *s) 837static int process_sample_event(event_t *self, struct sample_data *sample,
838 struct perf_session *s)
838{ 839{
839 struct sample_data data; 840 struct thread *thread = perf_session__findnew(s, sample->tid);
840 struct thread *thread;
841 841
842 bzero(&data, sizeof(data));
843 event__parse_sample(self, s->sample_type, &data);
844
845 thread = perf_session__findnew(s, data.tid);
846 if (thread == NULL) { 842 if (thread == NULL) {
847 pr_debug("problem processing %d event, skipping it.\n", 843 pr_debug("problem processing %d event, skipping it.\n",
848 self->header.type); 844 self->header.type);
849 return -1; 845 return -1;
850 } 846 }
851 847
852 process_raw_event(data.raw_data, data.cpu, data.time, thread); 848 process_raw_event(sample->raw_data, sample->cpu, sample->time, thread);
853 849
854 return 0; 850 return 0;
855} 851}
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 024e1441d76b..b34de9291c27 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -36,6 +36,7 @@ static int *fd[MAX_NR_CPUS][MAX_COUNTERS];
36 36
37static u64 user_interval = ULLONG_MAX; 37static u64 user_interval = ULLONG_MAX;
38static u64 default_interval = 0; 38static u64 default_interval = 0;
39static u64 sample_type;
39 40
40static int nr_cpus = 0; 41static int nr_cpus = 0;
41static unsigned int page_size; 42static unsigned int page_size;
@@ -129,6 +130,7 @@ static void write_output(void *buf, size_t size)
129} 130}
130 131
131static int process_synthesized_event(event_t *event, 132static int process_synthesized_event(event_t *event,
133 struct sample_data *sample __used,
132 struct perf_session *self __used) 134 struct perf_session *self __used)
133{ 135{
134 write_output(event, event->header.size); 136 write_output(event, event->header.size);
@@ -287,6 +289,9 @@ static void create_counter(int counter, int cpu)
287 attr->sample_type |= PERF_SAMPLE_CPU; 289 attr->sample_type |= PERF_SAMPLE_CPU;
288 } 290 }
289 291
292 if (!sample_type)
293 sample_type = attr->sample_type;
294
290 attr->mmap = track; 295 attr->mmap = track;
291 attr->comm = track; 296 attr->comm = track;
292 attr->inherit = !no_inherit; 297 attr->inherit = !no_inherit;
@@ -642,6 +647,8 @@ static int __cmd_record(int argc, const char **argv)
642 open_counters(cpumap[i]); 647 open_counters(cpumap[i]);
643 } 648 }
644 649
650 perf_session__set_sample_type(session, sample_type);
651
645 if (pipe_output) { 652 if (pipe_output) {
646 err = perf_header__write_pipe(output); 653 err = perf_header__write_pipe(output);
647 if (err < 0) 654 if (err < 0)
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 5de405d45230..904519fba434 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -150,13 +150,13 @@ static int add_event_total(struct perf_session *session,
150 return 0; 150 return 0;
151} 151}
152 152
153static int process_sample_event(event_t *event, struct perf_session *session) 153static int process_sample_event(event_t *event, struct sample_data *sample,
154 struct perf_session *session)
154{ 155{
155 struct sample_data data = { .period = 1, };
156 struct addr_location al; 156 struct addr_location al;
157 struct perf_event_attr *attr; 157 struct perf_event_attr *attr;
158 158
159 if (event__preprocess_sample(event, session, &al, &data, NULL) < 0) { 159 if (event__preprocess_sample(event, session, &al, sample, NULL) < 0) {
160 fprintf(stderr, "problem processing %d event, skipping it.\n", 160 fprintf(stderr, "problem processing %d event, skipping it.\n",
161 event->header.type); 161 event->header.type);
162 return -1; 162 return -1;
@@ -165,14 +165,14 @@ static int process_sample_event(event_t *event, struct perf_session *session)
165 if (al.filtered || (hide_unresolved && al.sym == NULL)) 165 if (al.filtered || (hide_unresolved && al.sym == NULL))
166 return 0; 166 return 0;
167 167
168 if (perf_session__add_hist_entry(session, &al, &data)) { 168 if (perf_session__add_hist_entry(session, &al, sample)) {
169 pr_debug("problem incrementing symbol period, skipping event\n"); 169 pr_debug("problem incrementing symbol period, skipping event\n");
170 return -1; 170 return -1;
171 } 171 }
172 172
173 attr = perf_header__find_attr(data.id, &session->header); 173 attr = perf_header__find_attr(sample->id, &session->header);
174 174
175 if (add_event_total(session, &data, attr)) { 175 if (add_event_total(session, sample, attr)) {
176 pr_debug("problem adding event period\n"); 176 pr_debug("problem adding event period\n");
177 return -1; 177 return -1;
178 } 178 }
@@ -180,7 +180,8 @@ static int process_sample_event(event_t *event, struct perf_session *session)
180 return 0; 180 return 0;
181} 181}
182 182
183static int process_read_event(event_t *event, struct perf_session *session __used) 183static int process_read_event(event_t *event, struct sample_data *sample __used,
184 struct perf_session *session __used)
184{ 185{
185 struct perf_event_attr *attr; 186 struct perf_event_attr *attr;
186 187
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 26523c939791..73d1e30b0fed 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -1606,25 +1606,15 @@ process_raw_event(event_t *raw_event __used, struct perf_session *session,
1606 process_sched_migrate_task_event(data, session, event, cpu, timestamp, thread); 1606 process_sched_migrate_task_event(data, session, event, cpu, timestamp, thread);
1607} 1607}
1608 1608
1609static int process_sample_event(event_t *event, struct perf_session *session) 1609static int process_sample_event(event_t *event, struct sample_data *sample,
1610 struct perf_session *session)
1610{ 1611{
1611 struct sample_data data;
1612 struct thread *thread; 1612 struct thread *thread;
1613 1613
1614 if (!(session->sample_type & PERF_SAMPLE_RAW)) 1614 if (!(session->sample_type & PERF_SAMPLE_RAW))
1615 return 0; 1615 return 0;
1616 1616
1617 memset(&data, 0, sizeof(data)); 1617 thread = perf_session__findnew(session, sample->pid);
1618 data.time = -1;
1619 data.cpu = -1;
1620 data.period = -1;
1621
1622 event__parse_sample(event, session->sample_type, &data);
1623
1624 dump_printf("(IP, %d): %d/%d: %#Lx period: %Ld\n", event->header.misc,
1625 data.pid, data.tid, data.ip, data.period);
1626
1627 thread = perf_session__findnew(session, data.pid);
1628 if (thread == NULL) { 1618 if (thread == NULL) {
1629 pr_debug("problem processing %d event, skipping it.\n", 1619 pr_debug("problem processing %d event, skipping it.\n",
1630 event->header.type); 1620 event->header.type);
@@ -1633,10 +1623,11 @@ static int process_sample_event(event_t *event, struct perf_session *session)
1633 1623
1634 dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); 1624 dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
1635 1625
1636 if (profile_cpu != -1 && profile_cpu != (int)data.cpu) 1626 if (profile_cpu != -1 && profile_cpu != (int)sample->cpu)
1637 return 0; 1627 return 0;
1638 1628
1639 process_raw_event(event, session, data.raw_data, data.cpu, data.time, thread); 1629 process_raw_event(event, session, sample->raw_data, sample->cpu,
1630 sample->time, thread);
1640 1631
1641 return 0; 1632 return 0;
1642} 1633}
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 4539551ab40e..683a30572cc5 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -63,22 +63,11 @@ static int cleanup_scripting(void)
63 63
64static char const *input_name = "perf.data"; 64static char const *input_name = "perf.data";
65 65
66static int process_sample_event(event_t *event, struct perf_session *session) 66static int process_sample_event(event_t *event, struct sample_data *sample,
67 struct perf_session *session)
67{ 68{
68 struct sample_data data; 69 struct thread *thread = perf_session__findnew(session, event->ip.pid);
69 struct thread *thread;
70 70
71 memset(&data, 0, sizeof(data));
72 data.time = -1;
73 data.cpu = -1;
74 data.period = 1;
75
76 event__parse_sample(event, session->sample_type, &data);
77
78 dump_printf("(IP, %d): %d/%d: %#Lx period: %Ld\n", event->header.misc,
79 data.pid, data.tid, data.ip, data.period);
80
81 thread = perf_session__findnew(session, event->ip.pid);
82 if (thread == NULL) { 71 if (thread == NULL) {
83 pr_debug("problem processing %d event, skipping it.\n", 72 pr_debug("problem processing %d event, skipping it.\n",
84 event->header.type); 73 event->header.type);
@@ -87,13 +76,13 @@ static int process_sample_event(event_t *event, struct perf_session *session)
87 76
88 if (session->sample_type & PERF_SAMPLE_RAW) { 77 if (session->sample_type & PERF_SAMPLE_RAW) {
89 if (debug_mode) { 78 if (debug_mode) {
90 if (data.time < last_timestamp) { 79 if (sample->time < last_timestamp) {
91 pr_err("Samples misordered, previous: %llu " 80 pr_err("Samples misordered, previous: %llu "
92 "this: %llu\n", last_timestamp, 81 "this: %llu\n", last_timestamp,
93 data.time); 82 sample->time);
94 nr_unordered++; 83 nr_unordered++;
95 } 84 }
96 last_timestamp = data.time; 85 last_timestamp = sample->time;
97 return 0; 86 return 0;
98 } 87 }
99 /* 88 /*
@@ -101,18 +90,19 @@ static int process_sample_event(event_t *event, struct perf_session *session)
101 * field, although it should be the same than this perf 90 * field, although it should be the same than this perf
102 * event pid 91 * event pid
103 */ 92 */
104 scripting_ops->process_event(data.cpu, data.raw_data, 93 scripting_ops->process_event(sample->cpu, sample->raw_data,
105 data.raw_size, 94 sample->raw_size,
106 data.time, thread->comm); 95 sample->time, thread->comm);
107 } 96 }
108 97
109 session->hists.stats.total_period += data.period; 98 session->hists.stats.total_period += sample->period;
110 return 0; 99 return 0;
111} 100}
112 101
113static u64 nr_lost; 102static u64 nr_lost;
114 103
115static int process_lost_event(event_t *event, struct perf_session *session __used) 104static int process_lost_event(event_t *event, struct sample_data *sample __used,
105 struct perf_session *session __used)
116{ 106{
117 nr_lost += event->lost.lost; 107 nr_lost += event->lost.lost;
118 108
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index 9bcc38f0b706..1f158dc03349 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -272,19 +272,22 @@ static int cpus_cstate_state[MAX_CPUS];
272static u64 cpus_pstate_start_times[MAX_CPUS]; 272static u64 cpus_pstate_start_times[MAX_CPUS];
273static u64 cpus_pstate_state[MAX_CPUS]; 273static u64 cpus_pstate_state[MAX_CPUS];
274 274
275static int process_comm_event(event_t *event, struct perf_session *session __used) 275static int process_comm_event(event_t *event, struct sample_data *sample __used,
276 struct perf_session *session __used)
276{ 277{
277 pid_set_comm(event->comm.tid, event->comm.comm); 278 pid_set_comm(event->comm.tid, event->comm.comm);
278 return 0; 279 return 0;
279} 280}
280 281
281static int process_fork_event(event_t *event, struct perf_session *session __used) 282static int process_fork_event(event_t *event, struct sample_data *sample __used,
283 struct perf_session *session __used)
282{ 284{
283 pid_fork(event->fork.pid, event->fork.ppid, event->fork.time); 285 pid_fork(event->fork.pid, event->fork.ppid, event->fork.time);
284 return 0; 286 return 0;
285} 287}
286 288
287static int process_exit_event(event_t *event, struct perf_session *session __used) 289static int process_exit_event(event_t *event, struct sample_data *sample __used,
290 struct perf_session *session __used)
288{ 291{
289 pid_exit(event->fork.pid, event->fork.time); 292 pid_exit(event->fork.pid, event->fork.time);
290 return 0; 293 return 0;
@@ -470,24 +473,21 @@ static void sched_switch(int cpu, u64 timestamp, struct trace_entry *te)
470} 473}
471 474
472 475
473static int process_sample_event(event_t *event, struct perf_session *session) 476static int process_sample_event(event_t *event __used,
477 struct sample_data *sample,
478 struct perf_session *session)
474{ 479{
475 struct sample_data data;
476 struct trace_entry *te; 480 struct trace_entry *te;
477 481
478 memset(&data, 0, sizeof(data));
479
480 event__parse_sample(event, session->sample_type, &data);
481
482 if (session->sample_type & PERF_SAMPLE_TIME) { 482 if (session->sample_type & PERF_SAMPLE_TIME) {
483 if (!first_time || first_time > data.time) 483 if (!first_time || first_time > sample->time)
484 first_time = data.time; 484 first_time = sample->time;
485 if (last_time < data.time) 485 if (last_time < sample->time)
486 last_time = data.time; 486 last_time = sample->time;
487 } 487 }
488 488
489 te = (void *)data.raw_data; 489 te = (void *)sample->raw_data;
490 if (session->sample_type & PERF_SAMPLE_RAW && data.raw_size > 0) { 490 if (session->sample_type & PERF_SAMPLE_RAW && sample->raw_size > 0) {
491 char *event_str; 491 char *event_str;
492 struct power_entry *pe; 492 struct power_entry *pe;
493 493
@@ -499,19 +499,19 @@ static int process_sample_event(event_t *event, struct perf_session *session)
499 return 0; 499 return 0;
500 500
501 if (strcmp(event_str, "power:power_start") == 0) 501 if (strcmp(event_str, "power:power_start") == 0)
502 c_state_start(pe->cpu_id, data.time, pe->value); 502 c_state_start(pe->cpu_id, sample->time, pe->value);
503 503
504 if (strcmp(event_str, "power:power_end") == 0) 504 if (strcmp(event_str, "power:power_end") == 0)
505 c_state_end(pe->cpu_id, data.time); 505 c_state_end(pe->cpu_id, sample->time);
506 506
507 if (strcmp(event_str, "power:power_frequency") == 0) 507 if (strcmp(event_str, "power:power_frequency") == 0)
508 p_state_change(pe->cpu_id, data.time, pe->value); 508 p_state_change(pe->cpu_id, sample->time, pe->value);
509 509
510 if (strcmp(event_str, "sched:sched_wakeup") == 0) 510 if (strcmp(event_str, "sched:sched_wakeup") == 0)
511 sched_wakeup(data.cpu, data.time, data.pid, te); 511 sched_wakeup(sample->cpu, sample->time, sample->pid, te);
512 512
513 if (strcmp(event_str, "sched:sched_switch") == 0) 513 if (strcmp(event_str, "sched:sched_switch") == 0)
514 sched_switch(data.cpu, data.time, te); 514 sched_switch(sample->cpu, sample->time, te);
515 } 515 }
516 return 0; 516 return 0;
517} 517}
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 3d2b47d5121a..5aa29e1e855a 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -1025,6 +1025,8 @@ static void event__process_sample(const event_t *self,
1025 if (self->header.misc & PERF_RECORD_MISC_EXACT_IP) 1025 if (self->header.misc & PERF_RECORD_MISC_EXACT_IP)
1026 exact_samples++; 1026 exact_samples++;
1027 1027
1028 event__parse_sample(self, session->sample_type, &data);
1029
1028 if (event__preprocess_sample(self, session, &al, &data, 1030 if (event__preprocess_sample(self, session, &al, &data,
1029 symbol_filter) < 0 || 1031 symbol_filter) < 0 ||
1030 al.filtered) 1032 al.filtered)
@@ -1155,7 +1157,7 @@ static void perf_session__mmap_read_counter(struct perf_session *self,
1155 if (event->header.type == PERF_RECORD_SAMPLE) 1157 if (event->header.type == PERF_RECORD_SAMPLE)
1156 event__process_sample(event, self, md->counter); 1158 event__process_sample(event, self, md->counter);
1157 else 1159 else
1158 event__process(event, self); 1160 event__process(event, NULL, self);
1159 old += size; 1161 old += size;
1160 } 1162 }
1161 1163
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index e437edb72417..deffb8c96071 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -14,7 +14,9 @@
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include "debug.h" 15#include "debug.h"
16 16
17static int build_id__mark_dso_hit(event_t *event, struct perf_session *session) 17static int build_id__mark_dso_hit(event_t *event,
18 struct sample_data *sample __used,
19 struct perf_session *session)
18{ 20{
19 struct addr_location al; 21 struct addr_location al;
20 u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 22 u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
@@ -35,7 +37,8 @@ static int build_id__mark_dso_hit(event_t *event, struct perf_session *session)
35 return 0; 37 return 0;
36} 38}
37 39
38static int event__exit_del_thread(event_t *self, struct perf_session *session) 40static int event__exit_del_thread(event_t *self, struct sample_data *sample __used,
41 struct perf_session *session)
39{ 42{
40 struct thread *thread = perf_session__findnew(session, self->fork.tid); 43 struct thread *thread = perf_session__findnew(session, self->fork.tid);
41 44
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 7260db75b93d..34510f441975 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -24,6 +24,15 @@ const char *event__name[] = {
24 [PERF_RECORD_HEADER_BUILD_ID] = "BUILD_ID", 24 [PERF_RECORD_HEADER_BUILD_ID] = "BUILD_ID",
25}; 25};
26 26
27static struct sample_data synth_sample = {
28 .pid = -1,
29 .tid = -1,
30 .time = -1,
31 .stream_id = -1,
32 .cpu = -1,
33 .period = 1,
34};
35
27static pid_t event__synthesize_comm(pid_t pid, int full, 36static pid_t event__synthesize_comm(pid_t pid, int full,
28 event__handler_t process, 37 event__handler_t process,
29 struct perf_session *session) 38 struct perf_session *session)
@@ -75,7 +84,7 @@ out_race:
75 if (!full) { 84 if (!full) {
76 ev.comm.tid = pid; 85 ev.comm.tid = pid;
77 86
78 process(&ev, session); 87 process(&ev, &synth_sample, session);
79 goto out_fclose; 88 goto out_fclose;
80 } 89 }
81 90
@@ -93,7 +102,7 @@ out_race:
93 102
94 ev.comm.tid = pid; 103 ev.comm.tid = pid;
95 104
96 process(&ev, session); 105 process(&ev, &synth_sample, session);
97 } 106 }
98 closedir(tasks); 107 closedir(tasks);
99 108
@@ -173,7 +182,7 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid,
173 ev.mmap.pid = tgid; 182 ev.mmap.pid = tgid;
174 ev.mmap.tid = pid; 183 ev.mmap.tid = pid;
175 184
176 process(&ev, session); 185 process(&ev, &synth_sample, session);
177 } 186 }
178 } 187 }
179 188
@@ -219,7 +228,7 @@ int event__synthesize_modules(event__handler_t process,
219 228
220 memcpy(ev.mmap.filename, pos->dso->long_name, 229 memcpy(ev.mmap.filename, pos->dso->long_name,
221 pos->dso->long_name_len + 1); 230 pos->dso->long_name_len + 1);
222 process(&ev, session); 231 process(&ev, &synth_sample, session);
223 } 232 }
224 233
225 return 0; 234 return 0;
@@ -331,7 +340,7 @@ int event__synthesize_kernel_mmap(event__handler_t process,
331 ev.mmap.len = map->end - ev.mmap.start; 340 ev.mmap.len = map->end - ev.mmap.start;
332 ev.mmap.pid = machine->pid; 341 ev.mmap.pid = machine->pid;
333 342
334 return process(&ev, session); 343 return process(&ev, &synth_sample, session);
335} 344}
336 345
337static void thread__comm_adjust(struct thread *self, struct hists *hists) 346static void thread__comm_adjust(struct thread *self, struct hists *hists)
@@ -361,7 +370,8 @@ static int thread__set_comm_adjust(struct thread *self, const char *comm,
361 return 0; 370 return 0;
362} 371}
363 372
364int event__process_comm(event_t *self, struct perf_session *session) 373int event__process_comm(event_t *self, struct sample_data *sample __used,
374 struct perf_session *session)
365{ 375{
366 struct thread *thread = perf_session__findnew(session, self->comm.tid); 376 struct thread *thread = perf_session__findnew(session, self->comm.tid);
367 377
@@ -376,7 +386,8 @@ int event__process_comm(event_t *self, struct perf_session *session)
376 return 0; 386 return 0;
377} 387}
378 388
379int event__process_lost(event_t *self, struct perf_session *session) 389int event__process_lost(event_t *self, struct sample_data *sample __used,
390 struct perf_session *session)
380{ 391{
381 dump_printf(": id:%Ld: lost:%Ld\n", self->lost.id, self->lost.lost); 392 dump_printf(": id:%Ld: lost:%Ld\n", self->lost.id, self->lost.lost);
382 session->hists.stats.total_lost += self->lost.lost; 393 session->hists.stats.total_lost += self->lost.lost;
@@ -485,7 +496,8 @@ out_problem:
485 return -1; 496 return -1;
486} 497}
487 498
488int event__process_mmap(event_t *self, struct perf_session *session) 499int event__process_mmap(event_t *self, struct sample_data *sample __used,
500 struct perf_session *session)
489{ 501{
490 struct machine *machine; 502 struct machine *machine;
491 struct thread *thread; 503 struct thread *thread;
@@ -526,7 +538,8 @@ out_problem:
526 return 0; 538 return 0;
527} 539}
528 540
529int event__process_task(event_t *self, struct perf_session *session) 541int event__process_task(event_t *self, struct sample_data *sample __used,
542 struct perf_session *session)
530{ 543{
531 struct thread *thread = perf_session__findnew(session, self->fork.tid); 544 struct thread *thread = perf_session__findnew(session, self->fork.tid);
532 struct thread *parent = perf_session__findnew(session, self->fork.ptid); 545 struct thread *parent = perf_session__findnew(session, self->fork.ptid);
@@ -548,18 +561,19 @@ int event__process_task(event_t *self, struct perf_session *session)
548 return 0; 561 return 0;
549} 562}
550 563
551int event__process(event_t *event, struct perf_session *session) 564int event__process(event_t *event, struct sample_data *sample,
565 struct perf_session *session)
552{ 566{
553 switch (event->header.type) { 567 switch (event->header.type) {
554 case PERF_RECORD_COMM: 568 case PERF_RECORD_COMM:
555 event__process_comm(event, session); 569 event__process_comm(event, sample, session);
556 break; 570 break;
557 case PERF_RECORD_MMAP: 571 case PERF_RECORD_MMAP:
558 event__process_mmap(event, session); 572 event__process_mmap(event, sample, session);
559 break; 573 break;
560 case PERF_RECORD_FORK: 574 case PERF_RECORD_FORK:
561 case PERF_RECORD_EXIT: 575 case PERF_RECORD_EXIT:
562 event__process_task(event, session); 576 event__process_task(event, sample, session);
563 break; 577 break;
564 default: 578 default:
565 break; 579 break;
@@ -674,32 +688,8 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session,
674 symbol_filter_t filter) 688 symbol_filter_t filter)
675{ 689{
676 u8 cpumode = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 690 u8 cpumode = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
677 struct thread *thread; 691 struct thread *thread = perf_session__findnew(session, self->ip.pid);
678
679 event__parse_sample(self, session->sample_type, data);
680 692
681 dump_printf("(IP, %d): %d/%d: %#Lx period: %Ld cpu:%d\n",
682 self->header.misc, data->pid, data->tid, data->ip,
683 data->period, data->cpu);
684
685 if (session->sample_type & PERF_SAMPLE_CALLCHAIN) {
686 unsigned int i;
687
688 dump_printf("... chain: nr:%Lu\n", data->callchain->nr);
689
690 if (!ip_callchain__valid(data->callchain, self)) {
691 pr_debug("call-chain problem with event, "
692 "skipping it.\n");
693 goto out_filtered;
694 }
695
696 if (dump_trace) {
697 for (i = 0; i < data->callchain->nr; i++)
698 dump_printf("..... %2d: %016Lx\n",
699 i, data->callchain->ips[i]);
700 }
701 }
702 thread = perf_session__findnew(session, self->ip.pid);
703 if (thread == NULL) 693 if (thread == NULL)
704 return -1; 694 return -1;
705 695
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 8e790dae7026..08c400b83d57 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -135,7 +135,10 @@ void event__print_totals(void);
135 135
136struct perf_session; 136struct perf_session;
137 137
138typedef int (*event__handler_t)(event_t *event, struct perf_session *session); 138typedef int (*event__handler_synth_t)(event_t *event,
139 struct perf_session *session);
140typedef int (*event__handler_t)(event_t *event, struct sample_data *sample,
141 struct perf_session *session);
139 142
140int event__synthesize_thread(pid_t pid, event__handler_t process, 143int event__synthesize_thread(pid_t pid, event__handler_t process,
141 struct perf_session *session); 144 struct perf_session *session);
@@ -150,11 +153,16 @@ int event__synthesize_modules(event__handler_t process,
150 struct perf_session *session, 153 struct perf_session *session,
151 struct machine *machine); 154 struct machine *machine);
152 155
153int event__process_comm(event_t *self, struct perf_session *session); 156int event__process_comm(event_t *self, struct sample_data *sample,
154int event__process_lost(event_t *self, struct perf_session *session); 157 struct perf_session *session);
155int event__process_mmap(event_t *self, struct perf_session *session); 158int event__process_lost(event_t *self, struct sample_data *sample,
156int event__process_task(event_t *self, struct perf_session *session); 159 struct perf_session *session);
157int event__process(event_t *event, struct perf_session *session); 160int event__process_mmap(event_t *self, struct sample_data *sample,
161 struct perf_session *session);
162int event__process_task(event_t *self, struct sample_data *sample,
163 struct perf_session *session);
164int event__process(event_t *event, struct sample_data *sample,
165 struct perf_session *session);
158 166
159struct addr_location; 167struct addr_location;
160int event__preprocess_sample(const event_t *self, struct perf_session *session, 168int event__preprocess_sample(const event_t *self, struct perf_session *session,
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index f65d7dc127b6..fe652f3b0aa7 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -993,15 +993,14 @@ int event__synthesize_attr(struct perf_event_attr *attr, u16 ids, u64 *id,
993 ev->attr.header.type = PERF_RECORD_HEADER_ATTR; 993 ev->attr.header.type = PERF_RECORD_HEADER_ATTR;
994 ev->attr.header.size = size; 994 ev->attr.header.size = size;
995 995
996 err = process(ev, session); 996 err = process(ev, NULL, session);
997 997
998 free(ev); 998 free(ev);
999 999
1000 return err; 1000 return err;
1001} 1001}
1002 1002
1003int event__synthesize_attrs(struct perf_header *self, 1003int event__synthesize_attrs(struct perf_header *self, event__handler_t process,
1004 event__handler_t process,
1005 struct perf_session *session) 1004 struct perf_session *session)
1006{ 1005{
1007 struct perf_header_attr *attr; 1006 struct perf_header_attr *attr;
@@ -1071,7 +1070,7 @@ int event__synthesize_event_type(u64 event_id, char *name,
1071 ev.event_type.header.size = sizeof(ev.event_type) - 1070 ev.event_type.header.size = sizeof(ev.event_type) -
1072 (sizeof(ev.event_type.event_type.name) - size); 1071 (sizeof(ev.event_type.event_type.name) - size);
1073 1072
1074 err = process(&ev, session); 1073 err = process(&ev, NULL, session);
1075 1074
1076 return err; 1075 return err;
1077} 1076}
@@ -1126,7 +1125,7 @@ int event__synthesize_tracing_data(int fd, struct perf_event_attr *pattrs,
1126 ev.tracing_data.header.size = sizeof(ev.tracing_data); 1125 ev.tracing_data.header.size = sizeof(ev.tracing_data);
1127 ev.tracing_data.size = aligned_size; 1126 ev.tracing_data.size = aligned_size;
1128 1127
1129 process(&ev, session); 1128 process(&ev, NULL, session);
1130 1129
1131 err = read_tracing_data(fd, pattrs, nb_events); 1130 err = read_tracing_data(fd, pattrs, nb_events);
1132 write_padded(fd, NULL, 0, padding); 1131 write_padded(fd, NULL, 0, padding);
@@ -1186,7 +1185,7 @@ int event__synthesize_build_id(struct dso *pos, u16 misc,
1186 ev.build_id.header.size = sizeof(ev.build_id) + len; 1185 ev.build_id.header.size = sizeof(ev.build_id) + len;
1187 memcpy(&ev.build_id.filename, pos->long_name, pos->long_name_len); 1186 memcpy(&ev.build_id.filename, pos->long_name, pos->long_name_len);
1188 1187
1189 err = process(&ev, session); 1188 err = process(&ev, NULL, session);
1190 1189
1191 return err; 1190 return err;
1192} 1191}
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 587d375d3430..ee789856a8c9 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -52,8 +52,10 @@ struct sym_priv {
52struct events_stats { 52struct events_stats {
53 u64 total_period; 53 u64 total_period;
54 u64 total_lost; 54 u64 total_lost;
55 u64 total_invalid_chains;
55 u32 nr_events[PERF_RECORD_HEADER_MAX]; 56 u32 nr_events[PERF_RECORD_HEADER_MAX];
56 u32 nr_unknown_events; 57 u32 nr_unknown_events;
58 u32 nr_invalid_chains;
57}; 59};
58 60
59enum hist_column { 61enum hist_column {
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 52672dad1fe9..08ec018966a8 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -70,6 +70,11 @@ void perf_session__update_sample_type(struct perf_session *self)
70 self->sample_type = perf_header__sample_type(&self->header); 70 self->sample_type = perf_header__sample_type(&self->header);
71} 71}
72 72
73void perf_session__set_sample_type(struct perf_session *session, u64 type)
74{
75 session->sample_type = type;
76}
77
73int perf_session__create_kernel_maps(struct perf_session *self) 78int perf_session__create_kernel_maps(struct perf_session *self)
74{ 79{
75 int ret = machine__create_kernel_maps(&self->host_machine); 80 int ret = machine__create_kernel_maps(&self->host_machine);
@@ -240,7 +245,15 @@ struct map_symbol *perf_session__resolve_callchain(struct perf_session *self,
240 return syms; 245 return syms;
241} 246}
242 247
248static int process_event_synth_stub(event_t *event __used,
249 struct perf_session *session __used)
250{
251 dump_printf(": unhandled!\n");
252 return 0;
253}
254
243static int process_event_stub(event_t *event __used, 255static int process_event_stub(event_t *event __used,
256 struct sample_data *sample __used,
244 struct perf_session *session __used) 257 struct perf_session *session __used)
245{ 258{
246 dump_printf(": unhandled!\n"); 259 dump_printf(": unhandled!\n");
@@ -280,13 +293,13 @@ static void perf_event_ops__fill_defaults(struct perf_event_ops *handler)
280 if (handler->unthrottle == NULL) 293 if (handler->unthrottle == NULL)
281 handler->unthrottle = process_event_stub; 294 handler->unthrottle = process_event_stub;
282 if (handler->attr == NULL) 295 if (handler->attr == NULL)
283 handler->attr = process_event_stub; 296 handler->attr = process_event_synth_stub;
284 if (handler->event_type == NULL) 297 if (handler->event_type == NULL)
285 handler->event_type = process_event_stub; 298 handler->event_type = process_event_synth_stub;
286 if (handler->tracing_data == NULL) 299 if (handler->tracing_data == NULL)
287 handler->tracing_data = process_event_stub; 300 handler->tracing_data = process_event_synth_stub;
288 if (handler->build_id == NULL) 301 if (handler->build_id == NULL)
289 handler->build_id = process_event_stub; 302 handler->build_id = process_event_synth_stub;
290 if (handler->finished_round == NULL) { 303 if (handler->finished_round == NULL) {
291 if (handler->ordered_samples) 304 if (handler->ordered_samples)
292 handler->finished_round = process_finished_round; 305 handler->finished_round = process_finished_round;
@@ -419,6 +432,7 @@ static void flush_sample_queue(struct perf_session *s,
419 struct ordered_samples *os = &s->ordered_samples; 432 struct ordered_samples *os = &s->ordered_samples;
420 struct list_head *head = &os->samples; 433 struct list_head *head = &os->samples;
421 struct sample_queue *tmp, *iter; 434 struct sample_queue *tmp, *iter;
435 struct sample_data sample;
422 u64 limit = os->next_flush; 436 u64 limit = os->next_flush;
423 u64 last_ts = os->last_sample ? os->last_sample->timestamp : 0ULL; 437 u64 last_ts = os->last_sample ? os->last_sample->timestamp : 0ULL;
424 438
@@ -429,7 +443,8 @@ static void flush_sample_queue(struct perf_session *s,
429 if (iter->timestamp > limit) 443 if (iter->timestamp > limit)
430 break; 444 break;
431 445
432 ops->sample(iter->event, s); 446 event__parse_sample(iter->event, s->sample_type, &sample);
447 ops->sample(iter->event, &sample, s);
433 448
434 os->last_flush = iter->timestamp; 449 os->last_flush = iter->timestamp;
435 list_del(&iter->list); 450 list_del(&iter->list);
@@ -578,20 +593,29 @@ static int queue_sample_event(event_t *event, struct sample_data *data,
578 return 0; 593 return 0;
579} 594}
580 595
581static int perf_session__process_sample(event_t *event, struct perf_session *s, 596static int perf_session__process_sample(event_t *event,
597 struct sample_data *sample,
598 struct perf_session *s,
582 struct perf_event_ops *ops) 599 struct perf_event_ops *ops)
583{ 600{
584 struct sample_data data;
585
586 if (!ops->ordered_samples) 601 if (!ops->ordered_samples)
587 return ops->sample(event, s); 602 return ops->sample(event, sample, s);
603
604 queue_sample_event(event, sample, s);
605 return 0;
606}
588 607
589 bzero(&data, sizeof(struct sample_data)); 608static void callchain__dump(struct sample_data *sample)
590 event__parse_sample(event, s->sample_type, &data); 609{
610 unsigned int i;
591 611
592 queue_sample_event(event, &data, s); 612 if (!dump_trace)
613 return;
593 614
594 return 0; 615 printf("... chain: nr:%Lu\n", sample->callchain->nr);
616
617 for (i = 0; i < sample->callchain->nr; i++)
618 printf("..... %2d: %016Lx\n", i, sample->callchain->ips[i]);
595} 619}
596 620
597static int perf_session__process_event(struct perf_session *self, 621static int perf_session__process_event(struct perf_session *self,
@@ -599,8 +623,16 @@ static int perf_session__process_event(struct perf_session *self,
599 struct perf_event_ops *ops, 623 struct perf_event_ops *ops,
600 u64 file_offset) 624 u64 file_offset)
601{ 625{
626 struct sample_data sample;
627
602 trace_event(event); 628 trace_event(event);
603 629
630 if (self->header.needs_swap && event__swap_ops[event->header.type])
631 event__swap_ops[event->header.type](event);
632
633 if (event->header.type == PERF_RECORD_SAMPLE)
634 event__parse_sample(event, self->sample_type, &sample);
635
604 if (event->header.type < PERF_RECORD_HEADER_MAX) { 636 if (event->header.type < PERF_RECORD_HEADER_MAX) {
605 dump_printf("%#Lx [%#x]: PERF_RECORD_%s", 637 dump_printf("%#Lx [%#x]: PERF_RECORD_%s",
606 file_offset, event->header.size, 638 file_offset, event->header.size,
@@ -608,28 +640,41 @@ static int perf_session__process_event(struct perf_session *self,
608 hists__inc_nr_events(&self->hists, event->header.type); 640 hists__inc_nr_events(&self->hists, event->header.type);
609 } 641 }
610 642
611 if (self->header.needs_swap && event__swap_ops[event->header.type])
612 event__swap_ops[event->header.type](event);
613
614 switch (event->header.type) { 643 switch (event->header.type) {
615 case PERF_RECORD_SAMPLE: 644 case PERF_RECORD_SAMPLE:
616 return perf_session__process_sample(event, self, ops); 645 dump_printf("(IP, %d): %d/%d: %#Lx period: %Ld\n", event->header.misc,
646 sample.pid, sample.tid, sample.ip, sample.period);
647
648 if (self->sample_type & PERF_SAMPLE_CALLCHAIN) {
649 if (!ip_callchain__valid(sample.callchain, event)) {
650 pr_debug("call-chain problem with event, "
651 "skipping it.\n");
652 ++self->hists.stats.nr_invalid_chains;
653 self->hists.stats.total_invalid_chains += sample.period;
654 return 0;
655 }
656
657 callchain__dump(&sample);
658 }
659
660 return perf_session__process_sample(event, &sample, self, ops);
661
617 case PERF_RECORD_MMAP: 662 case PERF_RECORD_MMAP:
618 return ops->mmap(event, self); 663 return ops->mmap(event, &sample, self);
619 case PERF_RECORD_COMM: 664 case PERF_RECORD_COMM:
620 return ops->comm(event, self); 665 return ops->comm(event, &sample, self);
621 case PERF_RECORD_FORK: 666 case PERF_RECORD_FORK:
622 return ops->fork(event, self); 667 return ops->fork(event, &sample, self);
623 case PERF_RECORD_EXIT: 668 case PERF_RECORD_EXIT:
624 return ops->exit(event, self); 669 return ops->exit(event, &sample, self);
625 case PERF_RECORD_LOST: 670 case PERF_RECORD_LOST:
626 return ops->lost(event, self); 671 return ops->lost(event, &sample, self);
627 case PERF_RECORD_READ: 672 case PERF_RECORD_READ:
628 return ops->read(event, self); 673 return ops->read(event, &sample, self);
629 case PERF_RECORD_THROTTLE: 674 case PERF_RECORD_THROTTLE:
630 return ops->throttle(event, self); 675 return ops->throttle(event, &sample, self);
631 case PERF_RECORD_UNTHROTTLE: 676 case PERF_RECORD_UNTHROTTLE:
632 return ops->unthrottle(event, self); 677 return ops->unthrottle(event, &sample, self);
633 case PERF_RECORD_HEADER_ATTR: 678 case PERF_RECORD_HEADER_ATTR:
634 return ops->attr(event, self); 679 return ops->attr(event, self);
635 case PERF_RECORD_HEADER_EVENT_TYPE: 680 case PERF_RECORD_HEADER_EVENT_TYPE:
@@ -894,6 +939,14 @@ out_err:
894 session->hists.stats.nr_unknown_events); 939 session->hists.stats.nr_unknown_events);
895 } 940 }
896 941
942 if (session->hists.stats.nr_invalid_chains != 0) {
943 ui__warning("Found invalid callchains!\n\n"
944 "%u out of %u events were discarded for this reason.\n\n"
945 "Consider reporting to linux-kernel@vger.kernel.org.\n\n",
946 session->hists.stats.nr_invalid_chains,
947 session->hists.stats.nr_events[PERF_RECORD_SAMPLE]);
948 }
949
897 perf_session_free_sample_buffers(session); 950 perf_session_free_sample_buffers(session);
898 return err; 951 return err;
899} 952}
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 5bf6efa3788a..4578f86a6209 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -54,7 +54,9 @@ struct perf_session {
54 54
55struct perf_event_ops; 55struct perf_event_ops;
56 56
57typedef int (*event_op)(event_t *self, struct perf_session *session); 57typedef int (*event_op)(event_t *self, struct sample_data *sample,
58 struct perf_session *session);
59typedef int (*event_synth_op)(event_t *self, struct perf_session *session);
58typedef int (*event_op2)(event_t *self, struct perf_session *session, 60typedef int (*event_op2)(event_t *self, struct perf_session *session,
59 struct perf_event_ops *ops); 61 struct perf_event_ops *ops);
60 62
@@ -67,8 +69,8 @@ struct perf_event_ops {
67 lost, 69 lost,
68 read, 70 read,
69 throttle, 71 throttle,
70 unthrottle, 72 unthrottle;
71 attr, 73 event_synth_op attr,
72 event_type, 74 event_type,
73 tracing_data, 75 tracing_data,
74 build_id; 76 build_id;
@@ -104,6 +106,7 @@ int perf_session__create_kernel_maps(struct perf_session *self);
104 106
105int do_read(int fd, void *buf, size_t size); 107int do_read(int fd, void *buf, size_t size);
106void perf_session__update_sample_type(struct perf_session *self); 108void perf_session__update_sample_type(struct perf_session *self);
109void perf_session__set_sample_type(struct perf_session *session, u64 type);
107void perf_session__remove_thread(struct perf_session *self, struct thread *th); 110void perf_session__remove_thread(struct perf_session *self, struct thread *th);
108 111
109static inline 112static inline