aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util')
-rw-r--r--tools/perf/util/build-id.c16
-rw-r--r--tools/perf/util/event.c151
-rw-r--r--tools/perf/util/event.h21
-rw-r--r--tools/perf/util/header.c28
-rw-r--r--tools/perf/util/header.h16
-rw-r--r--tools/perf/util/map.h10
-rw-r--r--tools/perf/util/scripting-engines/trace-event-perl.c4
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c4
-rw-r--r--tools/perf/util/session.c91
-rw-r--r--tools/perf/util/session.h30
-rw-r--r--tools/perf/util/thread.h14
-rw-r--r--tools/perf/util/trace-event-scripting.c2
-rw-r--r--tools/perf/util/trace-event.h8
13 files changed, 195 insertions, 200 deletions
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index 0e4de1865013..2f84c4802aca 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -19,11 +19,11 @@ static int build_id__mark_dso_hit(struct perf_event_ops *ops __used,
19 union perf_event *event, 19 union perf_event *event,
20 struct perf_sample *sample __used, 20 struct perf_sample *sample __used,
21 struct perf_evsel *evsel __used, 21 struct perf_evsel *evsel __used,
22 struct perf_session *session) 22 struct machine *machine)
23{ 23{
24 struct addr_location al; 24 struct addr_location al;
25 u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 25 u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
26 struct thread *thread = perf_session__findnew(session, event->ip.pid); 26 struct thread *thread = machine__findnew_thread(machine, event->ip.pid);
27 27
28 if (thread == NULL) { 28 if (thread == NULL) {
29 pr_err("problem processing %d event, skipping it.\n", 29 pr_err("problem processing %d event, skipping it.\n",
@@ -31,8 +31,8 @@ static int build_id__mark_dso_hit(struct perf_event_ops *ops __used,
31 return -1; 31 return -1;
32 } 32 }
33 33
34 thread__find_addr_map(thread, session, cpumode, MAP__FUNCTION, 34 thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION,
35 event->ip.pid, event->ip.ip, &al); 35 event->ip.ip, &al);
36 36
37 if (al.map != NULL) 37 if (al.map != NULL)
38 al.map->dso->hit = 1; 38 al.map->dso->hit = 1;
@@ -43,16 +43,16 @@ static int build_id__mark_dso_hit(struct perf_event_ops *ops __used,
43static int perf_event__exit_del_thread(struct perf_event_ops *ops __used, 43static int perf_event__exit_del_thread(struct perf_event_ops *ops __used,
44 union perf_event *event, 44 union perf_event *event,
45 struct perf_sample *sample __used, 45 struct perf_sample *sample __used,
46 struct perf_session *session) 46 struct machine *machine)
47{ 47{
48 struct thread *thread = perf_session__findnew(session, event->fork.tid); 48 struct thread *thread = machine__findnew_thread(machine, event->fork.tid);
49 49
50 dump_printf("(%d:%d):(%d:%d)\n", event->fork.pid, event->fork.tid, 50 dump_printf("(%d:%d):(%d:%d)\n", event->fork.pid, event->fork.tid,
51 event->fork.ppid, event->fork.ptid); 51 event->fork.ppid, event->fork.ptid);
52 52
53 if (thread) { 53 if (thread) {
54 rb_erase(&thread->rb_node, &session->host_machine.threads); 54 rb_erase(&thread->rb_node, &machine->threads);
55 session->host_machine.last_match = NULL; 55 machine->last_match = NULL;
56 thread__delete(thread); 56 thread__delete(thread);
57 } 57 }
58 58
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 4800f38c7277..0cdc811c48e2 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -1,7 +1,6 @@
1#include <linux/types.h> 1#include <linux/types.h>
2#include "event.h" 2#include "event.h"
3#include "debug.h" 3#include "debug.h"
4#include "session.h"
5#include "sort.h" 4#include "sort.h"
6#include "string.h" 5#include "string.h"
7#include "strlist.h" 6#include "strlist.h"
@@ -47,7 +46,7 @@ static struct perf_sample synth_sample = {
47static pid_t perf_event__synthesize_comm(struct perf_event_ops *ops, 46static pid_t perf_event__synthesize_comm(struct perf_event_ops *ops,
48 union perf_event *event, pid_t pid, 47 union perf_event *event, pid_t pid,
49 int full, perf_event__handler_t process, 48 int full, perf_event__handler_t process,
50 struct perf_session *session) 49 struct machine *machine)
51{ 50{
52 char filename[PATH_MAX]; 51 char filename[PATH_MAX];
53 char bf[BUFSIZ]; 52 char bf[BUFSIZ];
@@ -93,14 +92,14 @@ out_race:
93 92
94 event->comm.header.type = PERF_RECORD_COMM; 93 event->comm.header.type = PERF_RECORD_COMM;
95 size = ALIGN(size, sizeof(u64)); 94 size = ALIGN(size, sizeof(u64));
96 memset(event->comm.comm + size, 0, session->id_hdr_size); 95 memset(event->comm.comm + size, 0, machine->id_hdr_size);
97 event->comm.header.size = (sizeof(event->comm) - 96 event->comm.header.size = (sizeof(event->comm) -
98 (sizeof(event->comm.comm) - size) + 97 (sizeof(event->comm.comm) - size) +
99 session->id_hdr_size); 98 machine->id_hdr_size);
100 if (!full) { 99 if (!full) {
101 event->comm.tid = pid; 100 event->comm.tid = pid;
102 101
103 process(ops, event, &synth_sample, session); 102 process(ops, event, &synth_sample, machine);
104 goto out; 103 goto out;
105 } 104 }
106 105
@@ -118,7 +117,7 @@ out_race:
118 117
119 event->comm.tid = pid; 118 event->comm.tid = pid;
120 119
121 process(ops, event, &synth_sample, session); 120 process(ops, event, &synth_sample, machine);
122 } 121 }
123 122
124 closedir(tasks); 123 closedir(tasks);
@@ -132,7 +131,7 @@ static int perf_event__synthesize_mmap_events(struct perf_event_ops *ops,
132 union perf_event *event, 131 union perf_event *event,
133 pid_t pid, pid_t tgid, 132 pid_t pid, pid_t tgid,
134 perf_event__handler_t process, 133 perf_event__handler_t process,
135 struct perf_session *session) 134 struct machine *machine)
136{ 135{
137 char filename[PATH_MAX]; 136 char filename[PATH_MAX];
138 FILE *fp; 137 FILE *fp;
@@ -195,12 +194,12 @@ static int perf_event__synthesize_mmap_events(struct perf_event_ops *ops,
195 event->mmap.len -= event->mmap.start; 194 event->mmap.len -= event->mmap.start;
196 event->mmap.header.size = (sizeof(event->mmap) - 195 event->mmap.header.size = (sizeof(event->mmap) -
197 (sizeof(event->mmap.filename) - size)); 196 (sizeof(event->mmap.filename) - size));
198 memset(event->mmap.filename + size, 0, session->id_hdr_size); 197 memset(event->mmap.filename + size, 0, machine->id_hdr_size);
199 event->mmap.header.size += session->id_hdr_size; 198 event->mmap.header.size += machine->id_hdr_size;
200 event->mmap.pid = tgid; 199 event->mmap.pid = tgid;
201 event->mmap.tid = pid; 200 event->mmap.tid = pid;
202 201
203 process(ops, event, &synth_sample, session); 202 process(ops, event, &synth_sample, machine);
204 } 203 }
205 } 204 }
206 205
@@ -210,13 +209,12 @@ static int perf_event__synthesize_mmap_events(struct perf_event_ops *ops,
210 209
211int perf_event__synthesize_modules(struct perf_event_ops *ops, 210int perf_event__synthesize_modules(struct perf_event_ops *ops,
212 perf_event__handler_t process, 211 perf_event__handler_t process,
213 struct perf_session *session,
214 struct machine *machine) 212 struct machine *machine)
215{ 213{
216 struct rb_node *nd; 214 struct rb_node *nd;
217 struct map_groups *kmaps = &machine->kmaps; 215 struct map_groups *kmaps = &machine->kmaps;
218 union perf_event *event = zalloc((sizeof(event->mmap) + 216 union perf_event *event = zalloc((sizeof(event->mmap) +
219 session->id_hdr_size)); 217 machine->id_hdr_size));
220 if (event == NULL) { 218 if (event == NULL) {
221 pr_debug("Not enough memory synthesizing mmap event " 219 pr_debug("Not enough memory synthesizing mmap event "
222 "for kernel modules\n"); 220 "for kernel modules\n");
@@ -246,15 +244,15 @@ int perf_event__synthesize_modules(struct perf_event_ops *ops,
246 event->mmap.header.type = PERF_RECORD_MMAP; 244 event->mmap.header.type = PERF_RECORD_MMAP;
247 event->mmap.header.size = (sizeof(event->mmap) - 245 event->mmap.header.size = (sizeof(event->mmap) -
248 (sizeof(event->mmap.filename) - size)); 246 (sizeof(event->mmap.filename) - size));
249 memset(event->mmap.filename + size, 0, session->id_hdr_size); 247 memset(event->mmap.filename + size, 0, machine->id_hdr_size);
250 event->mmap.header.size += session->id_hdr_size; 248 event->mmap.header.size += machine->id_hdr_size;
251 event->mmap.start = pos->start; 249 event->mmap.start = pos->start;
252 event->mmap.len = pos->end - pos->start; 250 event->mmap.len = pos->end - pos->start;
253 event->mmap.pid = machine->pid; 251 event->mmap.pid = machine->pid;
254 252
255 memcpy(event->mmap.filename, pos->dso->long_name, 253 memcpy(event->mmap.filename, pos->dso->long_name,
256 pos->dso->long_name_len + 1); 254 pos->dso->long_name_len + 1);
257 process(ops, event, &synth_sample, session); 255 process(ops, event, &synth_sample, machine);
258 } 256 }
259 257
260 free(event); 258 free(event);
@@ -265,29 +263,29 @@ static int __event__synthesize_thread(union perf_event *comm_event,
265 union perf_event *mmap_event, 263 union perf_event *mmap_event,
266 pid_t pid, perf_event__handler_t process, 264 pid_t pid, perf_event__handler_t process,
267 struct perf_event_ops *ops, 265 struct perf_event_ops *ops,
268 struct perf_session *session) 266 struct machine *machine)
269{ 267{
270 pid_t tgid = perf_event__synthesize_comm(ops, comm_event, pid, 1, process, 268 pid_t tgid = perf_event__synthesize_comm(ops, comm_event, pid, 1,
271 session); 269 process, machine);
272 if (tgid == -1) 270 if (tgid == -1)
273 return -1; 271 return -1;
274 return perf_event__synthesize_mmap_events(ops, mmap_event, pid, tgid, 272 return perf_event__synthesize_mmap_events(ops, mmap_event, pid, tgid,
275 process, session); 273 process, machine);
276} 274}
277 275
278int perf_event__synthesize_thread_map(struct perf_event_ops *ops, 276int perf_event__synthesize_thread_map(struct perf_event_ops *ops,
279 struct thread_map *threads, 277 struct thread_map *threads,
280 perf_event__handler_t process, 278 perf_event__handler_t process,
281 struct perf_session *session) 279 struct machine *machine)
282{ 280{
283 union perf_event *comm_event, *mmap_event; 281 union perf_event *comm_event, *mmap_event;
284 int err = -1, thread; 282 int err = -1, thread;
285 283
286 comm_event = malloc(sizeof(comm_event->comm) + session->id_hdr_size); 284 comm_event = malloc(sizeof(comm_event->comm) + machine->id_hdr_size);
287 if (comm_event == NULL) 285 if (comm_event == NULL)
288 goto out; 286 goto out;
289 287
290 mmap_event = malloc(sizeof(mmap_event->mmap) + session->id_hdr_size); 288 mmap_event = malloc(sizeof(mmap_event->mmap) + machine->id_hdr_size);
291 if (mmap_event == NULL) 289 if (mmap_event == NULL)
292 goto out_free_comm; 290 goto out_free_comm;
293 291
@@ -295,7 +293,7 @@ int perf_event__synthesize_thread_map(struct perf_event_ops *ops,
295 for (thread = 0; thread < threads->nr; ++thread) { 293 for (thread = 0; thread < threads->nr; ++thread) {
296 if (__event__synthesize_thread(comm_event, mmap_event, 294 if (__event__synthesize_thread(comm_event, mmap_event,
297 threads->map[thread], 295 threads->map[thread],
298 process, ops, session)) { 296 process, ops, machine)) {
299 err = -1; 297 err = -1;
300 break; 298 break;
301 } 299 }
@@ -309,18 +307,18 @@ out:
309 307
310int perf_event__synthesize_threads(struct perf_event_ops *ops, 308int perf_event__synthesize_threads(struct perf_event_ops *ops,
311 perf_event__handler_t process, 309 perf_event__handler_t process,
312 struct perf_session *session) 310 struct machine *machine)
313{ 311{
314 DIR *proc; 312 DIR *proc;
315 struct dirent dirent, *next; 313 struct dirent dirent, *next;
316 union perf_event *comm_event, *mmap_event; 314 union perf_event *comm_event, *mmap_event;
317 int err = -1; 315 int err = -1;
318 316
319 comm_event = malloc(sizeof(comm_event->comm) + session->id_hdr_size); 317 comm_event = malloc(sizeof(comm_event->comm) + machine->id_hdr_size);
320 if (comm_event == NULL) 318 if (comm_event == NULL)
321 goto out; 319 goto out;
322 320
323 mmap_event = malloc(sizeof(mmap_event->mmap) + session->id_hdr_size); 321 mmap_event = malloc(sizeof(mmap_event->mmap) + machine->id_hdr_size);
324 if (mmap_event == NULL) 322 if (mmap_event == NULL)
325 goto out_free_comm; 323 goto out_free_comm;
326 324
@@ -336,7 +334,7 @@ int perf_event__synthesize_threads(struct perf_event_ops *ops,
336 continue; 334 continue;
337 335
338 __event__synthesize_thread(comm_event, mmap_event, pid, 336 __event__synthesize_thread(comm_event, mmap_event, pid,
339 process, ops, session); 337 process, ops, machine);
340 } 338 }
341 339
342 closedir(proc); 340 closedir(proc);
@@ -373,7 +371,6 @@ static int find_symbol_cb(void *arg, const char *name, char type,
373 371
374int perf_event__synthesize_kernel_mmap(struct perf_event_ops *ops, 372int perf_event__synthesize_kernel_mmap(struct perf_event_ops *ops,
375 perf_event__handler_t process, 373 perf_event__handler_t process,
376 struct perf_session *session,
377 struct machine *machine, 374 struct machine *machine,
378 const char *symbol_name) 375 const char *symbol_name)
379{ 376{
@@ -390,7 +387,7 @@ int perf_event__synthesize_kernel_mmap(struct perf_event_ops *ops,
390 */ 387 */
391 struct process_symbol_args args = { .name = symbol_name, }; 388 struct process_symbol_args args = { .name = symbol_name, };
392 union perf_event *event = zalloc((sizeof(event->mmap) + 389 union perf_event *event = zalloc((sizeof(event->mmap) +
393 session->id_hdr_size)); 390 machine->id_hdr_size));
394 if (event == NULL) { 391 if (event == NULL) {
395 pr_debug("Not enough memory synthesizing mmap event " 392 pr_debug("Not enough memory synthesizing mmap event "
396 "for kernel modules\n"); 393 "for kernel modules\n");
@@ -424,13 +421,13 @@ int perf_event__synthesize_kernel_mmap(struct perf_event_ops *ops,
424 size = ALIGN(size, sizeof(u64)); 421 size = ALIGN(size, sizeof(u64));
425 event->mmap.header.type = PERF_RECORD_MMAP; 422 event->mmap.header.type = PERF_RECORD_MMAP;
426 event->mmap.header.size = (sizeof(event->mmap) - 423 event->mmap.header.size = (sizeof(event->mmap) -
427 (sizeof(event->mmap.filename) - size) + session->id_hdr_size); 424 (sizeof(event->mmap.filename) - size) + machine->id_hdr_size);
428 event->mmap.pgoff = args.start; 425 event->mmap.pgoff = args.start;
429 event->mmap.start = map->start; 426 event->mmap.start = map->start;
430 event->mmap.len = map->end - event->mmap.start; 427 event->mmap.len = map->end - event->mmap.start;
431 event->mmap.pid = machine->pid; 428 event->mmap.pid = machine->pid;
432 429
433 err = process(ops, event, &synth_sample, session); 430 err = process(ops, event, &synth_sample, machine);
434 free(event); 431 free(event);
435 432
436 return err; 433 return err;
@@ -439,9 +436,9 @@ int perf_event__synthesize_kernel_mmap(struct perf_event_ops *ops,
439int perf_event__process_comm(struct perf_event_ops *ops __used, 436int perf_event__process_comm(struct perf_event_ops *ops __used,
440 union perf_event *event, 437 union perf_event *event,
441 struct perf_sample *sample __used, 438 struct perf_sample *sample __used,
442 struct perf_session *session) 439 struct machine *machine)
443{ 440{
444 struct thread *thread = perf_session__findnew(session, event->comm.tid); 441 struct thread *thread = machine__findnew_thread(machine, event->comm.tid);
445 442
446 dump_printf(": %s:%d\n", event->comm.comm, event->comm.tid); 443 dump_printf(": %s:%d\n", event->comm.comm, event->comm.tid);
447 444
@@ -456,11 +453,10 @@ int perf_event__process_comm(struct perf_event_ops *ops __used,
456int perf_event__process_lost(struct perf_event_ops *ops __used, 453int perf_event__process_lost(struct perf_event_ops *ops __used,
457 union perf_event *event, 454 union perf_event *event,
458 struct perf_sample *sample __used, 455 struct perf_sample *sample __used,
459 struct perf_session *session) 456 struct machine *machine __used)
460{ 457{
461 dump_printf(": id:%" PRIu64 ": lost:%" PRIu64 "\n", 458 dump_printf(": id:%" PRIu64 ": lost:%" PRIu64 "\n",
462 event->lost.id, event->lost.lost); 459 event->lost.id, event->lost.lost);
463 session->hists.stats.total_lost += event->lost.lost;
464 return 0; 460 return 0;
465} 461}
466 462
@@ -479,20 +475,13 @@ static void perf_event__set_kernel_mmap_len(union perf_event *event,
479 475
480static int perf_event__process_kernel_mmap(struct perf_event_ops *ops __used, 476static int perf_event__process_kernel_mmap(struct perf_event_ops *ops __used,
481 union perf_event *event, 477 union perf_event *event,
482 struct perf_session *session) 478 struct machine *machine)
483{ 479{
484 struct map *map; 480 struct map *map;
485 char kmmap_prefix[PATH_MAX]; 481 char kmmap_prefix[PATH_MAX];
486 struct machine *machine;
487 enum dso_kernel_type kernel_type; 482 enum dso_kernel_type kernel_type;
488 bool is_kernel_mmap; 483 bool is_kernel_mmap;
489 484
490 machine = perf_session__findnew_machine(session, event->mmap.pid);
491 if (!machine) {
492 pr_err("Can't find id %d's machine\n", event->mmap.pid);
493 goto out_problem;
494 }
495
496 machine__mmap_name(machine, kmmap_prefix, sizeof(kmmap_prefix)); 485 machine__mmap_name(machine, kmmap_prefix, sizeof(kmmap_prefix));
497 if (machine__is_host(machine)) 486 if (machine__is_host(machine))
498 kernel_type = DSO_TYPE_KERNEL; 487 kernel_type = DSO_TYPE_KERNEL;
@@ -559,9 +548,9 @@ static int perf_event__process_kernel_mmap(struct perf_event_ops *ops __used,
559 * time /proc/sys/kernel/kptr_restrict was non zero. 548 * time /proc/sys/kernel/kptr_restrict was non zero.
560 */ 549 */
561 if (event->mmap.pgoff != 0) { 550 if (event->mmap.pgoff != 0) {
562 perf_session__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, 551 maps__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps,
563 symbol_name, 552 symbol_name,
564 event->mmap.pgoff); 553 event->mmap.pgoff);
565 } 554 }
566 555
567 if (machine__is_default_guest(machine)) { 556 if (machine__is_default_guest(machine)) {
@@ -580,9 +569,8 @@ out_problem:
580int perf_event__process_mmap(struct perf_event_ops *ops, 569int perf_event__process_mmap(struct perf_event_ops *ops,
581 union perf_event *event, 570 union perf_event *event,
582 struct perf_sample *sample __used, 571 struct perf_sample *sample __used,
583 struct perf_session *session) 572 struct machine *machine)
584{ 573{
585 struct machine *machine;
586 struct thread *thread; 574 struct thread *thread;
587 struct map *map; 575 struct map *map;
588 u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 576 u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
@@ -594,16 +582,13 @@ int perf_event__process_mmap(struct perf_event_ops *ops,
594 582
595 if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL || 583 if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL ||
596 cpumode == PERF_RECORD_MISC_KERNEL) { 584 cpumode == PERF_RECORD_MISC_KERNEL) {
597 ret = perf_event__process_kernel_mmap(ops, event, session); 585 ret = perf_event__process_kernel_mmap(ops, event, machine);
598 if (ret < 0) 586 if (ret < 0)
599 goto out_problem; 587 goto out_problem;
600 return 0; 588 return 0;
601 } 589 }
602 590
603 machine = perf_session__find_host_machine(session); 591 thread = machine__findnew_thread(machine, event->mmap.pid);
604 if (machine == NULL)
605 goto out_problem;
606 thread = perf_session__findnew(session, event->mmap.pid);
607 if (thread == NULL) 592 if (thread == NULL)
608 goto out_problem; 593 goto out_problem;
609 map = map__new(&machine->user_dsos, event->mmap.start, 594 map = map__new(&machine->user_dsos, event->mmap.start,
@@ -624,16 +609,16 @@ out_problem:
624int perf_event__process_task(struct perf_event_ops *ops __used, 609int perf_event__process_task(struct perf_event_ops *ops __used,
625 union perf_event *event, 610 union perf_event *event,
626 struct perf_sample *sample __used, 611 struct perf_sample *sample __used,
627 struct perf_session *session) 612 struct machine *machine)
628{ 613{
629 struct thread *thread = perf_session__findnew(session, event->fork.tid); 614 struct thread *thread = machine__findnew_thread(machine, event->fork.tid);
630 struct thread *parent = perf_session__findnew(session, event->fork.ptid); 615 struct thread *parent = machine__findnew_thread(machine, event->fork.ptid);
631 616
632 dump_printf("(%d:%d):(%d:%d)\n", event->fork.pid, event->fork.tid, 617 dump_printf("(%d:%d):(%d:%d)\n", event->fork.pid, event->fork.tid,
633 event->fork.ppid, event->fork.ptid); 618 event->fork.ppid, event->fork.ptid);
634 619
635 if (event->header.type == PERF_RECORD_EXIT) { 620 if (event->header.type == PERF_RECORD_EXIT) {
636 perf_session__remove_thread(session, thread); 621 machine__remove_thread(machine, thread);
637 return 0; 622 return 0;
638 } 623 }
639 624
@@ -647,21 +632,21 @@ int perf_event__process_task(struct perf_event_ops *ops __used,
647} 632}
648 633
649int perf_event__process(struct perf_event_ops *ops, union perf_event *event, 634int perf_event__process(struct perf_event_ops *ops, union perf_event *event,
650 struct perf_sample *sample, struct perf_session *session) 635 struct perf_sample *sample, struct machine *machine)
651{ 636{
652 switch (event->header.type) { 637 switch (event->header.type) {
653 case PERF_RECORD_COMM: 638 case PERF_RECORD_COMM:
654 perf_event__process_comm(ops, event, sample, session); 639 perf_event__process_comm(ops, event, sample, machine);
655 break; 640 break;
656 case PERF_RECORD_MMAP: 641 case PERF_RECORD_MMAP:
657 perf_event__process_mmap(ops, event, sample, session); 642 perf_event__process_mmap(ops, event, sample, machine);
658 break; 643 break;
659 case PERF_RECORD_FORK: 644 case PERF_RECORD_FORK:
660 case PERF_RECORD_EXIT: 645 case PERF_RECORD_EXIT:
661 perf_event__process_task(ops, event, sample, session); 646 perf_event__process_task(ops, event, sample, machine);
662 break; 647 break;
663 case PERF_RECORD_LOST: 648 case PERF_RECORD_LOST:
664 perf_event__process_lost(ops, event, sample, session); 649 perf_event__process_lost(ops, event, sample, machine);
665 default: 650 default:
666 break; 651 break;
667 } 652 }
@@ -670,36 +655,29 @@ int perf_event__process(struct perf_event_ops *ops, union perf_event *event,
670} 655}
671 656
672void thread__find_addr_map(struct thread *self, 657void thread__find_addr_map(struct thread *self,
673 struct perf_session *session, u8 cpumode, 658 struct machine *machine, u8 cpumode,
674 enum map_type type, pid_t pid, u64 addr, 659 enum map_type type, u64 addr,
675 struct addr_location *al) 660 struct addr_location *al)
676{ 661{
677 struct map_groups *mg = &self->mg; 662 struct map_groups *mg = &self->mg;
678 struct machine *machine = NULL;
679 663
680 al->thread = self; 664 al->thread = self;
681 al->addr = addr; 665 al->addr = addr;
682 al->cpumode = cpumode; 666 al->cpumode = cpumode;
683 al->filtered = false; 667 al->filtered = false;
684 668
669 if (machine == NULL) {
670 al->map = NULL;
671 return;
672 }
673
685 if (cpumode == PERF_RECORD_MISC_KERNEL && perf_host) { 674 if (cpumode == PERF_RECORD_MISC_KERNEL && perf_host) {
686 al->level = 'k'; 675 al->level = 'k';
687 machine = perf_session__find_host_machine(session);
688 if (machine == NULL) {
689 al->map = NULL;
690 return;
691 }
692 mg = &machine->kmaps; 676 mg = &machine->kmaps;
693 } else if (cpumode == PERF_RECORD_MISC_USER && perf_host) { 677 } else if (cpumode == PERF_RECORD_MISC_USER && perf_host) {
694 al->level = '.'; 678 al->level = '.';
695 machine = perf_session__find_host_machine(session);
696 } else if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) { 679 } else if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) {
697 al->level = 'g'; 680 al->level = 'g';
698 machine = perf_session__find_machine(session, pid);
699 if (machine == NULL) {
700 al->map = NULL;
701 return;
702 }
703 mg = &machine->kmaps; 681 mg = &machine->kmaps;
704 } else { 682 } else {
705 /* 683 /*
@@ -745,13 +723,12 @@ try_again:
745 al->addr = al->map->map_ip(al->map, al->addr); 723 al->addr = al->map->map_ip(al->map, al->addr);
746} 724}
747 725
748void thread__find_addr_location(struct thread *self, 726void thread__find_addr_location(struct thread *thread, struct machine *machine,
749 struct perf_session *session, u8 cpumode, 727 u8 cpumode, enum map_type type, u64 addr,
750 enum map_type type, pid_t pid, u64 addr,
751 struct addr_location *al, 728 struct addr_location *al,
752 symbol_filter_t filter) 729 symbol_filter_t filter)
753{ 730{
754 thread__find_addr_map(self, session, cpumode, type, pid, addr, al); 731 thread__find_addr_map(thread, machine, cpumode, type, addr, al);
755 if (al->map != NULL) 732 if (al->map != NULL)
756 al->sym = map__find_symbol(al->map, al->addr, filter); 733 al->sym = map__find_symbol(al->map, al->addr, filter);
757 else 734 else
@@ -759,13 +736,13 @@ void thread__find_addr_location(struct thread *self,
759} 736}
760 737
761int perf_event__preprocess_sample(const union perf_event *event, 738int perf_event__preprocess_sample(const union perf_event *event,
762 struct perf_session *session, 739 struct machine *machine,
763 struct addr_location *al, 740 struct addr_location *al,
764 struct perf_sample *sample, 741 struct perf_sample *sample,
765 symbol_filter_t filter) 742 symbol_filter_t filter)
766{ 743{
767 u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 744 u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
768 struct thread *thread = perf_session__findnew(session, event->ip.pid); 745 struct thread *thread = machine__findnew_thread(machine, event->ip.pid);
769 746
770 if (thread == NULL) 747 if (thread == NULL)
771 return -1; 748 return -1;
@@ -776,18 +753,18 @@ int perf_event__preprocess_sample(const union perf_event *event,
776 753
777 dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); 754 dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
778 /* 755 /*
779 * Have we already created the kernel maps for the host machine? 756 * Have we already created the kernel maps for this machine?
780 * 757 *
781 * This should have happened earlier, when we processed the kernel MMAP 758 * This should have happened earlier, when we processed the kernel MMAP
782 * events, but for older perf.data files there was no such thing, so do 759 * events, but for older perf.data files there was no such thing, so do
783 * it now. 760 * it now.
784 */ 761 */
785 if (cpumode == PERF_RECORD_MISC_KERNEL && 762 if (cpumode == PERF_RECORD_MISC_KERNEL &&
786 session->host_machine.vmlinux_maps[MAP__FUNCTION] == NULL) 763 machine->vmlinux_maps[MAP__FUNCTION] == NULL)
787 machine__create_kernel_maps(&session->host_machine); 764 machine__create_kernel_maps(machine);
788 765
789 thread__find_addr_map(thread, session, cpumode, MAP__FUNCTION, 766 thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION,
790 event->ip.pid, event->ip.ip, al); 767 event->ip.ip, al);
791 dump_printf(" ...... dso: %s\n", 768 dump_printf(" ...... dso: %s\n",
792 al->map ? al->map->dso->long_name : 769 al->map ? al->map->dso->long_name :
793 al->level == 'H' ? "[hypervisor]" : "<not found>"); 770 al->level == 'H' ? "[hypervisor]" : "<not found>");
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 669409d35710..1564877e8703 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -142,56 +142,53 @@ union perf_event {
142void perf_event__print_totals(void); 142void perf_event__print_totals(void);
143 143
144struct perf_event_ops; 144struct perf_event_ops;
145struct perf_session;
146struct thread_map; 145struct thread_map;
147 146
148typedef int (*perf_event__handler_t)(struct perf_event_ops *ops, 147typedef int (*perf_event__handler_t)(struct perf_event_ops *ops,
149 union perf_event *event, 148 union perf_event *event,
150 struct perf_sample *sample, 149 struct perf_sample *sample,
151 struct perf_session *session); 150 struct machine *machine);
152 151
153int perf_event__synthesize_thread_map(struct perf_event_ops *ops, 152int perf_event__synthesize_thread_map(struct perf_event_ops *ops,
154 struct thread_map *threads, 153 struct thread_map *threads,
155 perf_event__handler_t process, 154 perf_event__handler_t process,
156 struct perf_session *session); 155 struct machine *machine);
157int perf_event__synthesize_threads(struct perf_event_ops *ops, 156int perf_event__synthesize_threads(struct perf_event_ops *ops,
158 perf_event__handler_t process, 157 perf_event__handler_t process,
159 struct perf_session *session); 158 struct machine *machine);
160int perf_event__synthesize_kernel_mmap(struct perf_event_ops *ops, 159int perf_event__synthesize_kernel_mmap(struct perf_event_ops *ops,
161 perf_event__handler_t process, 160 perf_event__handler_t process,
162 struct perf_session *session,
163 struct machine *machine, 161 struct machine *machine,
164 const char *symbol_name); 162 const char *symbol_name);
165 163
166int perf_event__synthesize_modules(struct perf_event_ops *ops, 164int perf_event__synthesize_modules(struct perf_event_ops *ops,
167 perf_event__handler_t process, 165 perf_event__handler_t process,
168 struct perf_session *session,
169 struct machine *machine); 166 struct machine *machine);
170 167
171int perf_event__process_comm(struct perf_event_ops *ops, 168int perf_event__process_comm(struct perf_event_ops *ops,
172 union perf_event *event, 169 union perf_event *event,
173 struct perf_sample *sample, 170 struct perf_sample *sample,
174 struct perf_session *session); 171 struct machine *machine);
175int perf_event__process_lost(struct perf_event_ops *ops, 172int perf_event__process_lost(struct perf_event_ops *ops,
176 union perf_event *event, 173 union perf_event *event,
177 struct perf_sample *sample, 174 struct perf_sample *sample,
178 struct perf_session *session); 175 struct machine *machine);
179int perf_event__process_mmap(struct perf_event_ops *ops, 176int perf_event__process_mmap(struct perf_event_ops *ops,
180 union perf_event *event, 177 union perf_event *event,
181 struct perf_sample *sample, 178 struct perf_sample *sample,
182 struct perf_session *session); 179 struct machine *machine);
183int perf_event__process_task(struct perf_event_ops *ops, 180int perf_event__process_task(struct perf_event_ops *ops,
184 union perf_event *event, 181 union perf_event *event,
185 struct perf_sample *sample, 182 struct perf_sample *sample,
186 struct perf_session *session); 183 struct machine *machine);
187int perf_event__process(struct perf_event_ops *ops, 184int perf_event__process(struct perf_event_ops *ops,
188 union perf_event *event, 185 union perf_event *event,
189 struct perf_sample *sample, 186 struct perf_sample *sample,
190 struct perf_session *session); 187 struct machine *machine);
191 188
192struct addr_location; 189struct addr_location;
193int perf_event__preprocess_sample(const union perf_event *self, 190int perf_event__preprocess_sample(const union perf_event *self,
194 struct perf_session *session, 191 struct machine *machine,
195 struct addr_location *al, 192 struct addr_location *al,
196 struct perf_sample *sample, 193 struct perf_sample *sample,
197 symbol_filter_t filter); 194 symbol_filter_t filter);
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index ab3a2b0e8f06..db280d6ca898 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -2072,8 +2072,7 @@ out_delete_evlist:
2072 2072
2073int perf_event__synthesize_attr(struct perf_event_ops *ops, 2073int perf_event__synthesize_attr(struct perf_event_ops *ops,
2074 struct perf_event_attr *attr, u16 ids, u64 *id, 2074 struct perf_event_attr *attr, u16 ids, u64 *id,
2075 perf_event__handler_t process, 2075 perf_event__handler_t process)
2076 struct perf_session *session)
2077{ 2076{
2078 union perf_event *ev; 2077 union perf_event *ev;
2079 size_t size; 2078 size_t size;
@@ -2095,7 +2094,7 @@ int perf_event__synthesize_attr(struct perf_event_ops *ops,
2095 ev->attr.header.type = PERF_RECORD_HEADER_ATTR; 2094 ev->attr.header.type = PERF_RECORD_HEADER_ATTR;
2096 ev->attr.header.size = size; 2095 ev->attr.header.size = size;
2097 2096
2098 err = process(ops, ev, NULL, session); 2097 err = process(ops, ev, NULL, NULL);
2099 2098
2100 free(ev); 2099 free(ev);
2101 2100
@@ -2111,7 +2110,7 @@ int perf_event__synthesize_attrs(struct perf_event_ops *ops,
2111 2110
2112 list_for_each_entry(attr, &session->evlist->entries, node) { 2111 list_for_each_entry(attr, &session->evlist->entries, node) {
2113 err = perf_event__synthesize_attr(ops, &attr->attr, attr->ids, 2112 err = perf_event__synthesize_attr(ops, &attr->attr, attr->ids,
2114 attr->id, process, session); 2113 attr->id, process);
2115 if (err) { 2114 if (err) {
2116 pr_debug("failed to create perf header attribute\n"); 2115 pr_debug("failed to create perf header attribute\n");
2117 return err; 2116 return err;
@@ -2161,7 +2160,7 @@ int perf_event__process_attr(union perf_event *event,
2161int perf_event__synthesize_event_type(struct perf_event_ops *ops, 2160int perf_event__synthesize_event_type(struct perf_event_ops *ops,
2162 u64 event_id, char *name, 2161 u64 event_id, char *name,
2163 perf_event__handler_t process, 2162 perf_event__handler_t process,
2164 struct perf_session *session) 2163 struct machine *machine)
2165{ 2164{
2166 union perf_event ev; 2165 union perf_event ev;
2167 size_t size = 0; 2166 size_t size = 0;
@@ -2179,14 +2178,14 @@ int perf_event__synthesize_event_type(struct perf_event_ops *ops,
2179 ev.event_type.header.size = sizeof(ev.event_type) - 2178 ev.event_type.header.size = sizeof(ev.event_type) -
2180 (sizeof(ev.event_type.event_type.name) - size); 2179 (sizeof(ev.event_type.event_type.name) - size);
2181 2180
2182 err = process(ops, &ev, NULL, session); 2181 err = process(ops, &ev, NULL, machine);
2183 2182
2184 return err; 2183 return err;
2185} 2184}
2186 2185
2187int perf_event__synthesize_event_types(struct perf_event_ops *ops, 2186int perf_event__synthesize_event_types(struct perf_event_ops *ops,
2188 perf_event__handler_t process, 2187 perf_event__handler_t process,
2189 struct perf_session *session) 2188 struct machine *machine)
2190{ 2189{
2191 struct perf_trace_event_type *type; 2190 struct perf_trace_event_type *type;
2192 int i, err = 0; 2191 int i, err = 0;
@@ -2196,7 +2195,7 @@ int perf_event__synthesize_event_types(struct perf_event_ops *ops,
2196 2195
2197 err = perf_event__synthesize_event_type(ops, type->event_id, 2196 err = perf_event__synthesize_event_type(ops, type->event_id,
2198 type->name, process, 2197 type->name, process,
2199 session); 2198 machine);
2200 if (err) { 2199 if (err) {
2201 pr_debug("failed to create perf header event type\n"); 2200 pr_debug("failed to create perf header event type\n");
2202 return err; 2201 return err;
@@ -2207,8 +2206,7 @@ int perf_event__synthesize_event_types(struct perf_event_ops *ops,
2207} 2206}
2208 2207
2209int perf_event__process_event_type(struct perf_event_ops *ops __unused, 2208int perf_event__process_event_type(struct perf_event_ops *ops __unused,
2210 union perf_event *event, 2209 union perf_event *event)
2211 struct perf_session *session __unused)
2212{ 2210{
2213 if (perf_header__push_event(event->event_type.event_type.event_id, 2211 if (perf_header__push_event(event->event_type.event_type.event_id,
2214 event->event_type.event_type.name) < 0) 2212 event->event_type.event_type.name) < 0)
@@ -2219,8 +2217,7 @@ int perf_event__process_event_type(struct perf_event_ops *ops __unused,
2219 2217
2220int perf_event__synthesize_tracing_data(struct perf_event_ops *ops, int fd, 2218int perf_event__synthesize_tracing_data(struct perf_event_ops *ops, int fd,
2221 struct perf_evlist *evlist, 2219 struct perf_evlist *evlist,
2222 perf_event__handler_t process, 2220 perf_event__handler_t process)
2223 struct perf_session *session __unused)
2224{ 2221{
2225 union perf_event ev; 2222 union perf_event ev;
2226 struct tracing_data *tdata; 2223 struct tracing_data *tdata;
@@ -2251,7 +2248,7 @@ int perf_event__synthesize_tracing_data(struct perf_event_ops *ops, int fd,
2251 ev.tracing_data.header.size = sizeof(ev.tracing_data); 2248 ev.tracing_data.header.size = sizeof(ev.tracing_data);
2252 ev.tracing_data.size = aligned_size; 2249 ev.tracing_data.size = aligned_size;
2253 2250
2254 process(ops, &ev, NULL, session); 2251 process(ops, &ev, NULL, NULL);
2255 2252
2256 /* 2253 /*
2257 * The put function will copy all the tracing data 2254 * The put function will copy all the tracing data
@@ -2296,8 +2293,7 @@ int perf_event__process_tracing_data(union perf_event *event,
2296int perf_event__synthesize_build_id(struct perf_event_ops *ops, 2293int perf_event__synthesize_build_id(struct perf_event_ops *ops,
2297 struct dso *pos, u16 misc, 2294 struct dso *pos, u16 misc,
2298 perf_event__handler_t process, 2295 perf_event__handler_t process,
2299 struct machine *machine, 2296 struct machine *machine)
2300 struct perf_session *session)
2301{ 2297{
2302 union perf_event ev; 2298 union perf_event ev;
2303 size_t len; 2299 size_t len;
@@ -2317,7 +2313,7 @@ int perf_event__synthesize_build_id(struct perf_event_ops *ops,
2317 ev.build_id.header.size = sizeof(ev.build_id) + len; 2313 ev.build_id.header.size = sizeof(ev.build_id) + len;
2318 memcpy(&ev.build_id.filename, pos->long_name, pos->long_name_len); 2314 memcpy(&ev.build_id.filename, pos->long_name, pos->long_name_len);
2319 2315
2320 err = process(ops, &ev, NULL, session); 2316 err = process(ops, &ev, NULL, machine);
2321 2317
2322 return err; 2318 return err;
2323} 2319}
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 54dae5f09556..a604962fc431 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -99,8 +99,7 @@ int build_id_cache__remove_s(const char *sbuild_id, const char *debugdir);
99 99
100int perf_event__synthesize_attr(struct perf_event_ops *ops, 100int perf_event__synthesize_attr(struct perf_event_ops *ops,
101 struct perf_event_attr *attr, u16 ids, u64 *id, 101 struct perf_event_attr *attr, u16 ids, u64 *id,
102 perf_event__handler_t process, 102 perf_event__handler_t process);
103 struct perf_session *session);
104int perf_event__synthesize_attrs(struct perf_event_ops *ops, 103int perf_event__synthesize_attrs(struct perf_event_ops *ops,
105 struct perf_session *session, 104 struct perf_session *session,
106 perf_event__handler_t process); 105 perf_event__handler_t process);
@@ -109,26 +108,23 @@ int perf_event__process_attr(union perf_event *event, struct perf_evlist **pevli
109int perf_event__synthesize_event_type(struct perf_event_ops *ops, 108int perf_event__synthesize_event_type(struct perf_event_ops *ops,
110 u64 event_id, char *name, 109 u64 event_id, char *name,
111 perf_event__handler_t process, 110 perf_event__handler_t process,
112 struct perf_session *session); 111 struct machine *machine);
113int perf_event__synthesize_event_types(struct perf_event_ops *ops, 112int perf_event__synthesize_event_types(struct perf_event_ops *ops,
114 perf_event__handler_t process, 113 perf_event__handler_t process,
115 struct perf_session *session); 114 struct machine *machine);
116int perf_event__process_event_type(struct perf_event_ops *ops, 115int perf_event__process_event_type(struct perf_event_ops *ops,
117 union perf_event *event, 116 union perf_event *event);
118 struct perf_session *session);
119 117
120int perf_event__synthesize_tracing_data(struct perf_event_ops *ops, 118int perf_event__synthesize_tracing_data(struct perf_event_ops *ops,
121 int fd, struct perf_evlist *evlist, 119 int fd, struct perf_evlist *evlist,
122 perf_event__handler_t process, 120 perf_event__handler_t process);
123 struct perf_session *session);
124int perf_event__process_tracing_data(union perf_event *event, 121int perf_event__process_tracing_data(union perf_event *event,
125 struct perf_session *session); 122 struct perf_session *session);
126 123
127int perf_event__synthesize_build_id(struct perf_event_ops *ops, 124int perf_event__synthesize_build_id(struct perf_event_ops *ops,
128 struct dso *pos, u16 misc, 125 struct dso *pos, u16 misc,
129 perf_event__handler_t process, 126 perf_event__handler_t process,
130 struct machine *machine, 127 struct machine *machine);
131 struct perf_session *session);
132int perf_event__process_build_id(struct perf_event_ops *ops, 128int perf_event__process_build_id(struct perf_event_ops *ops,
133 union perf_event *event, 129 union perf_event *event,
134 struct perf_session *session); 130 struct perf_session *session);
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index bde6835ee257..2b8017f8a930 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -18,9 +18,11 @@ enum map_type {
18extern const char *map_type__name[MAP__NR_TYPES]; 18extern const char *map_type__name[MAP__NR_TYPES];
19 19
20struct dso; 20struct dso;
21struct ip_callchain;
21struct ref_reloc_sym; 22struct ref_reloc_sym;
22struct map_groups; 23struct map_groups;
23struct machine; 24struct machine;
25struct perf_evsel;
24 26
25struct map { 27struct map {
26 union { 28 union {
@@ -61,6 +63,7 @@ struct map_groups {
61struct machine { 63struct machine {
62 struct rb_node rb_node; 64 struct rb_node rb_node;
63 pid_t pid; 65 pid_t pid;
66 u16 id_hdr_size;
64 char *root_dir; 67 char *root_dir;
65 struct rb_root threads; 68 struct rb_root threads;
66 struct list_head dead_threads; 69 struct list_head dead_threads;
@@ -151,6 +154,13 @@ int machine__init(struct machine *self, const char *root_dir, pid_t pid);
151void machine__exit(struct machine *self); 154void machine__exit(struct machine *self);
152void machine__delete(struct machine *self); 155void machine__delete(struct machine *self);
153 156
157int machine__resolve_callchain(struct machine *machine,
158 struct perf_evsel *evsel, struct thread *thread,
159 struct ip_callchain *chain,
160 struct symbol **parent);
161int maps__set_kallsyms_ref_reloc_sym(struct map **maps, const char *symbol_name,
162 u64 addr);
163
154/* 164/*
155 * Default guest kernel is defined by parameter --guestkallsyms 165 * Default guest kernel is defined by parameter --guestkallsyms
156 * and --guestmodules 166 * and --guestmodules
diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c
index 74350ffb57fe..a82ce4303ff5 100644
--- a/tools/perf/util/scripting-engines/trace-event-perl.c
+++ b/tools/perf/util/scripting-engines/trace-event-perl.c
@@ -27,6 +27,8 @@
27 27
28#include "../../perf.h" 28#include "../../perf.h"
29#include "../util.h" 29#include "../util.h"
30#include "../thread.h"
31#include "../event.h"
30#include "../trace-event.h" 32#include "../trace-event.h"
31 33
32#include <EXTERN.h> 34#include <EXTERN.h>
@@ -248,7 +250,7 @@ static inline struct event *find_cache_event(int type)
248static void perl_process_event(union perf_event *pevent __unused, 250static void perl_process_event(union perf_event *pevent __unused,
249 struct perf_sample *sample, 251 struct perf_sample *sample,
250 struct perf_evsel *evsel, 252 struct perf_evsel *evsel,
251 struct perf_session *session __unused, 253 struct machine *machine __unused,
252 struct thread *thread) 254 struct thread *thread)
253{ 255{
254 struct format_field *field; 256 struct format_field *field;
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 6ccf70e8d8f2..0b2a48783172 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -29,6 +29,8 @@
29 29
30#include "../../perf.h" 30#include "../../perf.h"
31#include "../util.h" 31#include "../util.h"
32#include "../event.h"
33#include "../thread.h"
32#include "../trace-event.h" 34#include "../trace-event.h"
33 35
34PyMODINIT_FUNC initperf_trace_context(void); 36PyMODINIT_FUNC initperf_trace_context(void);
@@ -207,7 +209,7 @@ static inline struct event *find_cache_event(int type)
207static void python_process_event(union perf_event *pevent __unused, 209static void python_process_event(union perf_event *pevent __unused,
208 struct perf_sample *sample, 210 struct perf_sample *sample,
209 struct perf_evsel *evsel __unused, 211 struct perf_evsel *evsel __unused,
210 struct perf_session *session __unused, 212 struct machine *machine __unused,
211 struct thread *thread) 213 struct thread *thread)
212{ 214{
213 PyObject *handler, *retval, *context, *t, *obj, *dict = NULL; 215 PyObject *handler, *retval, *context, *t, *obj, *dict = NULL;
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index a36023a66779..be33606386bf 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -84,6 +84,7 @@ void perf_session__update_sample_type(struct perf_session *self)
84 self->sample_size = __perf_evsel__sample_size(self->sample_type); 84 self->sample_size = __perf_evsel__sample_size(self->sample_type);
85 self->sample_id_all = perf_evlist__sample_id_all(self->evlist); 85 self->sample_id_all = perf_evlist__sample_id_all(self->evlist);
86 self->id_hdr_size = perf_evlist__id_hdr_size(self->evlist); 86 self->id_hdr_size = perf_evlist__id_hdr_size(self->evlist);
87 self->host_machine.id_hdr_size = self->id_hdr_size;
87} 88}
88 89
89int perf_session__create_kernel_maps(struct perf_session *self) 90int perf_session__create_kernel_maps(struct perf_session *self)
@@ -216,10 +217,10 @@ static bool symbol__match_parent_regex(struct symbol *sym)
216 return 0; 217 return 0;
217} 218}
218 219
219int perf_session__resolve_callchain(struct perf_session *self, struct perf_evsel *evsel, 220int machine__resolve_callchain(struct machine *self, struct perf_evsel *evsel,
220 struct thread *thread, 221 struct thread *thread,
221 struct ip_callchain *chain, 222 struct ip_callchain *chain,
222 struct symbol **parent) 223 struct symbol **parent)
223{ 224{
224 u8 cpumode = PERF_RECORD_MISC_USER; 225 u8 cpumode = PERF_RECORD_MISC_USER;
225 unsigned int i; 226 unsigned int i;
@@ -252,7 +253,7 @@ int perf_session__resolve_callchain(struct perf_session *self, struct perf_evsel
252 253
253 al.filtered = false; 254 al.filtered = false;
254 thread__find_addr_location(thread, self, cpumode, 255 thread__find_addr_location(thread, self, cpumode,
255 MAP__FUNCTION, thread->pid, ip, &al, NULL); 256 MAP__FUNCTION, ip, &al, NULL);
256 if (al.sym != NULL) { 257 if (al.sym != NULL) {
257 if (sort__has_parent && !*parent && 258 if (sort__has_parent && !*parent &&
258 symbol__match_parent_regex(al.sym)) 259 symbol__match_parent_regex(al.sym))
@@ -270,14 +271,6 @@ int perf_session__resolve_callchain(struct perf_session *self, struct perf_evsel
270 return 0; 271 return 0;
271} 272}
272 273
273static int process_event_synth_stub(struct perf_event_ops *ops __used,
274 union perf_event *event __used,
275 struct perf_session *session __used)
276{
277 dump_printf(": unhandled!\n");
278 return 0;
279}
280
281static int process_event_synth_tracing_data_stub(union perf_event *event __used, 274static int process_event_synth_tracing_data_stub(union perf_event *event __used,
282 struct perf_session *session __used) 275 struct perf_session *session __used)
283{ 276{
@@ -296,7 +289,7 @@ static int process_event_sample_stub(struct perf_event_ops *ops __used,
296 union perf_event *event __used, 289 union perf_event *event __used,
297 struct perf_sample *sample __used, 290 struct perf_sample *sample __used,
298 struct perf_evsel *evsel __used, 291 struct perf_evsel *evsel __used,
299 struct perf_session *session __used) 292 struct machine *machine __used)
300{ 293{
301 dump_printf(": unhandled!\n"); 294 dump_printf(": unhandled!\n");
302 return 0; 295 return 0;
@@ -305,7 +298,7 @@ static int process_event_sample_stub(struct perf_event_ops *ops __used,
305static int process_event_stub(struct perf_event_ops *ops __used, 298static int process_event_stub(struct perf_event_ops *ops __used,
306 union perf_event *event __used, 299 union perf_event *event __used,
307 struct perf_sample *sample __used, 300 struct perf_sample *sample __used,
308 struct perf_session *session __used) 301 struct machine *machine __used)
309{ 302{
310 dump_printf(": unhandled!\n"); 303 dump_printf(": unhandled!\n");
311 return 0; 304 return 0;
@@ -313,7 +306,14 @@ static int process_event_stub(struct perf_event_ops *ops __used,
313 306
314static int process_finished_round_stub(struct perf_event_ops *ops __used, 307static int process_finished_round_stub(struct perf_event_ops *ops __used,
315 union perf_event *event __used, 308 union perf_event *event __used,
316 struct perf_session *session __used) 309 struct perf_session *perf_session __used)
310{
311 dump_printf(": unhandled!\n");
312 return 0;
313}
314
315static int process_event_type_stub(struct perf_event_ops *ops __used,
316 union perf_event *event __used)
317{ 317{
318 dump_printf(": unhandled!\n"); 318 dump_printf(": unhandled!\n");
319 return 0; 319 return 0;
@@ -338,7 +338,7 @@ static void perf_event_ops__fill_defaults(struct perf_event_ops *handler)
338 if (handler->lost == NULL) 338 if (handler->lost == NULL)
339 handler->lost = perf_event__process_lost; 339 handler->lost = perf_event__process_lost;
340 if (handler->read == NULL) 340 if (handler->read == NULL)
341 handler->read = process_event_stub; 341 handler->read = process_event_sample_stub;
342 if (handler->throttle == NULL) 342 if (handler->throttle == NULL)
343 handler->throttle = process_event_stub; 343 handler->throttle = process_event_stub;
344 if (handler->unthrottle == NULL) 344 if (handler->unthrottle == NULL)
@@ -346,11 +346,11 @@ static void perf_event_ops__fill_defaults(struct perf_event_ops *handler)
346 if (handler->attr == NULL) 346 if (handler->attr == NULL)
347 handler->attr = process_event_synth_attr_stub; 347 handler->attr = process_event_synth_attr_stub;
348 if (handler->event_type == NULL) 348 if (handler->event_type == NULL)
349 handler->event_type = process_event_synth_stub; 349 handler->event_type = process_event_type_stub;
350 if (handler->tracing_data == NULL) 350 if (handler->tracing_data == NULL)
351 handler->tracing_data = process_event_synth_tracing_data_stub; 351 handler->tracing_data = process_event_synth_tracing_data_stub;
352 if (handler->build_id == NULL) 352 if (handler->build_id == NULL)
353 handler->build_id = process_event_synth_stub; 353 handler->build_id = process_finished_round_stub;
354 if (handler->finished_round == NULL) { 354 if (handler->finished_round == NULL) {
355 if (handler->ordered_samples) 355 if (handler->ordered_samples)
356 handler->finished_round = process_finished_round; 356 handler->finished_round = process_finished_round;
@@ -734,6 +734,18 @@ static void dump_sample(struct perf_session *session, union perf_event *event,
734 callchain__printf(sample); 734 callchain__printf(sample);
735} 735}
736 736
737static struct machine *
738 perf_session__find_machine_for_cpumode(struct perf_session *session,
739 union perf_event *event)
740{
741 const u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
742
743 if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest)
744 return perf_session__find_machine(session, event->ip.pid);
745
746 return perf_session__find_host_machine(session);
747}
748
737static int perf_session_deliver_event(struct perf_session *session, 749static int perf_session_deliver_event(struct perf_session *session,
738 union perf_event *event, 750 union perf_event *event,
739 struct perf_sample *sample, 751 struct perf_sample *sample,
@@ -741,6 +753,7 @@ static int perf_session_deliver_event(struct perf_session *session,
741 u64 file_offset) 753 u64 file_offset)
742{ 754{
743 struct perf_evsel *evsel; 755 struct perf_evsel *evsel;
756 struct machine *machine;
744 757
745 dump_event(session, event, file_offset, sample); 758 dump_event(session, event, file_offset, sample);
746 759
@@ -762,6 +775,8 @@ static int perf_session_deliver_event(struct perf_session *session,
762 hists__inc_nr_events(&evsel->hists, event->header.type); 775 hists__inc_nr_events(&evsel->hists, event->header.type);
763 } 776 }
764 777
778 machine = perf_session__find_machine_for_cpumode(session, event);
779
765 switch (event->header.type) { 780 switch (event->header.type) {
766 case PERF_RECORD_SAMPLE: 781 case PERF_RECORD_SAMPLE:
767 dump_sample(session, event, sample); 782 dump_sample(session, event, sample);
@@ -769,23 +784,25 @@ static int perf_session_deliver_event(struct perf_session *session,
769 ++session->hists.stats.nr_unknown_id; 784 ++session->hists.stats.nr_unknown_id;
770 return -1; 785 return -1;
771 } 786 }
772 return ops->sample(ops, event, sample, evsel, session); 787 return ops->sample(ops, event, sample, evsel, machine);
773 case PERF_RECORD_MMAP: 788 case PERF_RECORD_MMAP:
774 return ops->mmap(ops, event, sample, session); 789 return ops->mmap(ops, event, sample, machine);
775 case PERF_RECORD_COMM: 790 case PERF_RECORD_COMM:
776 return ops->comm(ops, event, sample, session); 791 return ops->comm(ops, event, sample, machine);
777 case PERF_RECORD_FORK: 792 case PERF_RECORD_FORK:
778 return ops->fork(ops, event, sample, session); 793 return ops->fork(ops, event, sample, machine);
779 case PERF_RECORD_EXIT: 794 case PERF_RECORD_EXIT:
780 return ops->exit(ops, event, sample, session); 795 return ops->exit(ops, event, sample, machine);
781 case PERF_RECORD_LOST: 796 case PERF_RECORD_LOST:
782 return ops->lost(ops, event, sample, session); 797 if (ops->lost == perf_event__process_lost)
798 session->hists.stats.total_lost += event->lost.lost;
799 return ops->lost(ops, event, sample, machine);
783 case PERF_RECORD_READ: 800 case PERF_RECORD_READ:
784 return ops->read(ops, event, sample, session); 801 return ops->read(ops, event, sample, evsel, machine);
785 case PERF_RECORD_THROTTLE: 802 case PERF_RECORD_THROTTLE:
786 return ops->throttle(ops, event, sample, session); 803 return ops->throttle(ops, event, sample, machine);
787 case PERF_RECORD_UNTHROTTLE: 804 case PERF_RECORD_UNTHROTTLE:
788 return ops->unthrottle(ops, event, sample, session); 805 return ops->unthrottle(ops, event, sample, machine);
789 default: 806 default:
790 ++session->hists.stats.nr_unknown_events; 807 ++session->hists.stats.nr_unknown_events;
791 return -1; 808 return -1;
@@ -823,7 +840,7 @@ static int perf_session__process_user_event(struct perf_session *session, union
823 perf_session__update_sample_type(session); 840 perf_session__update_sample_type(session);
824 return err; 841 return err;
825 case PERF_RECORD_HEADER_EVENT_TYPE: 842 case PERF_RECORD_HEADER_EVENT_TYPE:
826 return ops->event_type(ops, event, session); 843 return ops->event_type(ops, event);
827 case PERF_RECORD_HEADER_TRACING_DATA: 844 case PERF_RECORD_HEADER_TRACING_DATA:
828 /* setup for reading amidst mmap */ 845 /* setup for reading amidst mmap */
829 lseek(session->fd, file_offset, SEEK_SET); 846 lseek(session->fd, file_offset, SEEK_SET);
@@ -1170,9 +1187,8 @@ bool perf_session__has_traces(struct perf_session *self, const char *msg)
1170 return true; 1187 return true;
1171} 1188}
1172 1189
1173int perf_session__set_kallsyms_ref_reloc_sym(struct map **maps, 1190int maps__set_kallsyms_ref_reloc_sym(struct map **maps,
1174 const char *symbol_name, 1191 const char *symbol_name, u64 addr)
1175 u64 addr)
1176{ 1192{
1177 char *bracket; 1193 char *bracket;
1178 enum map_type i; 1194 enum map_type i;
@@ -1264,17 +1280,16 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
1264 return NULL; 1280 return NULL;
1265} 1281}
1266 1282
1267void perf_session__print_ip(union perf_event *event, struct perf_evsel *evsel, 1283void perf_event__print_ip(union perf_event *event, struct perf_sample *sample,
1268 struct perf_sample *sample, 1284 struct machine *machine, struct perf_evsel *evsel,
1269 struct perf_session *session, 1285 int print_sym, int print_dso)
1270 int print_sym, int print_dso)
1271{ 1286{
1272 struct addr_location al; 1287 struct addr_location al;
1273 const char *symname, *dsoname; 1288 const char *symname, *dsoname;
1274 struct callchain_cursor *cursor = &evsel->hists.callchain_cursor; 1289 struct callchain_cursor *cursor = &evsel->hists.callchain_cursor;
1275 struct callchain_cursor_node *node; 1290 struct callchain_cursor_node *node;
1276 1291
1277 if (perf_event__preprocess_sample(event, session, &al, sample, 1292 if (perf_event__preprocess_sample(event, machine, &al, sample,
1278 NULL) < 0) { 1293 NULL) < 0) {
1279 error("problem processing %d event, skipping it.\n", 1294 error("problem processing %d event, skipping it.\n",
1280 event->header.type); 1295 event->header.type);
@@ -1283,7 +1298,7 @@ void perf_session__print_ip(union perf_event *event, struct perf_evsel *evsel,
1283 1298
1284 if (symbol_conf.use_callchain && sample->callchain) { 1299 if (symbol_conf.use_callchain && sample->callchain) {
1285 1300
1286 if (perf_session__resolve_callchain(session, evsel, al.thread, 1301 if (machine__resolve_callchain(machine, evsel, al.thread,
1287 sample->callchain, NULL) != 0) { 1302 sample->callchain, NULL) != 0) {
1288 if (verbose) 1303 if (verbose)
1289 error("Failed to resolve callchain. Skipping\n"); 1304 error("Failed to resolve callchain. Skipping\n");
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 6de3d1368900..1c5823c7d6dc 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -58,32 +58,34 @@ struct perf_event_ops;
58 58
59typedef int (*event_sample)(struct perf_event_ops *ops, 59typedef int (*event_sample)(struct perf_event_ops *ops,
60 union perf_event *event, struct perf_sample *sample, 60 union perf_event *event, struct perf_sample *sample,
61 struct perf_evsel *evsel, struct perf_session *session); 61 struct perf_evsel *evsel, struct machine *machine);
62typedef int (*event_op)(struct perf_event_ops *ops, union perf_event *event, 62typedef int (*event_op)(struct perf_event_ops *ops, union perf_event *event,
63 struct perf_sample *sample, 63 struct perf_sample *sample,
64 struct perf_session *session); 64 struct machine *machine);
65typedef int (*event_synth_op)(union perf_event *self, 65typedef int (*event_synth_op)(union perf_event *self,
66 struct perf_session *session); 66 struct perf_session *session);
67typedef int (*event_attr_op)(union perf_event *event, 67typedef int (*event_attr_op)(union perf_event *event,
68 struct perf_evlist **pevlist); 68 struct perf_evlist **pevlist);
69typedef int (*event_simple_op)(struct perf_event_ops *ops,
70 union perf_event *event);
69typedef int (*event_op2)(struct perf_event_ops *ops, union perf_event *event, 71typedef int (*event_op2)(struct perf_event_ops *ops, union perf_event *event,
70 struct perf_session *session); 72 struct perf_session *session);
71 73
72struct perf_event_ops { 74struct perf_event_ops {
73 event_sample sample; 75 event_sample sample,
76 read;
74 event_op mmap, 77 event_op mmap,
75 comm, 78 comm,
76 fork, 79 fork,
77 exit, 80 exit,
78 lost, 81 lost,
79 read,
80 throttle, 82 throttle,
81 unthrottle; 83 unthrottle;
82 event_attr_op attr; 84 event_attr_op attr;
83 event_synth_op tracing_data; 85 event_synth_op tracing_data;
84 event_op2 event_type, 86 event_simple_op event_type;
85 build_id, 87 event_op2 finished_round,
86 finished_round; 88 build_id;
87 bool ordered_samples; 89 bool ordered_samples;
88 bool ordering_requires_timestamps; 90 bool ordering_requires_timestamps;
89}; 91};
@@ -108,10 +110,6 @@ int perf_session__resolve_callchain(struct perf_session *self, struct perf_evsel
108 110
109bool perf_session__has_traces(struct perf_session *self, const char *msg); 111bool perf_session__has_traces(struct perf_session *self, const char *msg);
110 112
111int perf_session__set_kallsyms_ref_reloc_sym(struct map **maps,
112 const char *symbol_name,
113 u64 addr);
114
115void mem_bswap_64(void *src, int byte_size); 113void mem_bswap_64(void *src, int byte_size);
116void perf_event__attr_swap(struct perf_event_attr *attr); 114void perf_event__attr_swap(struct perf_event_attr *attr);
117 115
@@ -151,6 +149,9 @@ void perf_session__process_machines(struct perf_session *self,
151 return machines__process(&self->machines, process, ops); 149 return machines__process(&self->machines, process, ops);
152} 150}
153 151
152struct thread *perf_session__findnew(struct perf_session *self, pid_t pid);
153size_t perf_session__fprintf(struct perf_session *self, FILE *fp);
154
154size_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp); 155size_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp);
155 156
156size_t perf_session__fprintf_dsos_buildid(struct perf_session *self, 157size_t perf_session__fprintf_dsos_buildid(struct perf_session *self,
@@ -171,10 +172,9 @@ static inline int perf_session__parse_sample(struct perf_session *session,
171struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, 172struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
172 unsigned int type); 173 unsigned int type);
173 174
174void perf_session__print_ip(union perf_event *event, struct perf_evsel *evsel, 175void perf_event__print_ip(union perf_event *event, struct perf_sample *sample,
175 struct perf_sample *sample, 176 struct machine *machine, struct perf_evsel *evsel,
176 struct perf_session *session, 177 int print_sym, int print_dso);
177 int print_sym, int print_dso);
178 178
179int perf_session__cpu_bitmap(struct perf_session *session, 179int perf_session__cpu_bitmap(struct perf_session *session,
180 const char *cpu_list, unsigned long *cpu_bitmap); 180 const char *cpu_list, unsigned long *cpu_bitmap);
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index e5f2401c1b5e..70c2c13ff679 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -18,16 +18,14 @@ struct thread {
18 int comm_len; 18 int comm_len;
19}; 19};
20 20
21struct perf_session; 21struct machine;
22 22
23void thread__delete(struct thread *self); 23void thread__delete(struct thread *self);
24 24
25int thread__set_comm(struct thread *self, const char *comm); 25int thread__set_comm(struct thread *self, const char *comm);
26int thread__comm_len(struct thread *self); 26int thread__comm_len(struct thread *self);
27struct thread *perf_session__findnew(struct perf_session *self, pid_t pid);
28void thread__insert_map(struct thread *self, struct map *map); 27void thread__insert_map(struct thread *self, struct map *map);
29int thread__fork(struct thread *self, struct thread *parent); 28int thread__fork(struct thread *self, struct thread *parent);
30size_t perf_session__fprintf(struct perf_session *self, FILE *fp);
31 29
32static inline struct map *thread__find_map(struct thread *self, 30static inline struct map *thread__find_map(struct thread *self,
33 enum map_type type, u64 addr) 31 enum map_type type, u64 addr)
@@ -35,14 +33,12 @@ static inline struct map *thread__find_map(struct thread *self,
35 return self ? map_groups__find(&self->mg, type, addr) : NULL; 33 return self ? map_groups__find(&self->mg, type, addr) : NULL;
36} 34}
37 35
38void thread__find_addr_map(struct thread *self, 36void thread__find_addr_map(struct thread *thread, struct machine *machine,
39 struct perf_session *session, u8 cpumode, 37 u8 cpumode, enum map_type type, u64 addr,
40 enum map_type type, pid_t pid, u64 addr,
41 struct addr_location *al); 38 struct addr_location *al);
42 39
43void thread__find_addr_location(struct thread *self, 40void thread__find_addr_location(struct thread *thread, struct machine *machine,
44 struct perf_session *session, u8 cpumode, 41 u8 cpumode, enum map_type type, u64 addr,
45 enum map_type type, pid_t pid, u64 addr,
46 struct addr_location *al, 42 struct addr_location *al,
47 symbol_filter_t filter); 43 symbol_filter_t filter);
48#endif /* __PERF_THREAD_H */ 44#endif /* __PERF_THREAD_H */
diff --git a/tools/perf/util/trace-event-scripting.c b/tools/perf/util/trace-event-scripting.c
index c9dcbec7d800..a3fdf55f317b 100644
--- a/tools/perf/util/trace-event-scripting.c
+++ b/tools/perf/util/trace-event-scripting.c
@@ -39,7 +39,7 @@ static int stop_script_unsupported(void)
39static void process_event_unsupported(union perf_event *event __unused, 39static void process_event_unsupported(union perf_event *event __unused,
40 struct perf_sample *sample __unused, 40 struct perf_sample *sample __unused,
41 struct perf_evsel *evsel __unused, 41 struct perf_evsel *evsel __unused,
42 struct perf_session *session __unused, 42 struct machine *machine __unused,
43 struct thread *thread __unused) 43 struct thread *thread __unused)
44{ 44{
45} 45}
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h
index a84100817649..58ae14c5baac 100644
--- a/tools/perf/util/trace-event.h
+++ b/tools/perf/util/trace-event.h
@@ -3,7 +3,11 @@
3 3
4#include <stdbool.h> 4#include <stdbool.h>
5#include "parse-events.h" 5#include "parse-events.h"
6#include "session.h" 6
7struct machine;
8struct perf_sample;
9union perf_event;
10struct thread;
7 11
8#define __unused __attribute__((unused)) 12#define __unused __attribute__((unused))
9 13
@@ -292,7 +296,7 @@ struct scripting_ops {
292 void (*process_event) (union perf_event *event, 296 void (*process_event) (union perf_event *event,
293 struct perf_sample *sample, 297 struct perf_sample *sample,
294 struct perf_evsel *evsel, 298 struct perf_evsel *evsel,
295 struct perf_session *session, 299 struct machine *machine,
296 struct thread *thread); 300 struct thread *thread);
297 int (*generate_script) (const char *outfile); 301 int (*generate_script) (const char *outfile);
298}; 302};