diff options
Diffstat (limited to 'tools/perf/util/event.c')
-rw-r--r-- | tools/perf/util/event.c | 374 |
1 files changed, 103 insertions, 271 deletions
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 50d0a931497a..2b15c362ef56 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c | |||
@@ -6,8 +6,9 @@ | |||
6 | #include "string.h" | 6 | #include "string.h" |
7 | #include "strlist.h" | 7 | #include "strlist.h" |
8 | #include "thread.h" | 8 | #include "thread.h" |
9 | #include "thread_map.h" | ||
9 | 10 | ||
10 | static const char *event__name[] = { | 11 | static const char *perf_event__names[] = { |
11 | [0] = "TOTAL", | 12 | [0] = "TOTAL", |
12 | [PERF_RECORD_MMAP] = "MMAP", | 13 | [PERF_RECORD_MMAP] = "MMAP", |
13 | [PERF_RECORD_LOST] = "LOST", | 14 | [PERF_RECORD_LOST] = "LOST", |
@@ -25,16 +26,16 @@ static const char *event__name[] = { | |||
25 | [PERF_RECORD_FINISHED_ROUND] = "FINISHED_ROUND", | 26 | [PERF_RECORD_FINISHED_ROUND] = "FINISHED_ROUND", |
26 | }; | 27 | }; |
27 | 28 | ||
28 | const char *event__get_event_name(unsigned int id) | 29 | const char *perf_event__name(unsigned int id) |
29 | { | 30 | { |
30 | if (id >= ARRAY_SIZE(event__name)) | 31 | if (id >= ARRAY_SIZE(perf_event__names)) |
31 | return "INVALID"; | 32 | return "INVALID"; |
32 | if (!event__name[id]) | 33 | if (!perf_event__names[id]) |
33 | return "UNKNOWN"; | 34 | return "UNKNOWN"; |
34 | return event__name[id]; | 35 | return perf_event__names[id]; |
35 | } | 36 | } |
36 | 37 | ||
37 | static struct sample_data synth_sample = { | 38 | static struct perf_sample synth_sample = { |
38 | .pid = -1, | 39 | .pid = -1, |
39 | .tid = -1, | 40 | .tid = -1, |
40 | .time = -1, | 41 | .time = -1, |
@@ -43,9 +44,9 @@ static struct sample_data synth_sample = { | |||
43 | .period = 1, | 44 | .period = 1, |
44 | }; | 45 | }; |
45 | 46 | ||
46 | static pid_t event__synthesize_comm(event_t *event, pid_t pid, int full, | 47 | static pid_t perf_event__synthesize_comm(union perf_event *event, pid_t pid, |
47 | event__handler_t process, | 48 | int full, perf_event__handler_t process, |
48 | struct perf_session *session) | 49 | struct perf_session *session) |
49 | { | 50 | { |
50 | char filename[PATH_MAX]; | 51 | char filename[PATH_MAX]; |
51 | char bf[BUFSIZ]; | 52 | char bf[BUFSIZ]; |
@@ -126,9 +127,10 @@ out: | |||
126 | return tgid; | 127 | return tgid; |
127 | } | 128 | } |
128 | 129 | ||
129 | static int event__synthesize_mmap_events(event_t *event, pid_t pid, pid_t tgid, | 130 | static int perf_event__synthesize_mmap_events(union perf_event *event, |
130 | event__handler_t process, | 131 | pid_t pid, pid_t tgid, |
131 | struct perf_session *session) | 132 | perf_event__handler_t process, |
133 | struct perf_session *session) | ||
132 | { | 134 | { |
133 | char filename[PATH_MAX]; | 135 | char filename[PATH_MAX]; |
134 | FILE *fp; | 136 | FILE *fp; |
@@ -199,14 +201,14 @@ static int event__synthesize_mmap_events(event_t *event, pid_t pid, pid_t tgid, | |||
199 | return 0; | 201 | return 0; |
200 | } | 202 | } |
201 | 203 | ||
202 | int event__synthesize_modules(event__handler_t process, | 204 | int perf_event__synthesize_modules(perf_event__handler_t process, |
203 | struct perf_session *session, | 205 | struct perf_session *session, |
204 | struct machine *machine) | 206 | struct machine *machine) |
205 | { | 207 | { |
206 | struct rb_node *nd; | 208 | struct rb_node *nd; |
207 | struct map_groups *kmaps = &machine->kmaps; | 209 | struct map_groups *kmaps = &machine->kmaps; |
208 | event_t *event = zalloc(sizeof(event->mmap) + session->id_hdr_size); | 210 | union perf_event *event = zalloc((sizeof(event->mmap) + |
209 | 211 | session->id_hdr_size)); | |
210 | if (event == NULL) { | 212 | if (event == NULL) { |
211 | pr_debug("Not enough memory synthesizing mmap event " | 213 | pr_debug("Not enough memory synthesizing mmap event " |
212 | "for kernel modules\n"); | 214 | "for kernel modules\n"); |
@@ -251,23 +253,24 @@ int event__synthesize_modules(event__handler_t process, | |||
251 | return 0; | 253 | return 0; |
252 | } | 254 | } |
253 | 255 | ||
254 | static int __event__synthesize_thread(event_t *comm_event, event_t *mmap_event, | 256 | static int __event__synthesize_thread(union perf_event *comm_event, |
255 | pid_t pid, event__handler_t process, | 257 | union perf_event *mmap_event, |
258 | pid_t pid, perf_event__handler_t process, | ||
256 | struct perf_session *session) | 259 | struct perf_session *session) |
257 | { | 260 | { |
258 | pid_t tgid = event__synthesize_comm(comm_event, pid, 1, process, | 261 | pid_t tgid = perf_event__synthesize_comm(comm_event, pid, 1, process, |
259 | session); | 262 | session); |
260 | if (tgid == -1) | 263 | if (tgid == -1) |
261 | return -1; | 264 | return -1; |
262 | return event__synthesize_mmap_events(mmap_event, pid, tgid, | 265 | return perf_event__synthesize_mmap_events(mmap_event, pid, tgid, |
263 | process, session); | 266 | process, session); |
264 | } | 267 | } |
265 | 268 | ||
266 | int event__synthesize_thread_map(struct thread_map *threads, | 269 | int perf_event__synthesize_thread_map(struct thread_map *threads, |
267 | event__handler_t process, | 270 | perf_event__handler_t process, |
268 | struct perf_session *session) | 271 | struct perf_session *session) |
269 | { | 272 | { |
270 | event_t *comm_event, *mmap_event; | 273 | union perf_event *comm_event, *mmap_event; |
271 | int err = -1, thread; | 274 | int err = -1, thread; |
272 | 275 | ||
273 | comm_event = malloc(sizeof(comm_event->comm) + session->id_hdr_size); | 276 | comm_event = malloc(sizeof(comm_event->comm) + session->id_hdr_size); |
@@ -294,12 +297,12 @@ out: | |||
294 | return err; | 297 | return err; |
295 | } | 298 | } |
296 | 299 | ||
297 | int event__synthesize_threads(event__handler_t process, | 300 | int perf_event__synthesize_threads(perf_event__handler_t process, |
298 | struct perf_session *session) | 301 | struct perf_session *session) |
299 | { | 302 | { |
300 | DIR *proc; | 303 | DIR *proc; |
301 | struct dirent dirent, *next; | 304 | struct dirent dirent, *next; |
302 | event_t *comm_event, *mmap_event; | 305 | union perf_event *comm_event, *mmap_event; |
303 | int err = -1; | 306 | int err = -1; |
304 | 307 | ||
305 | comm_event = malloc(sizeof(comm_event->comm) + session->id_hdr_size); | 308 | comm_event = malloc(sizeof(comm_event->comm) + session->id_hdr_size); |
@@ -357,10 +360,10 @@ static int find_symbol_cb(void *arg, const char *name, char type, | |||
357 | return 1; | 360 | return 1; |
358 | } | 361 | } |
359 | 362 | ||
360 | int event__synthesize_kernel_mmap(event__handler_t process, | 363 | int perf_event__synthesize_kernel_mmap(perf_event__handler_t process, |
361 | struct perf_session *session, | 364 | struct perf_session *session, |
362 | struct machine *machine, | 365 | struct machine *machine, |
363 | const char *symbol_name) | 366 | const char *symbol_name) |
364 | { | 367 | { |
365 | size_t size; | 368 | size_t size; |
366 | const char *filename, *mmap_name; | 369 | const char *filename, *mmap_name; |
@@ -374,8 +377,8 @@ int event__synthesize_kernel_mmap(event__handler_t process, | |||
374 | * kernels. | 377 | * kernels. |
375 | */ | 378 | */ |
376 | struct process_symbol_args args = { .name = symbol_name, }; | 379 | struct process_symbol_args args = { .name = symbol_name, }; |
377 | event_t *event = zalloc(sizeof(event->mmap) + session->id_hdr_size); | 380 | union perf_event *event = zalloc((sizeof(event->mmap) + |
378 | 381 | session->id_hdr_size)); | |
379 | if (event == NULL) { | 382 | if (event == NULL) { |
380 | pr_debug("Not enough memory synthesizing mmap event " | 383 | pr_debug("Not enough memory synthesizing mmap event " |
381 | "for kernel modules\n"); | 384 | "for kernel modules\n"); |
@@ -421,42 +424,15 @@ int event__synthesize_kernel_mmap(event__handler_t process, | |||
421 | return err; | 424 | return err; |
422 | } | 425 | } |
423 | 426 | ||
424 | static void thread__comm_adjust(struct thread *self, struct hists *hists) | 427 | int perf_event__process_comm(union perf_event *event, |
425 | { | 428 | struct perf_sample *sample __used, |
426 | char *comm = self->comm; | 429 | struct perf_session *session) |
427 | |||
428 | if (!symbol_conf.col_width_list_str && !symbol_conf.field_sep && | ||
429 | (!symbol_conf.comm_list || | ||
430 | strlist__has_entry(symbol_conf.comm_list, comm))) { | ||
431 | u16 slen = strlen(comm); | ||
432 | |||
433 | if (hists__new_col_len(hists, HISTC_COMM, slen)) | ||
434 | hists__set_col_len(hists, HISTC_THREAD, slen + 6); | ||
435 | } | ||
436 | } | ||
437 | |||
438 | static int thread__set_comm_adjust(struct thread *self, const char *comm, | ||
439 | struct hists *hists) | ||
440 | { | 430 | { |
441 | int ret = thread__set_comm(self, comm); | 431 | struct thread *thread = perf_session__findnew(session, event->comm.tid); |
442 | |||
443 | if (ret) | ||
444 | return ret; | ||
445 | |||
446 | thread__comm_adjust(self, hists); | ||
447 | 432 | ||
448 | return 0; | 433 | dump_printf(": %s:%d\n", event->comm.comm, event->comm.tid); |
449 | } | ||
450 | 434 | ||
451 | int event__process_comm(event_t *self, struct sample_data *sample __used, | 435 | if (thread == NULL || thread__set_comm(thread, event->comm.comm)) { |
452 | struct perf_session *session) | ||
453 | { | ||
454 | struct thread *thread = perf_session__findnew(session, self->comm.tid); | ||
455 | |||
456 | dump_printf(": %s:%d\n", self->comm.comm, self->comm.tid); | ||
457 | |||
458 | if (thread == NULL || thread__set_comm_adjust(thread, self->comm.comm, | ||
459 | &session->hists)) { | ||
460 | dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n"); | 436 | dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n"); |
461 | return -1; | 437 | return -1; |
462 | } | 438 | } |
@@ -464,19 +440,21 @@ int event__process_comm(event_t *self, struct sample_data *sample __used, | |||
464 | return 0; | 440 | return 0; |
465 | } | 441 | } |
466 | 442 | ||
467 | int event__process_lost(event_t *self, struct sample_data *sample __used, | 443 | int perf_event__process_lost(union perf_event *event, |
468 | struct perf_session *session) | 444 | struct perf_sample *sample __used, |
445 | struct perf_session *session) | ||
469 | { | 446 | { |
470 | dump_printf(": id:%" PRIu64 ": lost:%" PRIu64 "\n", | 447 | dump_printf(": id:%" PRIu64 ": lost:%" PRIu64 "\n", |
471 | self->lost.id, self->lost.lost); | 448 | event->lost.id, event->lost.lost); |
472 | session->hists.stats.total_lost += self->lost.lost; | 449 | session->hists.stats.total_lost += event->lost.lost; |
473 | return 0; | 450 | return 0; |
474 | } | 451 | } |
475 | 452 | ||
476 | static void event_set_kernel_mmap_len(struct map **maps, event_t *self) | 453 | static void perf_event__set_kernel_mmap_len(union perf_event *event, |
454 | struct map **maps) | ||
477 | { | 455 | { |
478 | maps[MAP__FUNCTION]->start = self->mmap.start; | 456 | maps[MAP__FUNCTION]->start = event->mmap.start; |
479 | maps[MAP__FUNCTION]->end = self->mmap.start + self->mmap.len; | 457 | maps[MAP__FUNCTION]->end = event->mmap.start + event->mmap.len; |
480 | /* | 458 | /* |
481 | * Be a bit paranoid here, some perf.data file came with | 459 | * Be a bit paranoid here, some perf.data file came with |
482 | * a zero sized synthesized MMAP event for the kernel. | 460 | * a zero sized synthesized MMAP event for the kernel. |
@@ -485,8 +463,8 @@ static void event_set_kernel_mmap_len(struct map **maps, event_t *self) | |||
485 | maps[MAP__FUNCTION]->end = ~0ULL; | 463 | maps[MAP__FUNCTION]->end = ~0ULL; |
486 | } | 464 | } |
487 | 465 | ||
488 | static int event__process_kernel_mmap(event_t *self, | 466 | static int perf_event__process_kernel_mmap(union perf_event *event, |
489 | struct perf_session *session) | 467 | struct perf_session *session) |
490 | { | 468 | { |
491 | struct map *map; | 469 | struct map *map; |
492 | char kmmap_prefix[PATH_MAX]; | 470 | char kmmap_prefix[PATH_MAX]; |
@@ -494,9 +472,9 @@ static int event__process_kernel_mmap(event_t *self, | |||
494 | enum dso_kernel_type kernel_type; | 472 | enum dso_kernel_type kernel_type; |
495 | bool is_kernel_mmap; | 473 | bool is_kernel_mmap; |
496 | 474 | ||
497 | machine = perf_session__findnew_machine(session, self->mmap.pid); | 475 | machine = perf_session__findnew_machine(session, event->mmap.pid); |
498 | if (!machine) { | 476 | if (!machine) { |
499 | pr_err("Can't find id %d's machine\n", self->mmap.pid); | 477 | pr_err("Can't find id %d's machine\n", event->mmap.pid); |
500 | goto out_problem; | 478 | goto out_problem; |
501 | } | 479 | } |
502 | 480 | ||
@@ -506,17 +484,17 @@ static int event__process_kernel_mmap(event_t *self, | |||
506 | else | 484 | else |
507 | kernel_type = DSO_TYPE_GUEST_KERNEL; | 485 | kernel_type = DSO_TYPE_GUEST_KERNEL; |
508 | 486 | ||
509 | is_kernel_mmap = memcmp(self->mmap.filename, | 487 | is_kernel_mmap = memcmp(event->mmap.filename, |
510 | kmmap_prefix, | 488 | kmmap_prefix, |
511 | strlen(kmmap_prefix)) == 0; | 489 | strlen(kmmap_prefix)) == 0; |
512 | if (self->mmap.filename[0] == '/' || | 490 | if (event->mmap.filename[0] == '/' || |
513 | (!is_kernel_mmap && self->mmap.filename[0] == '[')) { | 491 | (!is_kernel_mmap && event->mmap.filename[0] == '[')) { |
514 | 492 | ||
515 | char short_module_name[1024]; | 493 | char short_module_name[1024]; |
516 | char *name, *dot; | 494 | char *name, *dot; |
517 | 495 | ||
518 | if (self->mmap.filename[0] == '/') { | 496 | if (event->mmap.filename[0] == '/') { |
519 | name = strrchr(self->mmap.filename, '/'); | 497 | name = strrchr(event->mmap.filename, '/'); |
520 | if (name == NULL) | 498 | if (name == NULL) |
521 | goto out_problem; | 499 | goto out_problem; |
522 | 500 | ||
@@ -528,10 +506,10 @@ static int event__process_kernel_mmap(event_t *self, | |||
528 | "[%.*s]", (int)(dot - name), name); | 506 | "[%.*s]", (int)(dot - name), name); |
529 | strxfrchar(short_module_name, '-', '_'); | 507 | strxfrchar(short_module_name, '-', '_'); |
530 | } else | 508 | } else |
531 | strcpy(short_module_name, self->mmap.filename); | 509 | strcpy(short_module_name, event->mmap.filename); |
532 | 510 | ||
533 | map = machine__new_module(machine, self->mmap.start, | 511 | map = machine__new_module(machine, event->mmap.start, |
534 | self->mmap.filename); | 512 | event->mmap.filename); |
535 | if (map == NULL) | 513 | if (map == NULL) |
536 | goto out_problem; | 514 | goto out_problem; |
537 | 515 | ||
@@ -541,9 +519,9 @@ static int event__process_kernel_mmap(event_t *self, | |||
541 | 519 | ||
542 | map->dso->short_name = name; | 520 | map->dso->short_name = name; |
543 | map->dso->sname_alloc = 1; | 521 | map->dso->sname_alloc = 1; |
544 | map->end = map->start + self->mmap.len; | 522 | map->end = map->start + event->mmap.len; |
545 | } else if (is_kernel_mmap) { | 523 | } else if (is_kernel_mmap) { |
546 | const char *symbol_name = (self->mmap.filename + | 524 | const char *symbol_name = (event->mmap.filename + |
547 | strlen(kmmap_prefix)); | 525 | strlen(kmmap_prefix)); |
548 | /* | 526 | /* |
549 | * Should be there already, from the build-id table in | 527 | * Should be there already, from the build-id table in |
@@ -558,10 +536,10 @@ static int event__process_kernel_mmap(event_t *self, | |||
558 | if (__machine__create_kernel_maps(machine, kernel) < 0) | 536 | if (__machine__create_kernel_maps(machine, kernel) < 0) |
559 | goto out_problem; | 537 | goto out_problem; |
560 | 538 | ||
561 | event_set_kernel_mmap_len(machine->vmlinux_maps, self); | 539 | perf_event__set_kernel_mmap_len(event, machine->vmlinux_maps); |
562 | perf_session__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, | 540 | perf_session__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, |
563 | symbol_name, | 541 | symbol_name, |
564 | self->mmap.pgoff); | 542 | event->mmap.pgoff); |
565 | if (machine__is_default_guest(machine)) { | 543 | if (machine__is_default_guest(machine)) { |
566 | /* | 544 | /* |
567 | * preload dso of guest kernel and modules | 545 | * preload dso of guest kernel and modules |
@@ -575,22 +553,23 @@ out_problem: | |||
575 | return -1; | 553 | return -1; |
576 | } | 554 | } |
577 | 555 | ||
578 | int event__process_mmap(event_t *self, struct sample_data *sample __used, | 556 | int perf_event__process_mmap(union perf_event *event, |
579 | struct perf_session *session) | 557 | struct perf_sample *sample __used, |
558 | struct perf_session *session) | ||
580 | { | 559 | { |
581 | struct machine *machine; | 560 | struct machine *machine; |
582 | struct thread *thread; | 561 | struct thread *thread; |
583 | struct map *map; | 562 | struct map *map; |
584 | u8 cpumode = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; | 563 | u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; |
585 | int ret = 0; | 564 | int ret = 0; |
586 | 565 | ||
587 | dump_printf(" %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 "]: %s\n", | 566 | dump_printf(" %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 "]: %s\n", |
588 | self->mmap.pid, self->mmap.tid, self->mmap.start, | 567 | event->mmap.pid, event->mmap.tid, event->mmap.start, |
589 | self->mmap.len, self->mmap.pgoff, self->mmap.filename); | 568 | event->mmap.len, event->mmap.pgoff, event->mmap.filename); |
590 | 569 | ||
591 | if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL || | 570 | if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL || |
592 | cpumode == PERF_RECORD_MISC_KERNEL) { | 571 | cpumode == PERF_RECORD_MISC_KERNEL) { |
593 | ret = event__process_kernel_mmap(self, session); | 572 | ret = perf_event__process_kernel_mmap(event, session); |
594 | if (ret < 0) | 573 | if (ret < 0) |
595 | goto out_problem; | 574 | goto out_problem; |
596 | return 0; | 575 | return 0; |
@@ -599,12 +578,12 @@ int event__process_mmap(event_t *self, struct sample_data *sample __used, | |||
599 | machine = perf_session__find_host_machine(session); | 578 | machine = perf_session__find_host_machine(session); |
600 | if (machine == NULL) | 579 | if (machine == NULL) |
601 | goto out_problem; | 580 | goto out_problem; |
602 | thread = perf_session__findnew(session, self->mmap.pid); | 581 | thread = perf_session__findnew(session, event->mmap.pid); |
603 | if (thread == NULL) | 582 | if (thread == NULL) |
604 | goto out_problem; | 583 | goto out_problem; |
605 | map = map__new(&machine->user_dsos, self->mmap.start, | 584 | map = map__new(&machine->user_dsos, event->mmap.start, |
606 | self->mmap.len, self->mmap.pgoff, | 585 | event->mmap.len, event->mmap.pgoff, |
607 | self->mmap.pid, self->mmap.filename, | 586 | event->mmap.pid, event->mmap.filename, |
608 | MAP__FUNCTION); | 587 | MAP__FUNCTION); |
609 | if (map == NULL) | 588 | if (map == NULL) |
610 | goto out_problem; | 589 | goto out_problem; |
@@ -617,16 +596,17 @@ out_problem: | |||
617 | return 0; | 596 | return 0; |
618 | } | 597 | } |
619 | 598 | ||
620 | int event__process_task(event_t *self, struct sample_data *sample __used, | 599 | int perf_event__process_task(union perf_event *event, |
621 | struct perf_session *session) | 600 | struct perf_sample *sample __used, |
601 | struct perf_session *session) | ||
622 | { | 602 | { |
623 | struct thread *thread = perf_session__findnew(session, self->fork.tid); | 603 | struct thread *thread = perf_session__findnew(session, event->fork.tid); |
624 | struct thread *parent = perf_session__findnew(session, self->fork.ptid); | 604 | struct thread *parent = perf_session__findnew(session, event->fork.ptid); |
625 | 605 | ||
626 | dump_printf("(%d:%d):(%d:%d)\n", self->fork.pid, self->fork.tid, | 606 | dump_printf("(%d:%d):(%d:%d)\n", event->fork.pid, event->fork.tid, |
627 | self->fork.ppid, self->fork.ptid); | 607 | event->fork.ppid, event->fork.ptid); |
628 | 608 | ||
629 | if (self->header.type == PERF_RECORD_EXIT) { | 609 | if (event->header.type == PERF_RECORD_EXIT) { |
630 | perf_session__remove_thread(session, thread); | 610 | perf_session__remove_thread(session, thread); |
631 | return 0; | 611 | return 0; |
632 | } | 612 | } |
@@ -640,20 +620,22 @@ int event__process_task(event_t *self, struct sample_data *sample __used, | |||
640 | return 0; | 620 | return 0; |
641 | } | 621 | } |
642 | 622 | ||
643 | int event__process(event_t *event, struct sample_data *sample, | 623 | int perf_event__process(union perf_event *event, struct perf_sample *sample, |
644 | struct perf_session *session) | 624 | struct perf_session *session) |
645 | { | 625 | { |
646 | switch (event->header.type) { | 626 | switch (event->header.type) { |
647 | case PERF_RECORD_COMM: | 627 | case PERF_RECORD_COMM: |
648 | event__process_comm(event, sample, session); | 628 | perf_event__process_comm(event, sample, session); |
649 | break; | 629 | break; |
650 | case PERF_RECORD_MMAP: | 630 | case PERF_RECORD_MMAP: |
651 | event__process_mmap(event, sample, session); | 631 | perf_event__process_mmap(event, sample, session); |
652 | break; | 632 | break; |
653 | case PERF_RECORD_FORK: | 633 | case PERF_RECORD_FORK: |
654 | case PERF_RECORD_EXIT: | 634 | case PERF_RECORD_EXIT: |
655 | event__process_task(event, sample, session); | 635 | perf_event__process_task(event, sample, session); |
656 | break; | 636 | break; |
637 | case PERF_RECORD_LOST: | ||
638 | perf_event__process_lost(event, sample, session); | ||
657 | default: | 639 | default: |
658 | break; | 640 | break; |
659 | } | 641 | } |
@@ -750,24 +732,14 @@ void thread__find_addr_location(struct thread *self, | |||
750 | al->sym = NULL; | 732 | al->sym = NULL; |
751 | } | 733 | } |
752 | 734 | ||
753 | static void dso__calc_col_width(struct dso *self, struct hists *hists) | 735 | int perf_event__preprocess_sample(const union perf_event *event, |
754 | { | 736 | struct perf_session *session, |
755 | if (!symbol_conf.col_width_list_str && !symbol_conf.field_sep && | 737 | struct addr_location *al, |
756 | (!symbol_conf.dso_list || | 738 | struct perf_sample *sample, |
757 | strlist__has_entry(symbol_conf.dso_list, self->name))) { | 739 | symbol_filter_t filter) |
758 | u16 slen = dso__name_len(self); | ||
759 | hists__new_col_len(hists, HISTC_DSO, slen); | ||
760 | } | ||
761 | |||
762 | self->slen_calculated = 1; | ||
763 | } | ||
764 | |||
765 | int event__preprocess_sample(const event_t *self, struct perf_session *session, | ||
766 | struct addr_location *al, struct sample_data *data, | ||
767 | symbol_filter_t filter) | ||
768 | { | 740 | { |
769 | u8 cpumode = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; | 741 | u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; |
770 | struct thread *thread = perf_session__findnew(session, self->ip.pid); | 742 | struct thread *thread = perf_session__findnew(session, event->ip.pid); |
771 | 743 | ||
772 | if (thread == NULL) | 744 | if (thread == NULL) |
773 | return -1; | 745 | return -1; |
@@ -789,12 +761,12 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session, | |||
789 | machine__create_kernel_maps(&session->host_machine); | 761 | machine__create_kernel_maps(&session->host_machine); |
790 | 762 | ||
791 | thread__find_addr_map(thread, session, cpumode, MAP__FUNCTION, | 763 | thread__find_addr_map(thread, session, cpumode, MAP__FUNCTION, |
792 | self->ip.pid, self->ip.ip, al); | 764 | event->ip.pid, event->ip.ip, al); |
793 | dump_printf(" ...... dso: %s\n", | 765 | dump_printf(" ...... dso: %s\n", |
794 | al->map ? al->map->dso->long_name : | 766 | al->map ? al->map->dso->long_name : |
795 | al->level == 'H' ? "[hypervisor]" : "<not found>"); | 767 | al->level == 'H' ? "[hypervisor]" : "<not found>"); |
796 | al->sym = NULL; | 768 | al->sym = NULL; |
797 | al->cpu = data->cpu; | 769 | al->cpu = sample->cpu; |
798 | 770 | ||
799 | if (al->map) { | 771 | if (al->map) { |
800 | if (symbol_conf.dso_list && | 772 | if (symbol_conf.dso_list && |
@@ -805,23 +777,8 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session, | |||
805 | strlist__has_entry(symbol_conf.dso_list, | 777 | strlist__has_entry(symbol_conf.dso_list, |
806 | al->map->dso->long_name))))) | 778 | al->map->dso->long_name))))) |
807 | goto out_filtered; | 779 | goto out_filtered; |
808 | /* | ||
809 | * We have to do this here as we may have a dso with no symbol | ||
810 | * hit that has a name longer than the ones with symbols | ||
811 | * sampled. | ||
812 | */ | ||
813 | if (!sort_dso.elide && !al->map->dso->slen_calculated) | ||
814 | dso__calc_col_width(al->map->dso, &session->hists); | ||
815 | 780 | ||
816 | al->sym = map__find_symbol(al->map, al->addr, filter); | 781 | al->sym = map__find_symbol(al->map, al->addr, filter); |
817 | } else { | ||
818 | const unsigned int unresolved_col_width = BITS_PER_LONG / 4; | ||
819 | |||
820 | if (hists__col_len(&session->hists, HISTC_DSO) < unresolved_col_width && | ||
821 | !symbol_conf.col_width_list_str && !symbol_conf.field_sep && | ||
822 | !symbol_conf.dso_list) | ||
823 | hists__set_col_len(&session->hists, HISTC_DSO, | ||
824 | unresolved_col_width); | ||
825 | } | 782 | } |
826 | 783 | ||
827 | if (symbol_conf.sym_list && al->sym && | 784 | if (symbol_conf.sym_list && al->sym && |
@@ -834,128 +791,3 @@ out_filtered: | |||
834 | al->filtered = true; | 791 | al->filtered = true; |
835 | return 0; | 792 | return 0; |
836 | } | 793 | } |
837 | |||
838 | static int event__parse_id_sample(const event_t *event, | ||
839 | struct perf_session *session, | ||
840 | struct sample_data *sample) | ||
841 | { | ||
842 | const u64 *array; | ||
843 | u64 type; | ||
844 | |||
845 | sample->cpu = sample->pid = sample->tid = -1; | ||
846 | sample->stream_id = sample->id = sample->time = -1ULL; | ||
847 | |||
848 | if (!session->sample_id_all) | ||
849 | return 0; | ||
850 | |||
851 | array = event->sample.array; | ||
852 | array += ((event->header.size - | ||
853 | sizeof(event->header)) / sizeof(u64)) - 1; | ||
854 | type = session->sample_type; | ||
855 | |||
856 | if (type & PERF_SAMPLE_CPU) { | ||
857 | u32 *p = (u32 *)array; | ||
858 | sample->cpu = *p; | ||
859 | array--; | ||
860 | } | ||
861 | |||
862 | if (type & PERF_SAMPLE_STREAM_ID) { | ||
863 | sample->stream_id = *array; | ||
864 | array--; | ||
865 | } | ||
866 | |||
867 | if (type & PERF_SAMPLE_ID) { | ||
868 | sample->id = *array; | ||
869 | array--; | ||
870 | } | ||
871 | |||
872 | if (type & PERF_SAMPLE_TIME) { | ||
873 | sample->time = *array; | ||
874 | array--; | ||
875 | } | ||
876 | |||
877 | if (type & PERF_SAMPLE_TID) { | ||
878 | u32 *p = (u32 *)array; | ||
879 | sample->pid = p[0]; | ||
880 | sample->tid = p[1]; | ||
881 | } | ||
882 | |||
883 | return 0; | ||
884 | } | ||
885 | |||
886 | int event__parse_sample(const event_t *event, struct perf_session *session, | ||
887 | struct sample_data *data) | ||
888 | { | ||
889 | const u64 *array; | ||
890 | u64 type; | ||
891 | |||
892 | if (event->header.type != PERF_RECORD_SAMPLE) | ||
893 | return event__parse_id_sample(event, session, data); | ||
894 | |||
895 | array = event->sample.array; | ||
896 | type = session->sample_type; | ||
897 | |||
898 | if (type & PERF_SAMPLE_IP) { | ||
899 | data->ip = event->ip.ip; | ||
900 | array++; | ||
901 | } | ||
902 | |||
903 | if (type & PERF_SAMPLE_TID) { | ||
904 | u32 *p = (u32 *)array; | ||
905 | data->pid = p[0]; | ||
906 | data->tid = p[1]; | ||
907 | array++; | ||
908 | } | ||
909 | |||
910 | if (type & PERF_SAMPLE_TIME) { | ||
911 | data->time = *array; | ||
912 | array++; | ||
913 | } | ||
914 | |||
915 | if (type & PERF_SAMPLE_ADDR) { | ||
916 | data->addr = *array; | ||
917 | array++; | ||
918 | } | ||
919 | |||
920 | data->id = -1ULL; | ||
921 | if (type & PERF_SAMPLE_ID) { | ||
922 | data->id = *array; | ||
923 | array++; | ||
924 | } | ||
925 | |||
926 | if (type & PERF_SAMPLE_STREAM_ID) { | ||
927 | data->stream_id = *array; | ||
928 | array++; | ||
929 | } | ||
930 | |||
931 | if (type & PERF_SAMPLE_CPU) { | ||
932 | u32 *p = (u32 *)array; | ||
933 | data->cpu = *p; | ||
934 | array++; | ||
935 | } else | ||
936 | data->cpu = -1; | ||
937 | |||
938 | if (type & PERF_SAMPLE_PERIOD) { | ||
939 | data->period = *array; | ||
940 | array++; | ||
941 | } | ||
942 | |||
943 | if (type & PERF_SAMPLE_READ) { | ||
944 | pr_debug("PERF_SAMPLE_READ is unsuported for now\n"); | ||
945 | return -1; | ||
946 | } | ||
947 | |||
948 | if (type & PERF_SAMPLE_CALLCHAIN) { | ||
949 | data->callchain = (struct ip_callchain *)array; | ||
950 | array += 1 + data->callchain->nr; | ||
951 | } | ||
952 | |||
953 | if (type & PERF_SAMPLE_RAW) { | ||
954 | u32 *p = (u32 *)array; | ||
955 | data->raw_size = *p; | ||
956 | p++; | ||
957 | data->raw_data = p; | ||
958 | } | ||
959 | |||
960 | return 0; | ||
961 | } | ||