diff options
Diffstat (limited to 'tools/perf/util/event.c')
-rw-r--r-- | tools/perf/util/event.c | 391 |
1 files changed, 116 insertions, 275 deletions
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 2302ec051bb4..1023f67633a4 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,25 @@ 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(pid_t pid, event__handler_t process, | 269 | int perf_event__synthesize_thread_map(struct thread_map *threads, |
267 | struct perf_session *session) | 270 | perf_event__handler_t process, |
271 | struct perf_session *session) | ||
268 | { | 272 | { |
269 | event_t *comm_event, *mmap_event; | 273 | union perf_event *comm_event, *mmap_event; |
270 | int err = -1; | 274 | int err = -1, thread; |
271 | 275 | ||
272 | comm_event = malloc(sizeof(comm_event->comm) + session->id_hdr_size); | 276 | comm_event = malloc(sizeof(comm_event->comm) + session->id_hdr_size); |
273 | if (comm_event == NULL) | 277 | if (comm_event == NULL) |
@@ -277,8 +281,15 @@ int event__synthesize_thread(pid_t pid, event__handler_t process, | |||
277 | if (mmap_event == NULL) | 281 | if (mmap_event == NULL) |
278 | goto out_free_comm; | 282 | goto out_free_comm; |
279 | 283 | ||
280 | err = __event__synthesize_thread(comm_event, mmap_event, pid, | 284 | err = 0; |
281 | process, session); | 285 | for (thread = 0; thread < threads->nr; ++thread) { |
286 | if (__event__synthesize_thread(comm_event, mmap_event, | ||
287 | threads->map[thread], | ||
288 | process, session)) { | ||
289 | err = -1; | ||
290 | break; | ||
291 | } | ||
292 | } | ||
282 | free(mmap_event); | 293 | free(mmap_event); |
283 | out_free_comm: | 294 | out_free_comm: |
284 | free(comm_event); | 295 | free(comm_event); |
@@ -286,12 +297,12 @@ out: | |||
286 | return err; | 297 | return err; |
287 | } | 298 | } |
288 | 299 | ||
289 | int event__synthesize_threads(event__handler_t process, | 300 | int perf_event__synthesize_threads(perf_event__handler_t process, |
290 | struct perf_session *session) | 301 | struct perf_session *session) |
291 | { | 302 | { |
292 | DIR *proc; | 303 | DIR *proc; |
293 | struct dirent dirent, *next; | 304 | struct dirent dirent, *next; |
294 | event_t *comm_event, *mmap_event; | 305 | union perf_event *comm_event, *mmap_event; |
295 | int err = -1; | 306 | int err = -1; |
296 | 307 | ||
297 | comm_event = malloc(sizeof(comm_event->comm) + session->id_hdr_size); | 308 | comm_event = malloc(sizeof(comm_event->comm) + session->id_hdr_size); |
@@ -349,10 +360,10 @@ static int find_symbol_cb(void *arg, const char *name, char type, | |||
349 | return 1; | 360 | return 1; |
350 | } | 361 | } |
351 | 362 | ||
352 | int event__synthesize_kernel_mmap(event__handler_t process, | 363 | int perf_event__synthesize_kernel_mmap(perf_event__handler_t process, |
353 | struct perf_session *session, | 364 | struct perf_session *session, |
354 | struct machine *machine, | 365 | struct machine *machine, |
355 | const char *symbol_name) | 366 | const char *symbol_name) |
356 | { | 367 | { |
357 | size_t size; | 368 | size_t size; |
358 | const char *filename, *mmap_name; | 369 | const char *filename, *mmap_name; |
@@ -366,8 +377,8 @@ int event__synthesize_kernel_mmap(event__handler_t process, | |||
366 | * kernels. | 377 | * kernels. |
367 | */ | 378 | */ |
368 | struct process_symbol_args args = { .name = symbol_name, }; | 379 | struct process_symbol_args args = { .name = symbol_name, }; |
369 | event_t *event = zalloc(sizeof(event->mmap) + session->id_hdr_size); | 380 | union perf_event *event = zalloc((sizeof(event->mmap) + |
370 | 381 | session->id_hdr_size)); | |
371 | if (event == NULL) { | 382 | if (event == NULL) { |
372 | pr_debug("Not enough memory synthesizing mmap event " | 383 | pr_debug("Not enough memory synthesizing mmap event " |
373 | "for kernel modules\n"); | 384 | "for kernel modules\n"); |
@@ -413,42 +424,15 @@ int event__synthesize_kernel_mmap(event__handler_t process, | |||
413 | return err; | 424 | return err; |
414 | } | 425 | } |
415 | 426 | ||
416 | static void thread__comm_adjust(struct thread *self, struct hists *hists) | 427 | int perf_event__process_comm(union perf_event *event, |
417 | { | 428 | struct perf_sample *sample __used, |
418 | char *comm = self->comm; | 429 | struct perf_session *session) |
419 | |||
420 | if (!symbol_conf.col_width_list_str && !symbol_conf.field_sep && | ||
421 | (!symbol_conf.comm_list || | ||
422 | strlist__has_entry(symbol_conf.comm_list, comm))) { | ||
423 | u16 slen = strlen(comm); | ||
424 | |||
425 | if (hists__new_col_len(hists, HISTC_COMM, slen)) | ||
426 | hists__set_col_len(hists, HISTC_THREAD, slen + 6); | ||
427 | } | ||
428 | } | ||
429 | |||
430 | static int thread__set_comm_adjust(struct thread *self, const char *comm, | ||
431 | struct hists *hists) | ||
432 | { | ||
433 | int ret = thread__set_comm(self, comm); | ||
434 | |||
435 | if (ret) | ||
436 | return ret; | ||
437 | |||
438 | thread__comm_adjust(self, hists); | ||
439 | |||
440 | return 0; | ||
441 | } | ||
442 | |||
443 | int event__process_comm(event_t *self, struct sample_data *sample __used, | ||
444 | struct perf_session *session) | ||
445 | { | 430 | { |
446 | struct thread *thread = perf_session__findnew(session, self->comm.tid); | 431 | struct thread *thread = perf_session__findnew(session, event->comm.tid); |
447 | 432 | ||
448 | dump_printf(": %s:%d\n", self->comm.comm, self->comm.tid); | 433 | dump_printf(": %s:%d\n", event->comm.comm, event->comm.tid); |
449 | 434 | ||
450 | if (thread == NULL || thread__set_comm_adjust(thread, self->comm.comm, | 435 | if (thread == NULL || thread__set_comm(thread, event->comm.comm)) { |
451 | &session->hists)) { | ||
452 | dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n"); | 436 | dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n"); |
453 | return -1; | 437 | return -1; |
454 | } | 438 | } |
@@ -456,18 +440,21 @@ int event__process_comm(event_t *self, struct sample_data *sample __used, | |||
456 | return 0; | 440 | return 0; |
457 | } | 441 | } |
458 | 442 | ||
459 | int event__process_lost(event_t *self, struct sample_data *sample __used, | 443 | int perf_event__process_lost(union perf_event *event, |
460 | struct perf_session *session) | 444 | struct perf_sample *sample __used, |
445 | struct perf_session *session) | ||
461 | { | 446 | { |
462 | dump_printf(": id:%Ld: lost:%Ld\n", self->lost.id, self->lost.lost); | 447 | dump_printf(": id:%" PRIu64 ": lost:%" PRIu64 "\n", |
463 | session->hists.stats.total_lost += self->lost.lost; | 448 | event->lost.id, event->lost.lost); |
449 | session->hists.stats.total_lost += event->lost.lost; | ||
464 | return 0; | 450 | return 0; |
465 | } | 451 | } |
466 | 452 | ||
467 | 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) | ||
468 | { | 455 | { |
469 | maps[MAP__FUNCTION]->start = self->mmap.start; | 456 | maps[MAP__FUNCTION]->start = event->mmap.start; |
470 | maps[MAP__FUNCTION]->end = self->mmap.start + self->mmap.len; | 457 | maps[MAP__FUNCTION]->end = event->mmap.start + event->mmap.len; |
471 | /* | 458 | /* |
472 | * Be a bit paranoid here, some perf.data file came with | 459 | * Be a bit paranoid here, some perf.data file came with |
473 | * a zero sized synthesized MMAP event for the kernel. | 460 | * a zero sized synthesized MMAP event for the kernel. |
@@ -476,8 +463,8 @@ static void event_set_kernel_mmap_len(struct map **maps, event_t *self) | |||
476 | maps[MAP__FUNCTION]->end = ~0ULL; | 463 | maps[MAP__FUNCTION]->end = ~0ULL; |
477 | } | 464 | } |
478 | 465 | ||
479 | static int event__process_kernel_mmap(event_t *self, | 466 | static int perf_event__process_kernel_mmap(union perf_event *event, |
480 | struct perf_session *session) | 467 | struct perf_session *session) |
481 | { | 468 | { |
482 | struct map *map; | 469 | struct map *map; |
483 | char kmmap_prefix[PATH_MAX]; | 470 | char kmmap_prefix[PATH_MAX]; |
@@ -485,9 +472,9 @@ static int event__process_kernel_mmap(event_t *self, | |||
485 | enum dso_kernel_type kernel_type; | 472 | enum dso_kernel_type kernel_type; |
486 | bool is_kernel_mmap; | 473 | bool is_kernel_mmap; |
487 | 474 | ||
488 | machine = perf_session__findnew_machine(session, self->mmap.pid); | 475 | machine = perf_session__findnew_machine(session, event->mmap.pid); |
489 | if (!machine) { | 476 | if (!machine) { |
490 | 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); |
491 | goto out_problem; | 478 | goto out_problem; |
492 | } | 479 | } |
493 | 480 | ||
@@ -497,17 +484,17 @@ static int event__process_kernel_mmap(event_t *self, | |||
497 | else | 484 | else |
498 | kernel_type = DSO_TYPE_GUEST_KERNEL; | 485 | kernel_type = DSO_TYPE_GUEST_KERNEL; |
499 | 486 | ||
500 | is_kernel_mmap = memcmp(self->mmap.filename, | 487 | is_kernel_mmap = memcmp(event->mmap.filename, |
501 | kmmap_prefix, | 488 | kmmap_prefix, |
502 | strlen(kmmap_prefix)) == 0; | 489 | strlen(kmmap_prefix)) == 0; |
503 | if (self->mmap.filename[0] == '/' || | 490 | if (event->mmap.filename[0] == '/' || |
504 | (!is_kernel_mmap && self->mmap.filename[0] == '[')) { | 491 | (!is_kernel_mmap && event->mmap.filename[0] == '[')) { |
505 | 492 | ||
506 | char short_module_name[1024]; | 493 | char short_module_name[1024]; |
507 | char *name, *dot; | 494 | char *name, *dot; |
508 | 495 | ||
509 | if (self->mmap.filename[0] == '/') { | 496 | if (event->mmap.filename[0] == '/') { |
510 | name = strrchr(self->mmap.filename, '/'); | 497 | name = strrchr(event->mmap.filename, '/'); |
511 | if (name == NULL) | 498 | if (name == NULL) |
512 | goto out_problem; | 499 | goto out_problem; |
513 | 500 | ||
@@ -519,10 +506,10 @@ static int event__process_kernel_mmap(event_t *self, | |||
519 | "[%.*s]", (int)(dot - name), name); | 506 | "[%.*s]", (int)(dot - name), name); |
520 | strxfrchar(short_module_name, '-', '_'); | 507 | strxfrchar(short_module_name, '-', '_'); |
521 | } else | 508 | } else |
522 | strcpy(short_module_name, self->mmap.filename); | 509 | strcpy(short_module_name, event->mmap.filename); |
523 | 510 | ||
524 | map = machine__new_module(machine, self->mmap.start, | 511 | map = machine__new_module(machine, event->mmap.start, |
525 | self->mmap.filename); | 512 | event->mmap.filename); |
526 | if (map == NULL) | 513 | if (map == NULL) |
527 | goto out_problem; | 514 | goto out_problem; |
528 | 515 | ||
@@ -532,9 +519,9 @@ static int event__process_kernel_mmap(event_t *self, | |||
532 | 519 | ||
533 | map->dso->short_name = name; | 520 | map->dso->short_name = name; |
534 | map->dso->sname_alloc = 1; | 521 | map->dso->sname_alloc = 1; |
535 | map->end = map->start + self->mmap.len; | 522 | map->end = map->start + event->mmap.len; |
536 | } else if (is_kernel_mmap) { | 523 | } else if (is_kernel_mmap) { |
537 | const char *symbol_name = (self->mmap.filename + | 524 | const char *symbol_name = (event->mmap.filename + |
538 | strlen(kmmap_prefix)); | 525 | strlen(kmmap_prefix)); |
539 | /* | 526 | /* |
540 | * Should be there already, from the build-id table in | 527 | * Should be there already, from the build-id table in |
@@ -549,10 +536,10 @@ static int event__process_kernel_mmap(event_t *self, | |||
549 | if (__machine__create_kernel_maps(machine, kernel) < 0) | 536 | if (__machine__create_kernel_maps(machine, kernel) < 0) |
550 | goto out_problem; | 537 | goto out_problem; |
551 | 538 | ||
552 | event_set_kernel_mmap_len(machine->vmlinux_maps, self); | 539 | perf_event__set_kernel_mmap_len(event, machine->vmlinux_maps); |
553 | perf_session__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, | 540 | perf_session__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps, |
554 | symbol_name, | 541 | symbol_name, |
555 | self->mmap.pgoff); | 542 | event->mmap.pgoff); |
556 | if (machine__is_default_guest(machine)) { | 543 | if (machine__is_default_guest(machine)) { |
557 | /* | 544 | /* |
558 | * preload dso of guest kernel and modules | 545 | * preload dso of guest kernel and modules |
@@ -566,22 +553,23 @@ out_problem: | |||
566 | return -1; | 553 | return -1; |
567 | } | 554 | } |
568 | 555 | ||
569 | int event__process_mmap(event_t *self, struct sample_data *sample __used, | 556 | int perf_event__process_mmap(union perf_event *event, |
570 | struct perf_session *session) | 557 | struct perf_sample *sample __used, |
558 | struct perf_session *session) | ||
571 | { | 559 | { |
572 | struct machine *machine; | 560 | struct machine *machine; |
573 | struct thread *thread; | 561 | struct thread *thread; |
574 | struct map *map; | 562 | struct map *map; |
575 | u8 cpumode = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; | 563 | u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; |
576 | int ret = 0; | 564 | int ret = 0; |
577 | 565 | ||
578 | dump_printf(" %d/%d: [%#Lx(%#Lx) @ %#Lx]: %s\n", | 566 | dump_printf(" %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 "]: %s\n", |
579 | self->mmap.pid, self->mmap.tid, self->mmap.start, | 567 | event->mmap.pid, event->mmap.tid, event->mmap.start, |
580 | self->mmap.len, self->mmap.pgoff, self->mmap.filename); | 568 | event->mmap.len, event->mmap.pgoff, event->mmap.filename); |
581 | 569 | ||
582 | if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL || | 570 | if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL || |
583 | cpumode == PERF_RECORD_MISC_KERNEL) { | 571 | cpumode == PERF_RECORD_MISC_KERNEL) { |
584 | ret = event__process_kernel_mmap(self, session); | 572 | ret = perf_event__process_kernel_mmap(event, session); |
585 | if (ret < 0) | 573 | if (ret < 0) |
586 | goto out_problem; | 574 | goto out_problem; |
587 | return 0; | 575 | return 0; |
@@ -590,12 +578,12 @@ int event__process_mmap(event_t *self, struct sample_data *sample __used, | |||
590 | machine = perf_session__find_host_machine(session); | 578 | machine = perf_session__find_host_machine(session); |
591 | if (machine == NULL) | 579 | if (machine == NULL) |
592 | goto out_problem; | 580 | goto out_problem; |
593 | thread = perf_session__findnew(session, self->mmap.pid); | 581 | thread = perf_session__findnew(session, event->mmap.pid); |
594 | if (thread == NULL) | 582 | if (thread == NULL) |
595 | goto out_problem; | 583 | goto out_problem; |
596 | map = map__new(&machine->user_dsos, self->mmap.start, | 584 | map = map__new(&machine->user_dsos, event->mmap.start, |
597 | self->mmap.len, self->mmap.pgoff, | 585 | event->mmap.len, event->mmap.pgoff, |
598 | self->mmap.pid, self->mmap.filename, | 586 | event->mmap.pid, event->mmap.filename, |
599 | MAP__FUNCTION); | 587 | MAP__FUNCTION); |
600 | if (map == NULL) | 588 | if (map == NULL) |
601 | goto out_problem; | 589 | goto out_problem; |
@@ -608,16 +596,17 @@ out_problem: | |||
608 | return 0; | 596 | return 0; |
609 | } | 597 | } |
610 | 598 | ||
611 | int event__process_task(event_t *self, struct sample_data *sample __used, | 599 | int perf_event__process_task(union perf_event *event, |
612 | struct perf_session *session) | 600 | struct perf_sample *sample __used, |
601 | struct perf_session *session) | ||
613 | { | 602 | { |
614 | struct thread *thread = perf_session__findnew(session, self->fork.tid); | 603 | struct thread *thread = perf_session__findnew(session, event->fork.tid); |
615 | struct thread *parent = perf_session__findnew(session, self->fork.ptid); | 604 | struct thread *parent = perf_session__findnew(session, event->fork.ptid); |
616 | 605 | ||
617 | 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, |
618 | self->fork.ppid, self->fork.ptid); | 607 | event->fork.ppid, event->fork.ptid); |
619 | 608 | ||
620 | if (self->header.type == PERF_RECORD_EXIT) { | 609 | if (event->header.type == PERF_RECORD_EXIT) { |
621 | perf_session__remove_thread(session, thread); | 610 | perf_session__remove_thread(session, thread); |
622 | return 0; | 611 | return 0; |
623 | } | 612 | } |
@@ -631,20 +620,22 @@ int event__process_task(event_t *self, struct sample_data *sample __used, | |||
631 | return 0; | 620 | return 0; |
632 | } | 621 | } |
633 | 622 | ||
634 | int event__process(event_t *event, struct sample_data *sample, | 623 | int perf_event__process(union perf_event *event, struct perf_sample *sample, |
635 | struct perf_session *session) | 624 | struct perf_session *session) |
636 | { | 625 | { |
637 | switch (event->header.type) { | 626 | switch (event->header.type) { |
638 | case PERF_RECORD_COMM: | 627 | case PERF_RECORD_COMM: |
639 | event__process_comm(event, sample, session); | 628 | perf_event__process_comm(event, sample, session); |
640 | break; | 629 | break; |
641 | case PERF_RECORD_MMAP: | 630 | case PERF_RECORD_MMAP: |
642 | event__process_mmap(event, sample, session); | 631 | perf_event__process_mmap(event, sample, session); |
643 | break; | 632 | break; |
644 | case PERF_RECORD_FORK: | 633 | case PERF_RECORD_FORK: |
645 | case PERF_RECORD_EXIT: | 634 | case PERF_RECORD_EXIT: |
646 | event__process_task(event, sample, session); | 635 | perf_event__process_task(event, sample, session); |
647 | break; | 636 | break; |
637 | case PERF_RECORD_LOST: | ||
638 | perf_event__process_lost(event, sample, session); | ||
648 | default: | 639 | default: |
649 | break; | 640 | break; |
650 | } | 641 | } |
@@ -719,7 +710,7 @@ try_again: | |||
719 | * in the whole kernel symbol list. | 710 | * in the whole kernel symbol list. |
720 | */ | 711 | */ |
721 | if ((long long)al->addr < 0 && | 712 | if ((long long)al->addr < 0 && |
722 | cpumode == PERF_RECORD_MISC_KERNEL && | 713 | cpumode == PERF_RECORD_MISC_USER && |
723 | machine && mg != &machine->kmaps) { | 714 | machine && mg != &machine->kmaps) { |
724 | mg = &machine->kmaps; | 715 | mg = &machine->kmaps; |
725 | goto try_again; | 716 | goto try_again; |
@@ -741,24 +732,14 @@ void thread__find_addr_location(struct thread *self, | |||
741 | al->sym = NULL; | 732 | al->sym = NULL; |
742 | } | 733 | } |
743 | 734 | ||
744 | static void dso__calc_col_width(struct dso *self, struct hists *hists) | 735 | int perf_event__preprocess_sample(const union perf_event *event, |
745 | { | 736 | struct perf_session *session, |
746 | if (!symbol_conf.col_width_list_str && !symbol_conf.field_sep && | 737 | struct addr_location *al, |
747 | (!symbol_conf.dso_list || | 738 | struct perf_sample *sample, |
748 | strlist__has_entry(symbol_conf.dso_list, self->name))) { | 739 | symbol_filter_t filter) |
749 | u16 slen = dso__name_len(self); | ||
750 | hists__new_col_len(hists, HISTC_DSO, slen); | ||
751 | } | ||
752 | |||
753 | self->slen_calculated = 1; | ||
754 | } | ||
755 | |||
756 | int event__preprocess_sample(const event_t *self, struct perf_session *session, | ||
757 | struct addr_location *al, struct sample_data *data, | ||
758 | symbol_filter_t filter) | ||
759 | { | 740 | { |
760 | u8 cpumode = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; | 741 | u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; |
761 | struct thread *thread = perf_session__findnew(session, self->ip.pid); | 742 | struct thread *thread = perf_session__findnew(session, event->ip.pid); |
762 | 743 | ||
763 | if (thread == NULL) | 744 | if (thread == NULL) |
764 | return -1; | 745 | return -1; |
@@ -780,12 +761,12 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session, | |||
780 | machine__create_kernel_maps(&session->host_machine); | 761 | machine__create_kernel_maps(&session->host_machine); |
781 | 762 | ||
782 | thread__find_addr_map(thread, session, cpumode, MAP__FUNCTION, | 763 | thread__find_addr_map(thread, session, cpumode, MAP__FUNCTION, |
783 | self->ip.pid, self->ip.ip, al); | 764 | event->ip.pid, event->ip.ip, al); |
784 | dump_printf(" ...... dso: %s\n", | 765 | dump_printf(" ...... dso: %s\n", |
785 | al->map ? al->map->dso->long_name : | 766 | al->map ? al->map->dso->long_name : |
786 | al->level == 'H' ? "[hypervisor]" : "<not found>"); | 767 | al->level == 'H' ? "[hypervisor]" : "<not found>"); |
787 | al->sym = NULL; | 768 | al->sym = NULL; |
788 | al->cpu = data->cpu; | 769 | al->cpu = sample->cpu; |
789 | 770 | ||
790 | if (al->map) { | 771 | if (al->map) { |
791 | if (symbol_conf.dso_list && | 772 | if (symbol_conf.dso_list && |
@@ -796,23 +777,8 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session, | |||
796 | strlist__has_entry(symbol_conf.dso_list, | 777 | strlist__has_entry(symbol_conf.dso_list, |
797 | al->map->dso->long_name))))) | 778 | al->map->dso->long_name))))) |
798 | goto out_filtered; | 779 | goto out_filtered; |
799 | /* | ||
800 | * We have to do this here as we may have a dso with no symbol | ||
801 | * hit that has a name longer than the ones with symbols | ||
802 | * sampled. | ||
803 | */ | ||
804 | if (!sort_dso.elide && !al->map->dso->slen_calculated) | ||
805 | dso__calc_col_width(al->map->dso, &session->hists); | ||
806 | 780 | ||
807 | al->sym = map__find_symbol(al->map, al->addr, filter); | 781 | al->sym = map__find_symbol(al->map, al->addr, filter); |
808 | } else { | ||
809 | const unsigned int unresolved_col_width = BITS_PER_LONG / 4; | ||
810 | |||
811 | if (hists__col_len(&session->hists, HISTC_DSO) < unresolved_col_width && | ||
812 | !symbol_conf.col_width_list_str && !symbol_conf.field_sep && | ||
813 | !symbol_conf.dso_list) | ||
814 | hists__set_col_len(&session->hists, HISTC_DSO, | ||
815 | unresolved_col_width); | ||
816 | } | 782 | } |
817 | 783 | ||
818 | if (symbol_conf.sym_list && al->sym && | 784 | if (symbol_conf.sym_list && al->sym && |
@@ -825,128 +791,3 @@ out_filtered: | |||
825 | al->filtered = true; | 791 | al->filtered = true; |
826 | return 0; | 792 | return 0; |
827 | } | 793 | } |
828 | |||
829 | static int event__parse_id_sample(const event_t *event, | ||
830 | struct perf_session *session, | ||
831 | struct sample_data *sample) | ||
832 | { | ||
833 | const u64 *array; | ||
834 | u64 type; | ||
835 | |||
836 | sample->cpu = sample->pid = sample->tid = -1; | ||
837 | sample->stream_id = sample->id = sample->time = -1ULL; | ||
838 | |||
839 | if (!session->sample_id_all) | ||
840 | return 0; | ||
841 | |||
842 | array = event->sample.array; | ||
843 | array += ((event->header.size - | ||
844 | sizeof(event->header)) / sizeof(u64)) - 1; | ||
845 | type = session->sample_type; | ||
846 | |||
847 | if (type & PERF_SAMPLE_CPU) { | ||
848 | u32 *p = (u32 *)array; | ||
849 | sample->cpu = *p; | ||
850 | array--; | ||
851 | } | ||
852 | |||
853 | if (type & PERF_SAMPLE_STREAM_ID) { | ||
854 | sample->stream_id = *array; | ||
855 | array--; | ||
856 | } | ||
857 | |||
858 | if (type & PERF_SAMPLE_ID) { | ||
859 | sample->id = *array; | ||
860 | array--; | ||
861 | } | ||
862 | |||
863 | if (type & PERF_SAMPLE_TIME) { | ||
864 | sample->time = *array; | ||
865 | array--; | ||
866 | } | ||
867 | |||
868 | if (type & PERF_SAMPLE_TID) { | ||
869 | u32 *p = (u32 *)array; | ||
870 | sample->pid = p[0]; | ||
871 | sample->tid = p[1]; | ||
872 | } | ||
873 | |||
874 | return 0; | ||
875 | } | ||
876 | |||
877 | int event__parse_sample(const event_t *event, struct perf_session *session, | ||
878 | struct sample_data *data) | ||
879 | { | ||
880 | const u64 *array; | ||
881 | u64 type; | ||
882 | |||
883 | if (event->header.type != PERF_RECORD_SAMPLE) | ||
884 | return event__parse_id_sample(event, session, data); | ||
885 | |||
886 | array = event->sample.array; | ||
887 | type = session->sample_type; | ||
888 | |||
889 | if (type & PERF_SAMPLE_IP) { | ||
890 | data->ip = event->ip.ip; | ||
891 | array++; | ||
892 | } | ||
893 | |||
894 | if (type & PERF_SAMPLE_TID) { | ||
895 | u32 *p = (u32 *)array; | ||
896 | data->pid = p[0]; | ||
897 | data->tid = p[1]; | ||
898 | array++; | ||
899 | } | ||
900 | |||
901 | if (type & PERF_SAMPLE_TIME) { | ||
902 | data->time = *array; | ||
903 | array++; | ||
904 | } | ||
905 | |||
906 | if (type & PERF_SAMPLE_ADDR) { | ||
907 | data->addr = *array; | ||
908 | array++; | ||
909 | } | ||
910 | |||
911 | data->id = -1ULL; | ||
912 | if (type & PERF_SAMPLE_ID) { | ||
913 | data->id = *array; | ||
914 | array++; | ||
915 | } | ||
916 | |||
917 | if (type & PERF_SAMPLE_STREAM_ID) { | ||
918 | data->stream_id = *array; | ||
919 | array++; | ||
920 | } | ||
921 | |||
922 | if (type & PERF_SAMPLE_CPU) { | ||
923 | u32 *p = (u32 *)array; | ||
924 | data->cpu = *p; | ||
925 | array++; | ||
926 | } else | ||
927 | data->cpu = -1; | ||
928 | |||
929 | if (type & PERF_SAMPLE_PERIOD) { | ||
930 | data->period = *array; | ||
931 | array++; | ||
932 | } | ||
933 | |||
934 | if (type & PERF_SAMPLE_READ) { | ||
935 | pr_debug("PERF_SAMPLE_READ is unsuported for now\n"); | ||
936 | return -1; | ||
937 | } | ||
938 | |||
939 | if (type & PERF_SAMPLE_CALLCHAIN) { | ||
940 | data->callchain = (struct ip_callchain *)array; | ||
941 | array += 1 + data->callchain->nr; | ||
942 | } | ||
943 | |||
944 | if (type & PERF_SAMPLE_RAW) { | ||
945 | u32 *p = (u32 *)array; | ||
946 | data->raw_size = *p; | ||
947 | p++; | ||
948 | data->raw_data = p; | ||
949 | } | ||
950 | |||
951 | return 0; | ||
952 | } | ||