diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2013-10-08 11:43:00 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2013-10-08 11:43:00 -0400 |
commit | e3c55d406bd8df1a878546002c93db90c42be10c (patch) | |
tree | efb0ba2707c95fd7166cf1b76887c43c977e37dd /tools/perf/util/event.c | |
parent | 4d6e482675f13e33599fc3d18fc723959be0a9b6 (diff) | |
parent | d0e639c9e06d44e713170031fe05fb60ebe680af (diff) |
Merge tag 'v3.12-rc4' into next
Merge with mainline to bring in changes to input subsystem that were
committed through other trees.
Diffstat (limited to 'tools/perf/util/event.c')
-rw-r--r-- | tools/perf/util/event.c | 87 |
1 files changed, 65 insertions, 22 deletions
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 5cd13d768cec..9b393e7dca6f 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c | |||
@@ -11,6 +11,7 @@ | |||
11 | static const char *perf_event__names[] = { | 11 | static const char *perf_event__names[] = { |
12 | [0] = "TOTAL", | 12 | [0] = "TOTAL", |
13 | [PERF_RECORD_MMAP] = "MMAP", | 13 | [PERF_RECORD_MMAP] = "MMAP", |
14 | [PERF_RECORD_MMAP2] = "MMAP2", | ||
14 | [PERF_RECORD_LOST] = "LOST", | 15 | [PERF_RECORD_LOST] = "LOST", |
15 | [PERF_RECORD_COMM] = "COMM", | 16 | [PERF_RECORD_COMM] = "COMM", |
16 | [PERF_RECORD_EXIT] = "EXIT", | 17 | [PERF_RECORD_EXIT] = "EXIT", |
@@ -186,7 +187,7 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool, | |||
186 | return -1; | 187 | return -1; |
187 | } | 188 | } |
188 | 189 | ||
189 | event->header.type = PERF_RECORD_MMAP; | 190 | event->header.type = PERF_RECORD_MMAP2; |
190 | /* | 191 | /* |
191 | * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c | 192 | * Just like the kernel, see __perf_event_mmap in kernel/perf_event.c |
192 | */ | 193 | */ |
@@ -197,7 +198,9 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool, | |||
197 | char prot[5]; | 198 | char prot[5]; |
198 | char execname[PATH_MAX]; | 199 | char execname[PATH_MAX]; |
199 | char anonstr[] = "//anon"; | 200 | char anonstr[] = "//anon"; |
201 | unsigned int ino; | ||
200 | size_t size; | 202 | size_t size; |
203 | ssize_t n; | ||
201 | 204 | ||
202 | if (fgets(bf, sizeof(bf), fp) == NULL) | 205 | if (fgets(bf, sizeof(bf), fp) == NULL) |
203 | break; | 206 | break; |
@@ -206,9 +209,16 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool, | |||
206 | strcpy(execname, ""); | 209 | strcpy(execname, ""); |
207 | 210 | ||
208 | /* 00400000-0040c000 r-xp 00000000 fd:01 41038 /bin/cat */ | 211 | /* 00400000-0040c000 r-xp 00000000 fd:01 41038 /bin/cat */ |
209 | sscanf(bf, "%"PRIx64"-%"PRIx64" %s %"PRIx64" %*x:%*x %*u %s\n", | 212 | n = sscanf(bf, "%"PRIx64"-%"PRIx64" %s %"PRIx64" %x:%x %u %s\n", |
210 | &event->mmap.start, &event->mmap.len, prot, | 213 | &event->mmap2.start, &event->mmap2.len, prot, |
211 | &event->mmap.pgoff, execname); | 214 | &event->mmap2.pgoff, &event->mmap2.maj, |
215 | &event->mmap2.min, | ||
216 | &ino, execname); | ||
217 | |||
218 | event->mmap2.ino = (u64)ino; | ||
219 | |||
220 | if (n != 8) | ||
221 | continue; | ||
212 | 222 | ||
213 | if (prot[2] != 'x') | 223 | if (prot[2] != 'x') |
214 | continue; | 224 | continue; |
@@ -217,15 +227,15 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool, | |||
217 | strcpy(execname, anonstr); | 227 | strcpy(execname, anonstr); |
218 | 228 | ||
219 | size = strlen(execname) + 1; | 229 | size = strlen(execname) + 1; |
220 | memcpy(event->mmap.filename, execname, size); | 230 | memcpy(event->mmap2.filename, execname, size); |
221 | size = PERF_ALIGN(size, sizeof(u64)); | 231 | size = PERF_ALIGN(size, sizeof(u64)); |
222 | event->mmap.len -= event->mmap.start; | 232 | event->mmap2.len -= event->mmap.start; |
223 | event->mmap.header.size = (sizeof(event->mmap) - | 233 | event->mmap2.header.size = (sizeof(event->mmap2) - |
224 | (sizeof(event->mmap.filename) - size)); | 234 | (sizeof(event->mmap2.filename) - size)); |
225 | memset(event->mmap.filename + size, 0, machine->id_hdr_size); | 235 | memset(event->mmap2.filename + size, 0, machine->id_hdr_size); |
226 | event->mmap.header.size += machine->id_hdr_size; | 236 | event->mmap2.header.size += machine->id_hdr_size; |
227 | event->mmap.pid = tgid; | 237 | event->mmap2.pid = tgid; |
228 | event->mmap.tid = pid; | 238 | event->mmap2.tid = pid; |
229 | 239 | ||
230 | if (process(tool, event, &synth_sample, machine) != 0) { | 240 | if (process(tool, event, &synth_sample, machine) != 0) { |
231 | rc = -1; | 241 | rc = -1; |
@@ -527,6 +537,17 @@ size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp) | |||
527 | event->mmap.len, event->mmap.pgoff, event->mmap.filename); | 537 | event->mmap.len, event->mmap.pgoff, event->mmap.filename); |
528 | } | 538 | } |
529 | 539 | ||
540 | size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp) | ||
541 | { | ||
542 | return fprintf(fp, " %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 | ||
543 | " %02x:%02x %"PRIu64" %"PRIu64"]: %s\n", | ||
544 | event->mmap2.pid, event->mmap2.tid, event->mmap2.start, | ||
545 | event->mmap2.len, event->mmap2.pgoff, event->mmap2.maj, | ||
546 | event->mmap2.min, event->mmap2.ino, | ||
547 | event->mmap2.ino_generation, | ||
548 | event->mmap2.filename); | ||
549 | } | ||
550 | |||
530 | int perf_event__process_mmap(struct perf_tool *tool __maybe_unused, | 551 | int perf_event__process_mmap(struct perf_tool *tool __maybe_unused, |
531 | union perf_event *event, | 552 | union perf_event *event, |
532 | struct perf_sample *sample __maybe_unused, | 553 | struct perf_sample *sample __maybe_unused, |
@@ -535,6 +556,14 @@ int perf_event__process_mmap(struct perf_tool *tool __maybe_unused, | |||
535 | return machine__process_mmap_event(machine, event); | 556 | return machine__process_mmap_event(machine, event); |
536 | } | 557 | } |
537 | 558 | ||
559 | int perf_event__process_mmap2(struct perf_tool *tool __maybe_unused, | ||
560 | union perf_event *event, | ||
561 | struct perf_sample *sample __maybe_unused, | ||
562 | struct machine *machine) | ||
563 | { | ||
564 | return machine__process_mmap2_event(machine, event); | ||
565 | } | ||
566 | |||
538 | size_t perf_event__fprintf_task(union perf_event *event, FILE *fp) | 567 | size_t perf_event__fprintf_task(union perf_event *event, FILE *fp) |
539 | { | 568 | { |
540 | return fprintf(fp, "(%d:%d):(%d:%d)\n", | 569 | return fprintf(fp, "(%d:%d):(%d:%d)\n", |
@@ -574,6 +603,9 @@ size_t perf_event__fprintf(union perf_event *event, FILE *fp) | |||
574 | case PERF_RECORD_MMAP: | 603 | case PERF_RECORD_MMAP: |
575 | ret += perf_event__fprintf_mmap(event, fp); | 604 | ret += perf_event__fprintf_mmap(event, fp); |
576 | break; | 605 | break; |
606 | case PERF_RECORD_MMAP2: | ||
607 | ret += perf_event__fprintf_mmap2(event, fp); | ||
608 | break; | ||
577 | default: | 609 | default: |
578 | ret += fprintf(fp, "\n"); | 610 | ret += fprintf(fp, "\n"); |
579 | } | 611 | } |
@@ -595,6 +627,7 @@ void thread__find_addr_map(struct thread *self, | |||
595 | struct addr_location *al) | 627 | struct addr_location *al) |
596 | { | 628 | { |
597 | struct map_groups *mg = &self->mg; | 629 | struct map_groups *mg = &self->mg; |
630 | bool load_map = false; | ||
598 | 631 | ||
599 | al->thread = self; | 632 | al->thread = self; |
600 | al->addr = addr; | 633 | al->addr = addr; |
@@ -609,11 +642,13 @@ void thread__find_addr_map(struct thread *self, | |||
609 | if (cpumode == PERF_RECORD_MISC_KERNEL && perf_host) { | 642 | if (cpumode == PERF_RECORD_MISC_KERNEL && perf_host) { |
610 | al->level = 'k'; | 643 | al->level = 'k'; |
611 | mg = &machine->kmaps; | 644 | mg = &machine->kmaps; |
645 | load_map = true; | ||
612 | } else if (cpumode == PERF_RECORD_MISC_USER && perf_host) { | 646 | } else if (cpumode == PERF_RECORD_MISC_USER && perf_host) { |
613 | al->level = '.'; | 647 | al->level = '.'; |
614 | } else if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) { | 648 | } else if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) { |
615 | al->level = 'g'; | 649 | al->level = 'g'; |
616 | mg = &machine->kmaps; | 650 | mg = &machine->kmaps; |
651 | load_map = true; | ||
617 | } else { | 652 | } else { |
618 | /* | 653 | /* |
619 | * 'u' means guest os user space. | 654 | * 'u' means guest os user space. |
@@ -654,18 +689,25 @@ try_again: | |||
654 | mg = &machine->kmaps; | 689 | mg = &machine->kmaps; |
655 | goto try_again; | 690 | goto try_again; |
656 | } | 691 | } |
657 | } else | 692 | } else { |
693 | /* | ||
694 | * Kernel maps might be changed when loading symbols so loading | ||
695 | * must be done prior to using kernel maps. | ||
696 | */ | ||
697 | if (load_map) | ||
698 | map__load(al->map, machine->symbol_filter); | ||
658 | al->addr = al->map->map_ip(al->map, al->addr); | 699 | al->addr = al->map->map_ip(al->map, al->addr); |
700 | } | ||
659 | } | 701 | } |
660 | 702 | ||
661 | void thread__find_addr_location(struct thread *thread, struct machine *machine, | 703 | void thread__find_addr_location(struct thread *thread, struct machine *machine, |
662 | u8 cpumode, enum map_type type, u64 addr, | 704 | u8 cpumode, enum map_type type, u64 addr, |
663 | struct addr_location *al, | 705 | struct addr_location *al) |
664 | symbol_filter_t filter) | ||
665 | { | 706 | { |
666 | thread__find_addr_map(thread, machine, cpumode, type, addr, al); | 707 | thread__find_addr_map(thread, machine, cpumode, type, addr, al); |
667 | if (al->map != NULL) | 708 | if (al->map != NULL) |
668 | al->sym = map__find_symbol(al->map, al->addr, filter); | 709 | al->sym = map__find_symbol(al->map, al->addr, |
710 | machine->symbol_filter); | ||
669 | else | 711 | else |
670 | al->sym = NULL; | 712 | al->sym = NULL; |
671 | } | 713 | } |
@@ -673,11 +715,11 @@ void thread__find_addr_location(struct thread *thread, struct machine *machine, | |||
673 | int perf_event__preprocess_sample(const union perf_event *event, | 715 | int perf_event__preprocess_sample(const union perf_event *event, |
674 | struct machine *machine, | 716 | struct machine *machine, |
675 | struct addr_location *al, | 717 | struct addr_location *al, |
676 | struct perf_sample *sample, | 718 | struct perf_sample *sample) |
677 | symbol_filter_t filter) | ||
678 | { | 719 | { |
679 | u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; | 720 | u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; |
680 | struct thread *thread = machine__findnew_thread(machine, event->ip.pid); | 721 | struct thread *thread = machine__findnew_thread(machine, sample->pid, |
722 | sample->pid); | ||
681 | 723 | ||
682 | if (thread == NULL) | 724 | if (thread == NULL) |
683 | return -1; | 725 | return -1; |
@@ -686,7 +728,7 @@ int perf_event__preprocess_sample(const union perf_event *event, | |||
686 | !strlist__has_entry(symbol_conf.comm_list, thread->comm)) | 728 | !strlist__has_entry(symbol_conf.comm_list, thread->comm)) |
687 | goto out_filtered; | 729 | goto out_filtered; |
688 | 730 | ||
689 | dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); | 731 | dump_printf(" ... thread: %s:%d\n", thread->comm, thread->tid); |
690 | /* | 732 | /* |
691 | * Have we already created the kernel maps for this machine? | 733 | * Have we already created the kernel maps for this machine? |
692 | * | 734 | * |
@@ -699,7 +741,7 @@ int perf_event__preprocess_sample(const union perf_event *event, | |||
699 | machine__create_kernel_maps(machine); | 741 | machine__create_kernel_maps(machine); |
700 | 742 | ||
701 | thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION, | 743 | thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION, |
702 | event->ip.ip, al); | 744 | sample->ip, al); |
703 | dump_printf(" ...... dso: %s\n", | 745 | dump_printf(" ...... dso: %s\n", |
704 | al->map ? al->map->dso->long_name : | 746 | al->map ? al->map->dso->long_name : |
705 | al->level == 'H' ? "[hypervisor]" : "<not found>"); | 747 | al->level == 'H' ? "[hypervisor]" : "<not found>"); |
@@ -717,7 +759,8 @@ int perf_event__preprocess_sample(const union perf_event *event, | |||
717 | dso->long_name))))) | 759 | dso->long_name))))) |
718 | goto out_filtered; | 760 | goto out_filtered; |
719 | 761 | ||
720 | al->sym = map__find_symbol(al->map, al->addr, filter); | 762 | al->sym = map__find_symbol(al->map, al->addr, |
763 | machine->symbol_filter); | ||
721 | } | 764 | } |
722 | 765 | ||
723 | if (symbol_conf.sym_list && | 766 | if (symbol_conf.sym_list && |