aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/event.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/event.c')
-rw-r--r--tools/perf/util/event.c87
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 @@
11static const char *perf_event__names[] = { 11static 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
540size_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
530int perf_event__process_mmap(struct perf_tool *tool __maybe_unused, 551int 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
559int 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
538size_t perf_event__fprintf_task(union perf_event *event, FILE *fp) 567size_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
661void thread__find_addr_location(struct thread *thread, struct machine *machine, 703void 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,
673int perf_event__preprocess_sample(const union perf_event *event, 715int 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 &&