aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/event.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2012-10-06 15:26:02 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2012-10-06 15:34:13 -0400
commitb0a7d1a0cd2e228dc06d099db2e1bb02f1b7d591 (patch)
treee943d42d36229261829b7c51978ecd1ee649a59a /tools/perf/util/event.c
parent0439539f72ea222fbfe511b47318b9c1815a7108 (diff)
perf machine: Carve up event processing specific from perf_tool
The perf_tool vtable expects methods that receive perf_tool and perf_sample entries, but for tools not interested in doing any special processing on non PERF_RECORD_SAMPLE events, like 'perf top', and for those not using perf_session, like 'perf trace', they were using perf_event__process passing tool and sample paramenters that were just not used. Provide 'machine' methods for this purpose and make the perf_event ones use them. Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-ot9cc6mt025o8kbngzckcrx9@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/event.c')
-rw-r--r--tools/perf/util/event.c211
1 files changed, 12 insertions, 199 deletions
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index eaaee22628ea..0ae444ef1429 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -520,134 +520,15 @@ int perf_event__process_comm(struct perf_tool *tool __maybe_unused,
520 struct perf_sample *sample __maybe_unused, 520 struct perf_sample *sample __maybe_unused,
521 struct machine *machine) 521 struct machine *machine)
522{ 522{
523 struct thread *thread = machine__findnew_thread(machine, event->comm.tid); 523 return machine__process_comm_event(machine, event);
524
525 if (dump_trace)
526 perf_event__fprintf_comm(event, stdout);
527
528 if (thread == NULL || thread__set_comm(thread, event->comm.comm)) {
529 dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
530 return -1;
531 }
532
533 return 0;
534} 524}
535 525
536int perf_event__process_lost(struct perf_tool *tool __maybe_unused, 526int perf_event__process_lost(struct perf_tool *tool __maybe_unused,
537 union perf_event *event, 527 union perf_event *event,
538 struct perf_sample *sample __maybe_unused, 528 struct perf_sample *sample __maybe_unused,
539 struct machine *machine __maybe_unused) 529 struct machine *machine)
540{
541 dump_printf(": id:%" PRIu64 ": lost:%" PRIu64 "\n",
542 event->lost.id, event->lost.lost);
543 return 0;
544}
545
546static void perf_event__set_kernel_mmap_len(union perf_event *event,
547 struct map **maps)
548{
549 maps[MAP__FUNCTION]->start = event->mmap.start;
550 maps[MAP__FUNCTION]->end = event->mmap.start + event->mmap.len;
551 /*
552 * Be a bit paranoid here, some perf.data file came with
553 * a zero sized synthesized MMAP event for the kernel.
554 */
555 if (maps[MAP__FUNCTION]->end == 0)
556 maps[MAP__FUNCTION]->end = ~0ULL;
557}
558
559static int perf_event__process_kernel_mmap(struct perf_tool *tool
560 __maybe_unused,
561 union perf_event *event,
562 struct machine *machine)
563{ 530{
564 struct map *map; 531 return machine__process_lost_event(machine, event);
565 char kmmap_prefix[PATH_MAX];
566 enum dso_kernel_type kernel_type;
567 bool is_kernel_mmap;
568
569 machine__mmap_name(machine, kmmap_prefix, sizeof(kmmap_prefix));
570 if (machine__is_host(machine))
571 kernel_type = DSO_TYPE_KERNEL;
572 else
573 kernel_type = DSO_TYPE_GUEST_KERNEL;
574
575 is_kernel_mmap = memcmp(event->mmap.filename,
576 kmmap_prefix,
577 strlen(kmmap_prefix) - 1) == 0;
578 if (event->mmap.filename[0] == '/' ||
579 (!is_kernel_mmap && event->mmap.filename[0] == '[')) {
580
581 char short_module_name[1024];
582 char *name, *dot;
583
584 if (event->mmap.filename[0] == '/') {
585 name = strrchr(event->mmap.filename, '/');
586 if (name == NULL)
587 goto out_problem;
588
589 ++name; /* skip / */
590 dot = strrchr(name, '.');
591 if (dot == NULL)
592 goto out_problem;
593 snprintf(short_module_name, sizeof(short_module_name),
594 "[%.*s]", (int)(dot - name), name);
595 strxfrchar(short_module_name, '-', '_');
596 } else
597 strcpy(short_module_name, event->mmap.filename);
598
599 map = machine__new_module(machine, event->mmap.start,
600 event->mmap.filename);
601 if (map == NULL)
602 goto out_problem;
603
604 name = strdup(short_module_name);
605 if (name == NULL)
606 goto out_problem;
607
608 map->dso->short_name = name;
609 map->dso->sname_alloc = 1;
610 map->end = map->start + event->mmap.len;
611 } else if (is_kernel_mmap) {
612 const char *symbol_name = (event->mmap.filename +
613 strlen(kmmap_prefix));
614 /*
615 * Should be there already, from the build-id table in
616 * the header.
617 */
618 struct dso *kernel = __dsos__findnew(&machine->kernel_dsos,
619 kmmap_prefix);
620 if (kernel == NULL)
621 goto out_problem;
622
623 kernel->kernel = kernel_type;
624 if (__machine__create_kernel_maps(machine, kernel) < 0)
625 goto out_problem;
626
627 perf_event__set_kernel_mmap_len(event, machine->vmlinux_maps);
628
629 /*
630 * Avoid using a zero address (kptr_restrict) for the ref reloc
631 * symbol. Effectively having zero here means that at record
632 * time /proc/sys/kernel/kptr_restrict was non zero.
633 */
634 if (event->mmap.pgoff != 0) {
635 maps__set_kallsyms_ref_reloc_sym(machine->vmlinux_maps,
636 symbol_name,
637 event->mmap.pgoff);
638 }
639
640 if (machine__is_default_guest(machine)) {
641 /*
642 * preload dso of guest kernel and modules
643 */
644 dso__load(kernel, machine->vmlinux_maps[MAP__FUNCTION],
645 NULL);
646 }
647 }
648 return 0;
649out_problem:
650 return -1;
651} 532}
652 533
653size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp) 534size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp)
@@ -657,43 +538,12 @@ size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp)
657 event->mmap.len, event->mmap.pgoff, event->mmap.filename); 538 event->mmap.len, event->mmap.pgoff, event->mmap.filename);
658} 539}
659 540
660int perf_event__process_mmap(struct perf_tool *tool, 541int perf_event__process_mmap(struct perf_tool *tool __maybe_unused,
661 union perf_event *event, 542 union perf_event *event,
662 struct perf_sample *sample __maybe_unused, 543 struct perf_sample *sample __maybe_unused,
663 struct machine *machine) 544 struct machine *machine)
664{ 545{
665 struct thread *thread; 546 return machine__process_mmap_event(machine, event);
666 struct map *map;
667 u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
668 int ret = 0;
669
670 if (dump_trace)
671 perf_event__fprintf_mmap(event, stdout);
672
673 if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL ||
674 cpumode == PERF_RECORD_MISC_KERNEL) {
675 ret = perf_event__process_kernel_mmap(tool, event, machine);
676 if (ret < 0)
677 goto out_problem;
678 return 0;
679 }
680
681 thread = machine__findnew_thread(machine, event->mmap.pid);
682 if (thread == NULL)
683 goto out_problem;
684 map = map__new(&machine->user_dsos, event->mmap.start,
685 event->mmap.len, event->mmap.pgoff,
686 event->mmap.pid, event->mmap.filename,
687 MAP__FUNCTION);
688 if (map == NULL)
689 goto out_problem;
690
691 thread__insert_map(thread, map);
692 return 0;
693
694out_problem:
695 dump_printf("problem processing PERF_RECORD_MMAP, skipping event.\n");
696 return 0;
697} 547}
698 548
699size_t perf_event__fprintf_task(union perf_event *event, FILE *fp) 549size_t perf_event__fprintf_task(union perf_event *event, FILE *fp)
@@ -708,19 +558,7 @@ int perf_event__process_fork(struct perf_tool *tool __maybe_unused,
708 struct perf_sample *sample __maybe_unused, 558 struct perf_sample *sample __maybe_unused,
709 struct machine *machine) 559 struct machine *machine)
710{ 560{
711 struct thread *thread = machine__findnew_thread(machine, event->fork.tid); 561 return machine__process_fork_event(machine, event);
712 struct thread *parent = machine__findnew_thread(machine, event->fork.ptid);
713
714 if (dump_trace)
715 perf_event__fprintf_task(event, stdout);
716
717 if (thread == NULL || parent == NULL ||
718 thread__fork(thread, parent) < 0) {
719 dump_printf("problem processing PERF_RECORD_FORK, skipping event.\n");
720 return -1;
721 }
722
723 return 0;
724} 562}
725 563
726int perf_event__process_exit(struct perf_tool *tool __maybe_unused, 564int perf_event__process_exit(struct perf_tool *tool __maybe_unused,
@@ -728,15 +566,7 @@ int perf_event__process_exit(struct perf_tool *tool __maybe_unused,
728 struct perf_sample *sample __maybe_unused, 566 struct perf_sample *sample __maybe_unused,
729 struct machine *machine) 567 struct machine *machine)
730{ 568{
731 struct thread *thread = machine__find_thread(machine, event->fork.tid); 569 return machine__process_exit_event(machine, event);
732
733 if (dump_trace)
734 perf_event__fprintf_task(event, stdout);
735
736 if (thread != NULL)
737 machine__remove_thread(machine, thread);
738
739 return 0;
740} 570}
741 571
742size_t perf_event__fprintf(union perf_event *event, FILE *fp) 572size_t perf_event__fprintf(union perf_event *event, FILE *fp)
@@ -762,29 +592,12 @@ size_t perf_event__fprintf(union perf_event *event, FILE *fp)
762 return ret; 592 return ret;
763} 593}
764 594
765int perf_event__process(struct perf_tool *tool, union perf_event *event, 595int perf_event__process(struct perf_tool *tool __maybe_unused,
766 struct perf_sample *sample, struct machine *machine) 596 union perf_event *event,
597 struct perf_sample *sample __maybe_unused,
598 struct machine *machine)
767{ 599{
768 switch (event->header.type) { 600 return machine__process_event(machine, event);
769 case PERF_RECORD_COMM:
770 perf_event__process_comm(tool, event, sample, machine);
771 break;
772 case PERF_RECORD_MMAP:
773 perf_event__process_mmap(tool, event, sample, machine);
774 break;
775 case PERF_RECORD_FORK:
776 perf_event__process_fork(tool, event, sample, machine);
777 break;
778 case PERF_RECORD_EXIT:
779 perf_event__process_exit(tool, event, sample, machine);
780 break;
781 case PERF_RECORD_LOST:
782 perf_event__process_lost(tool, event, sample, machine);
783 default:
784 break;
785 }
786
787 return 0;
788} 601}
789 602
790void thread__find_addr_map(struct thread *self, 603void thread__find_addr_map(struct thread *self,