diff options
Diffstat (limited to 'tools/perf/util/event.c')
-rw-r--r-- | tools/perf/util/event.c | 243 |
1 files changed, 137 insertions, 106 deletions
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 437f8ca679a0..97c479bcb0dc 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" |
@@ -44,9 +43,10 @@ static struct perf_sample synth_sample = { | |||
44 | .period = 1, | 43 | .period = 1, |
45 | }; | 44 | }; |
46 | 45 | ||
47 | static pid_t perf_event__synthesize_comm(union perf_event *event, pid_t pid, | 46 | static pid_t perf_event__synthesize_comm(struct perf_tool *tool, |
47 | union perf_event *event, pid_t pid, | ||
48 | int full, perf_event__handler_t process, | 48 | int full, perf_event__handler_t process, |
49 | struct perf_session *session) | 49 | struct machine *machine) |
50 | { | 50 | { |
51 | char filename[PATH_MAX]; | 51 | char filename[PATH_MAX]; |
52 | char bf[BUFSIZ]; | 52 | char bf[BUFSIZ]; |
@@ -92,14 +92,14 @@ out_race: | |||
92 | 92 | ||
93 | event->comm.header.type = PERF_RECORD_COMM; | 93 | event->comm.header.type = PERF_RECORD_COMM; |
94 | size = ALIGN(size, sizeof(u64)); | 94 | size = ALIGN(size, sizeof(u64)); |
95 | memset(event->comm.comm + size, 0, session->id_hdr_size); | 95 | memset(event->comm.comm + size, 0, machine->id_hdr_size); |
96 | event->comm.header.size = (sizeof(event->comm) - | 96 | event->comm.header.size = (sizeof(event->comm) - |
97 | (sizeof(event->comm.comm) - size) + | 97 | (sizeof(event->comm.comm) - size) + |
98 | session->id_hdr_size); | 98 | machine->id_hdr_size); |
99 | if (!full) { | 99 | if (!full) { |
100 | event->comm.tid = pid; | 100 | event->comm.tid = pid; |
101 | 101 | ||
102 | process(event, &synth_sample, session); | 102 | process(tool, event, &synth_sample, machine); |
103 | goto out; | 103 | goto out; |
104 | } | 104 | } |
105 | 105 | ||
@@ -117,7 +117,7 @@ out_race: | |||
117 | 117 | ||
118 | event->comm.tid = pid; | 118 | event->comm.tid = pid; |
119 | 119 | ||
120 | process(event, &synth_sample, session); | 120 | process(tool, event, &synth_sample, machine); |
121 | } | 121 | } |
122 | 122 | ||
123 | closedir(tasks); | 123 | closedir(tasks); |
@@ -127,10 +127,11 @@ out: | |||
127 | return tgid; | 127 | return tgid; |
128 | } | 128 | } |
129 | 129 | ||
130 | static int perf_event__synthesize_mmap_events(union perf_event *event, | 130 | static int perf_event__synthesize_mmap_events(struct perf_tool *tool, |
131 | union perf_event *event, | ||
131 | pid_t pid, pid_t tgid, | 132 | pid_t pid, pid_t tgid, |
132 | perf_event__handler_t process, | 133 | perf_event__handler_t process, |
133 | struct perf_session *session) | 134 | struct machine *machine) |
134 | { | 135 | { |
135 | char filename[PATH_MAX]; | 136 | char filename[PATH_MAX]; |
136 | FILE *fp; | 137 | FILE *fp; |
@@ -193,12 +194,12 @@ static int perf_event__synthesize_mmap_events(union perf_event *event, | |||
193 | event->mmap.len -= event->mmap.start; | 194 | event->mmap.len -= event->mmap.start; |
194 | event->mmap.header.size = (sizeof(event->mmap) - | 195 | event->mmap.header.size = (sizeof(event->mmap) - |
195 | (sizeof(event->mmap.filename) - size)); | 196 | (sizeof(event->mmap.filename) - size)); |
196 | memset(event->mmap.filename + size, 0, session->id_hdr_size); | 197 | memset(event->mmap.filename + size, 0, machine->id_hdr_size); |
197 | event->mmap.header.size += session->id_hdr_size; | 198 | event->mmap.header.size += machine->id_hdr_size; |
198 | event->mmap.pid = tgid; | 199 | event->mmap.pid = tgid; |
199 | event->mmap.tid = pid; | 200 | event->mmap.tid = pid; |
200 | 201 | ||
201 | process(event, &synth_sample, session); | 202 | process(tool, event, &synth_sample, machine); |
202 | } | 203 | } |
203 | } | 204 | } |
204 | 205 | ||
@@ -206,14 +207,14 @@ static int perf_event__synthesize_mmap_events(union perf_event *event, | |||
206 | return 0; | 207 | return 0; |
207 | } | 208 | } |
208 | 209 | ||
209 | int perf_event__synthesize_modules(perf_event__handler_t process, | 210 | int perf_event__synthesize_modules(struct perf_tool *tool, |
210 | struct perf_session *session, | 211 | perf_event__handler_t process, |
211 | struct machine *machine) | 212 | struct machine *machine) |
212 | { | 213 | { |
213 | struct rb_node *nd; | 214 | struct rb_node *nd; |
214 | struct map_groups *kmaps = &machine->kmaps; | 215 | struct map_groups *kmaps = &machine->kmaps; |
215 | union perf_event *event = zalloc((sizeof(event->mmap) + | 216 | union perf_event *event = zalloc((sizeof(event->mmap) + |
216 | session->id_hdr_size)); | 217 | machine->id_hdr_size)); |
217 | if (event == NULL) { | 218 | if (event == NULL) { |
218 | pr_debug("Not enough memory synthesizing mmap event " | 219 | pr_debug("Not enough memory synthesizing mmap event " |
219 | "for kernel modules\n"); | 220 | "for kernel modules\n"); |
@@ -243,15 +244,15 @@ int perf_event__synthesize_modules(perf_event__handler_t process, | |||
243 | event->mmap.header.type = PERF_RECORD_MMAP; | 244 | event->mmap.header.type = PERF_RECORD_MMAP; |
244 | event->mmap.header.size = (sizeof(event->mmap) - | 245 | event->mmap.header.size = (sizeof(event->mmap) - |
245 | (sizeof(event->mmap.filename) - size)); | 246 | (sizeof(event->mmap.filename) - size)); |
246 | memset(event->mmap.filename + size, 0, session->id_hdr_size); | 247 | memset(event->mmap.filename + size, 0, machine->id_hdr_size); |
247 | event->mmap.header.size += session->id_hdr_size; | 248 | event->mmap.header.size += machine->id_hdr_size; |
248 | event->mmap.start = pos->start; | 249 | event->mmap.start = pos->start; |
249 | event->mmap.len = pos->end - pos->start; | 250 | event->mmap.len = pos->end - pos->start; |
250 | event->mmap.pid = machine->pid; | 251 | event->mmap.pid = machine->pid; |
251 | 252 | ||
252 | memcpy(event->mmap.filename, pos->dso->long_name, | 253 | memcpy(event->mmap.filename, pos->dso->long_name, |
253 | pos->dso->long_name_len + 1); | 254 | pos->dso->long_name_len + 1); |
254 | process(event, &synth_sample, session); | 255 | process(tool, event, &synth_sample, machine); |
255 | } | 256 | } |
256 | 257 | ||
257 | free(event); | 258 | free(event); |
@@ -261,28 +262,30 @@ int perf_event__synthesize_modules(perf_event__handler_t process, | |||
261 | static int __event__synthesize_thread(union perf_event *comm_event, | 262 | static int __event__synthesize_thread(union perf_event *comm_event, |
262 | union perf_event *mmap_event, | 263 | union perf_event *mmap_event, |
263 | pid_t pid, perf_event__handler_t process, | 264 | pid_t pid, perf_event__handler_t process, |
264 | struct perf_session *session) | 265 | struct perf_tool *tool, |
266 | struct machine *machine) | ||
265 | { | 267 | { |
266 | pid_t tgid = perf_event__synthesize_comm(comm_event, pid, 1, process, | 268 | pid_t tgid = perf_event__synthesize_comm(tool, comm_event, pid, 1, |
267 | session); | 269 | process, machine); |
268 | if (tgid == -1) | 270 | if (tgid == -1) |
269 | return -1; | 271 | return -1; |
270 | return perf_event__synthesize_mmap_events(mmap_event, pid, tgid, | 272 | return perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid, |
271 | process, session); | 273 | process, machine); |
272 | } | 274 | } |
273 | 275 | ||
274 | int perf_event__synthesize_thread_map(struct thread_map *threads, | 276 | int perf_event__synthesize_thread_map(struct perf_tool *tool, |
277 | struct thread_map *threads, | ||
275 | perf_event__handler_t process, | 278 | perf_event__handler_t process, |
276 | struct perf_session *session) | 279 | struct machine *machine) |
277 | { | 280 | { |
278 | union perf_event *comm_event, *mmap_event; | 281 | union perf_event *comm_event, *mmap_event; |
279 | int err = -1, thread; | 282 | int err = -1, thread; |
280 | 283 | ||
281 | comm_event = malloc(sizeof(comm_event->comm) + session->id_hdr_size); | 284 | comm_event = malloc(sizeof(comm_event->comm) + machine->id_hdr_size); |
282 | if (comm_event == NULL) | 285 | if (comm_event == NULL) |
283 | goto out; | 286 | goto out; |
284 | 287 | ||
285 | mmap_event = malloc(sizeof(mmap_event->mmap) + session->id_hdr_size); | 288 | mmap_event = malloc(sizeof(mmap_event->mmap) + machine->id_hdr_size); |
286 | if (mmap_event == NULL) | 289 | if (mmap_event == NULL) |
287 | goto out_free_comm; | 290 | goto out_free_comm; |
288 | 291 | ||
@@ -290,7 +293,7 @@ int perf_event__synthesize_thread_map(struct thread_map *threads, | |||
290 | for (thread = 0; thread < threads->nr; ++thread) { | 293 | for (thread = 0; thread < threads->nr; ++thread) { |
291 | if (__event__synthesize_thread(comm_event, mmap_event, | 294 | if (__event__synthesize_thread(comm_event, mmap_event, |
292 | threads->map[thread], | 295 | threads->map[thread], |
293 | process, session)) { | 296 | process, tool, machine)) { |
294 | err = -1; | 297 | err = -1; |
295 | break; | 298 | break; |
296 | } | 299 | } |
@@ -302,19 +305,20 @@ out: | |||
302 | return err; | 305 | return err; |
303 | } | 306 | } |
304 | 307 | ||
305 | int perf_event__synthesize_threads(perf_event__handler_t process, | 308 | int perf_event__synthesize_threads(struct perf_tool *tool, |
306 | struct perf_session *session) | 309 | perf_event__handler_t process, |
310 | struct machine *machine) | ||
307 | { | 311 | { |
308 | DIR *proc; | 312 | DIR *proc; |
309 | struct dirent dirent, *next; | 313 | struct dirent dirent, *next; |
310 | union perf_event *comm_event, *mmap_event; | 314 | union perf_event *comm_event, *mmap_event; |
311 | int err = -1; | 315 | int err = -1; |
312 | 316 | ||
313 | comm_event = malloc(sizeof(comm_event->comm) + session->id_hdr_size); | 317 | comm_event = malloc(sizeof(comm_event->comm) + machine->id_hdr_size); |
314 | if (comm_event == NULL) | 318 | if (comm_event == NULL) |
315 | goto out; | 319 | goto out; |
316 | 320 | ||
317 | mmap_event = malloc(sizeof(mmap_event->mmap) + session->id_hdr_size); | 321 | mmap_event = malloc(sizeof(mmap_event->mmap) + machine->id_hdr_size); |
318 | if (mmap_event == NULL) | 322 | if (mmap_event == NULL) |
319 | goto out_free_comm; | 323 | goto out_free_comm; |
320 | 324 | ||
@@ -330,7 +334,7 @@ int perf_event__synthesize_threads(perf_event__handler_t process, | |||
330 | continue; | 334 | continue; |
331 | 335 | ||
332 | __event__synthesize_thread(comm_event, mmap_event, pid, | 336 | __event__synthesize_thread(comm_event, mmap_event, pid, |
333 | process, session); | 337 | process, tool, machine); |
334 | } | 338 | } |
335 | 339 | ||
336 | closedir(proc); | 340 | closedir(proc); |
@@ -365,8 +369,8 @@ static int find_symbol_cb(void *arg, const char *name, char type, | |||
365 | return 1; | 369 | return 1; |
366 | } | 370 | } |
367 | 371 | ||
368 | int perf_event__synthesize_kernel_mmap(perf_event__handler_t process, | 372 | int perf_event__synthesize_kernel_mmap(struct perf_tool *tool, |
369 | struct perf_session *session, | 373 | perf_event__handler_t process, |
370 | struct machine *machine, | 374 | struct machine *machine, |
371 | const char *symbol_name) | 375 | const char *symbol_name) |
372 | { | 376 | { |
@@ -383,7 +387,7 @@ int perf_event__synthesize_kernel_mmap(perf_event__handler_t process, | |||
383 | */ | 387 | */ |
384 | struct process_symbol_args args = { .name = symbol_name, }; | 388 | struct process_symbol_args args = { .name = symbol_name, }; |
385 | union perf_event *event = zalloc((sizeof(event->mmap) + | 389 | union perf_event *event = zalloc((sizeof(event->mmap) + |
386 | session->id_hdr_size)); | 390 | machine->id_hdr_size)); |
387 | if (event == NULL) { | 391 | if (event == NULL) { |
388 | pr_debug("Not enough memory synthesizing mmap event " | 392 | pr_debug("Not enough memory synthesizing mmap event " |
389 | "for kernel modules\n"); | 393 | "for kernel modules\n"); |
@@ -417,25 +421,32 @@ int perf_event__synthesize_kernel_mmap(perf_event__handler_t process, | |||
417 | size = ALIGN(size, sizeof(u64)); | 421 | size = ALIGN(size, sizeof(u64)); |
418 | event->mmap.header.type = PERF_RECORD_MMAP; | 422 | event->mmap.header.type = PERF_RECORD_MMAP; |
419 | event->mmap.header.size = (sizeof(event->mmap) - | 423 | event->mmap.header.size = (sizeof(event->mmap) - |
420 | (sizeof(event->mmap.filename) - size) + session->id_hdr_size); | 424 | (sizeof(event->mmap.filename) - size) + machine->id_hdr_size); |
421 | event->mmap.pgoff = args.start; | 425 | event->mmap.pgoff = args.start; |
422 | event->mmap.start = map->start; | 426 | event->mmap.start = map->start; |
423 | event->mmap.len = map->end - event->mmap.start; | 427 | event->mmap.len = map->end - event->mmap.start; |
424 | event->mmap.pid = machine->pid; | 428 | event->mmap.pid = machine->pid; |
425 | 429 | ||
426 | err = process(event, &synth_sample, session); | 430 | err = process(tool, event, &synth_sample, machine); |
427 | free(event); | 431 | free(event); |
428 | 432 | ||
429 | return err; | 433 | return err; |
430 | } | 434 | } |
431 | 435 | ||
432 | int perf_event__process_comm(union perf_event *event, | 436 | size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp) |
437 | { | ||
438 | return fprintf(fp, ": %s:%d\n", event->comm.comm, event->comm.tid); | ||
439 | } | ||
440 | |||
441 | int perf_event__process_comm(struct perf_tool *tool __used, | ||
442 | union perf_event *event, | ||
433 | struct perf_sample *sample __used, | 443 | struct perf_sample *sample __used, |
434 | struct perf_session *session) | 444 | struct machine *machine) |
435 | { | 445 | { |
436 | struct thread *thread = perf_session__findnew(session, event->comm.tid); | 446 | struct thread *thread = machine__findnew_thread(machine, event->comm.tid); |
437 | 447 | ||
438 | dump_printf(": %s:%d\n", event->comm.comm, event->comm.tid); | 448 | if (dump_trace) |
449 | perf_event__fprintf_comm(event, stdout); | ||
439 | 450 | ||
440 | if (thread == NULL || thread__set_comm(thread, event->comm.comm)) { | 451 | if (thread == NULL || thread__set_comm(thread, event->comm.comm)) { |
441 | dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n"); | 452 | dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n"); |
@@ -445,13 +456,13 @@ int perf_event__process_comm(union perf_event *event, | |||
445 | return 0; | 456 | return 0; |
446 | } | 457 | } |
447 | 458 | ||
448 | int perf_event__process_lost(union perf_event *event, | 459 | int perf_event__process_lost(struct perf_tool *tool __used, |
460 | union perf_event *event, | ||
449 | struct perf_sample *sample __used, | 461 | struct perf_sample *sample __used, |
450 | struct perf_session *session) | 462 | struct machine *machine __used) |
451 | { | 463 | { |
452 | dump_printf(": id:%" PRIu64 ": lost:%" PRIu64 "\n", | 464 | dump_printf(": id:%" PRIu64 ": lost:%" PRIu64 "\n", |
453 | event->lost.id, event->lost.lost); | 465 | event->lost.id, event->lost.lost); |
454 | session->hists.stats.total_lost += event->lost.lost; | ||
455 | return 0; | 466 | return 0; |
456 | } | 467 | } |
457 | 468 | ||
@@ -468,21 +479,15 @@ static void perf_event__set_kernel_mmap_len(union perf_event *event, | |||
468 | maps[MAP__FUNCTION]->end = ~0ULL; | 479 | maps[MAP__FUNCTION]->end = ~0ULL; |
469 | } | 480 | } |
470 | 481 | ||
471 | static int perf_event__process_kernel_mmap(union perf_event *event, | 482 | static int perf_event__process_kernel_mmap(struct perf_tool *tool __used, |
472 | struct perf_session *session) | 483 | union perf_event *event, |
484 | struct machine *machine) | ||
473 | { | 485 | { |
474 | struct map *map; | 486 | struct map *map; |
475 | char kmmap_prefix[PATH_MAX]; | 487 | char kmmap_prefix[PATH_MAX]; |
476 | struct machine *machine; | ||
477 | enum dso_kernel_type kernel_type; | 488 | enum dso_kernel_type kernel_type; |
478 | bool is_kernel_mmap; | 489 | bool is_kernel_mmap; |
479 | 490 | ||
480 | machine = perf_session__findnew_machine(session, event->mmap.pid); | ||
481 | if (!machine) { | ||
482 | pr_err("Can't find id %d's machine\n", event->mmap.pid); | ||
483 | goto out_problem; | ||
484 | } | ||
485 | |||
486 | machine__mmap_name(machine, kmmap_prefix, sizeof(kmmap_prefix)); | 491 | machine__mmap_name(machine, kmmap_prefix, sizeof(kmmap_prefix)); |
487 | if (machine__is_host(machine)) | 492 | if (machine__is_host(machine)) |
488 | kernel_type = DSO_TYPE_KERNEL; | 493 | kernel_type = DSO_TYPE_KERNEL; |
@@ -549,9 +554,9 @@ static int perf_event__process_kernel_mmap(union perf_event *event, | |||
549 | * time /proc/sys/kernel/kptr_restrict was non zero. | 554 | * time /proc/sys/kernel/kptr_restrict was non zero. |
550 | */ | 555 | */ |
551 | if (event->mmap.pgoff != 0) { | 556 | if (event->mmap.pgoff != 0) { |
552 | perf_session__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, | 557 | maps__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, |
553 | symbol_name, | 558 | symbol_name, |
554 | event->mmap.pgoff); | 559 | event->mmap.pgoff); |
555 | } | 560 | } |
556 | 561 | ||
557 | if (machine__is_default_guest(machine)) { | 562 | if (machine__is_default_guest(machine)) { |
@@ -567,32 +572,35 @@ out_problem: | |||
567 | return -1; | 572 | return -1; |
568 | } | 573 | } |
569 | 574 | ||
570 | int perf_event__process_mmap(union perf_event *event, | 575 | size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp) |
576 | { | ||
577 | return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 "]: %s\n", | ||
578 | event->mmap.pid, event->mmap.tid, event->mmap.start, | ||
579 | event->mmap.len, event->mmap.pgoff, event->mmap.filename); | ||
580 | } | ||
581 | |||
582 | int perf_event__process_mmap(struct perf_tool *tool, | ||
583 | union perf_event *event, | ||
571 | struct perf_sample *sample __used, | 584 | struct perf_sample *sample __used, |
572 | struct perf_session *session) | 585 | struct machine *machine) |
573 | { | 586 | { |
574 | struct machine *machine; | ||
575 | struct thread *thread; | 587 | struct thread *thread; |
576 | struct map *map; | 588 | struct map *map; |
577 | u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; | 589 | u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; |
578 | int ret = 0; | 590 | int ret = 0; |
579 | 591 | ||
580 | dump_printf(" %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 "]: %s\n", | 592 | if (dump_trace) |
581 | event->mmap.pid, event->mmap.tid, event->mmap.start, | 593 | perf_event__fprintf_mmap(event, stdout); |
582 | event->mmap.len, event->mmap.pgoff, event->mmap.filename); | ||
583 | 594 | ||
584 | if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL || | 595 | if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL || |
585 | cpumode == PERF_RECORD_MISC_KERNEL) { | 596 | cpumode == PERF_RECORD_MISC_KERNEL) { |
586 | ret = perf_event__process_kernel_mmap(event, session); | 597 | ret = perf_event__process_kernel_mmap(tool, event, machine); |
587 | if (ret < 0) | 598 | if (ret < 0) |
588 | goto out_problem; | 599 | goto out_problem; |
589 | return 0; | 600 | return 0; |
590 | } | 601 | } |
591 | 602 | ||
592 | machine = perf_session__find_host_machine(session); | 603 | thread = machine__findnew_thread(machine, event->mmap.pid); |
593 | if (machine == NULL) | ||
594 | goto out_problem; | ||
595 | thread = perf_session__findnew(session, event->mmap.pid); | ||
596 | if (thread == NULL) | 604 | if (thread == NULL) |
597 | goto out_problem; | 605 | goto out_problem; |
598 | map = map__new(&machine->user_dsos, event->mmap.start, | 606 | map = map__new(&machine->user_dsos, event->mmap.start, |
@@ -610,18 +618,26 @@ out_problem: | |||
610 | return 0; | 618 | return 0; |
611 | } | 619 | } |
612 | 620 | ||
613 | int perf_event__process_task(union perf_event *event, | 621 | size_t perf_event__fprintf_task(union perf_event *event, FILE *fp) |
622 | { | ||
623 | return fprintf(fp, "(%d:%d):(%d:%d)\n", | ||
624 | event->fork.pid, event->fork.tid, | ||
625 | event->fork.ppid, event->fork.ptid); | ||
626 | } | ||
627 | |||
628 | int perf_event__process_task(struct perf_tool *tool __used, | ||
629 | union perf_event *event, | ||
614 | struct perf_sample *sample __used, | 630 | struct perf_sample *sample __used, |
615 | struct perf_session *session) | 631 | struct machine *machine) |
616 | { | 632 | { |
617 | struct thread *thread = perf_session__findnew(session, event->fork.tid); | 633 | struct thread *thread = machine__findnew_thread(machine, event->fork.tid); |
618 | struct thread *parent = perf_session__findnew(session, event->fork.ptid); | 634 | struct thread *parent = machine__findnew_thread(machine, event->fork.ptid); |
619 | 635 | ||
620 | dump_printf("(%d:%d):(%d:%d)\n", event->fork.pid, event->fork.tid, | 636 | if (dump_trace) |
621 | event->fork.ppid, event->fork.ptid); | 637 | perf_event__fprintf_task(event, stdout); |
622 | 638 | ||
623 | if (event->header.type == PERF_RECORD_EXIT) { | 639 | if (event->header.type == PERF_RECORD_EXIT) { |
624 | perf_session__remove_thread(session, thread); | 640 | machine__remove_thread(machine, thread); |
625 | return 0; | 641 | return 0; |
626 | } | 642 | } |
627 | 643 | ||
@@ -634,22 +650,45 @@ int perf_event__process_task(union perf_event *event, | |||
634 | return 0; | 650 | return 0; |
635 | } | 651 | } |
636 | 652 | ||
637 | int perf_event__process(union perf_event *event, struct perf_sample *sample, | 653 | size_t perf_event__fprintf(union perf_event *event, FILE *fp) |
638 | struct perf_session *session) | ||
639 | { | 654 | { |
655 | size_t ret = fprintf(fp, "PERF_RECORD_%s", | ||
656 | perf_event__name(event->header.type)); | ||
657 | |||
640 | switch (event->header.type) { | 658 | switch (event->header.type) { |
641 | case PERF_RECORD_COMM: | 659 | case PERF_RECORD_COMM: |
642 | perf_event__process_comm(event, sample, session); | 660 | ret += perf_event__fprintf_comm(event, fp); |
661 | break; | ||
662 | case PERF_RECORD_FORK: | ||
663 | case PERF_RECORD_EXIT: | ||
664 | ret += perf_event__fprintf_task(event, fp); | ||
643 | break; | 665 | break; |
644 | case PERF_RECORD_MMAP: | 666 | case PERF_RECORD_MMAP: |
645 | perf_event__process_mmap(event, sample, session); | 667 | ret += perf_event__fprintf_mmap(event, fp); |
668 | break; | ||
669 | default: | ||
670 | ret += fprintf(fp, "\n"); | ||
671 | } | ||
672 | |||
673 | return ret; | ||
674 | } | ||
675 | |||
676 | int perf_event__process(struct perf_tool *tool, union perf_event *event, | ||
677 | struct perf_sample *sample, struct machine *machine) | ||
678 | { | ||
679 | switch (event->header.type) { | ||
680 | case PERF_RECORD_COMM: | ||
681 | perf_event__process_comm(tool, event, sample, machine); | ||
682 | break; | ||
683 | case PERF_RECORD_MMAP: | ||
684 | perf_event__process_mmap(tool, event, sample, machine); | ||
646 | break; | 685 | break; |
647 | case PERF_RECORD_FORK: | 686 | case PERF_RECORD_FORK: |
648 | case PERF_RECORD_EXIT: | 687 | case PERF_RECORD_EXIT: |
649 | perf_event__process_task(event, sample, session); | 688 | perf_event__process_task(tool, event, sample, machine); |
650 | break; | 689 | break; |
651 | case PERF_RECORD_LOST: | 690 | case PERF_RECORD_LOST: |
652 | perf_event__process_lost(event, sample, session); | 691 | perf_event__process_lost(tool, event, sample, machine); |
653 | default: | 692 | default: |
654 | break; | 693 | break; |
655 | } | 694 | } |
@@ -658,36 +697,29 @@ int perf_event__process(union perf_event *event, struct perf_sample *sample, | |||
658 | } | 697 | } |
659 | 698 | ||
660 | void thread__find_addr_map(struct thread *self, | 699 | void thread__find_addr_map(struct thread *self, |
661 | struct perf_session *session, u8 cpumode, | 700 | struct machine *machine, u8 cpumode, |
662 | enum map_type type, pid_t pid, u64 addr, | 701 | enum map_type type, u64 addr, |
663 | struct addr_location *al) | 702 | struct addr_location *al) |
664 | { | 703 | { |
665 | struct map_groups *mg = &self->mg; | 704 | struct map_groups *mg = &self->mg; |
666 | struct machine *machine = NULL; | ||
667 | 705 | ||
668 | al->thread = self; | 706 | al->thread = self; |
669 | al->addr = addr; | 707 | al->addr = addr; |
670 | al->cpumode = cpumode; | 708 | al->cpumode = cpumode; |
671 | al->filtered = false; | 709 | al->filtered = false; |
672 | 710 | ||
711 | if (machine == NULL) { | ||
712 | al->map = NULL; | ||
713 | return; | ||
714 | } | ||
715 | |||
673 | if (cpumode == PERF_RECORD_MISC_KERNEL && perf_host) { | 716 | if (cpumode == PERF_RECORD_MISC_KERNEL && perf_host) { |
674 | al->level = 'k'; | 717 | al->level = 'k'; |
675 | machine = perf_session__find_host_machine(session); | ||
676 | if (machine == NULL) { | ||
677 | al->map = NULL; | ||
678 | return; | ||
679 | } | ||
680 | mg = &machine->kmaps; | 718 | mg = &machine->kmaps; |
681 | } else if (cpumode == PERF_RECORD_MISC_USER && perf_host) { | 719 | } else if (cpumode == PERF_RECORD_MISC_USER && perf_host) { |
682 | al->level = '.'; | 720 | al->level = '.'; |
683 | machine = perf_session__find_host_machine(session); | ||
684 | } else if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) { | 721 | } else if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) { |
685 | al->level = 'g'; | 722 | al->level = 'g'; |
686 | machine = perf_session__find_machine(session, pid); | ||
687 | if (machine == NULL) { | ||
688 | al->map = NULL; | ||
689 | return; | ||
690 | } | ||
691 | mg = &machine->kmaps; | 723 | mg = &machine->kmaps; |
692 | } else { | 724 | } else { |
693 | /* | 725 | /* |
@@ -733,13 +765,12 @@ try_again: | |||
733 | al->addr = al->map->map_ip(al->map, al->addr); | 765 | al->addr = al->map->map_ip(al->map, al->addr); |
734 | } | 766 | } |
735 | 767 | ||
736 | void thread__find_addr_location(struct thread *self, | 768 | void thread__find_addr_location(struct thread *thread, struct machine *machine, |
737 | struct perf_session *session, u8 cpumode, | 769 | u8 cpumode, enum map_type type, u64 addr, |
738 | enum map_type type, pid_t pid, u64 addr, | ||
739 | struct addr_location *al, | 770 | struct addr_location *al, |
740 | symbol_filter_t filter) | 771 | symbol_filter_t filter) |
741 | { | 772 | { |
742 | thread__find_addr_map(self, session, cpumode, type, pid, addr, al); | 773 | thread__find_addr_map(thread, machine, cpumode, type, addr, al); |
743 | if (al->map != NULL) | 774 | if (al->map != NULL) |
744 | al->sym = map__find_symbol(al->map, al->addr, filter); | 775 | al->sym = map__find_symbol(al->map, al->addr, filter); |
745 | else | 776 | else |
@@ -747,13 +778,13 @@ void thread__find_addr_location(struct thread *self, | |||
747 | } | 778 | } |
748 | 779 | ||
749 | int perf_event__preprocess_sample(const union perf_event *event, | 780 | int perf_event__preprocess_sample(const union perf_event *event, |
750 | struct perf_session *session, | 781 | struct machine *machine, |
751 | struct addr_location *al, | 782 | struct addr_location *al, |
752 | struct perf_sample *sample, | 783 | struct perf_sample *sample, |
753 | symbol_filter_t filter) | 784 | symbol_filter_t filter) |
754 | { | 785 | { |
755 | u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; | 786 | u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; |
756 | struct thread *thread = perf_session__findnew(session, event->ip.pid); | 787 | struct thread *thread = machine__findnew_thread(machine, event->ip.pid); |
757 | 788 | ||
758 | if (thread == NULL) | 789 | if (thread == NULL) |
759 | return -1; | 790 | return -1; |
@@ -764,18 +795,18 @@ int perf_event__preprocess_sample(const union perf_event *event, | |||
764 | 795 | ||
765 | dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); | 796 | dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); |
766 | /* | 797 | /* |
767 | * Have we already created the kernel maps for the host machine? | 798 | * Have we already created the kernel maps for this machine? |
768 | * | 799 | * |
769 | * This should have happened earlier, when we processed the kernel MMAP | 800 | * This should have happened earlier, when we processed the kernel MMAP |
770 | * events, but for older perf.data files there was no such thing, so do | 801 | * events, but for older perf.data files there was no such thing, so do |
771 | * it now. | 802 | * it now. |
772 | */ | 803 | */ |
773 | if (cpumode == PERF_RECORD_MISC_KERNEL && | 804 | if (cpumode == PERF_RECORD_MISC_KERNEL && |
774 | session->host_machine.vmlinux_maps[MAP__FUNCTION] == NULL) | 805 | machine->vmlinux_maps[MAP__FUNCTION] == NULL) |
775 | machine__create_kernel_maps(&session->host_machine); | 806 | machine__create_kernel_maps(machine); |
776 | 807 | ||
777 | thread__find_addr_map(thread, session, cpumode, MAP__FUNCTION, | 808 | thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION, |
778 | event->ip.pid, event->ip.ip, al); | 809 | event->ip.ip, al); |
779 | dump_printf(" ...... dso: %s\n", | 810 | dump_printf(" ...... dso: %s\n", |
780 | al->map ? al->map->dso->long_name : | 811 | al->map ? al->map->dso->long_name : |
781 | al->level == 'H' ? "[hypervisor]" : "<not found>"); | 812 | al->level == 'H' ? "[hypervisor]" : "<not found>"); |