diff options
Diffstat (limited to 'tools/perf/util/event.c')
-rw-r--r-- | tools/perf/util/event.c | 107 |
1 files changed, 74 insertions, 33 deletions
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 2fbf6a463c81..dab9e754a281 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c | |||
@@ -151,7 +151,6 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid, | |||
151 | continue; | 151 | continue; |
152 | pbf += n + 3; | 152 | pbf += n + 3; |
153 | if (*pbf == 'x') { /* vm_exec */ | 153 | if (*pbf == 'x') { /* vm_exec */ |
154 | u64 vm_pgoff; | ||
155 | char *execname = strchr(bf, '/'); | 154 | char *execname = strchr(bf, '/'); |
156 | 155 | ||
157 | /* Catch VDSO */ | 156 | /* Catch VDSO */ |
@@ -162,12 +161,7 @@ static int event__synthesize_mmap_events(pid_t pid, pid_t tgid, | |||
162 | continue; | 161 | continue; |
163 | 162 | ||
164 | pbf += 3; | 163 | pbf += 3; |
165 | n = hex2u64(pbf, &vm_pgoff); | 164 | n = hex2u64(pbf, &ev.mmap.pgoff); |
166 | /* pgoff is in bytes, not pages */ | ||
167 | if (n >= 0) | ||
168 | ev.mmap.pgoff = vm_pgoff << getpagesize(); | ||
169 | else | ||
170 | ev.mmap.pgoff = 0; | ||
171 | 165 | ||
172 | size = strlen(execname); | 166 | size = strlen(execname); |
173 | execname[size - 1] = '\0'; /* Remove \n */ | 167 | execname[size - 1] = '\0'; /* Remove \n */ |
@@ -340,30 +334,29 @@ int event__synthesize_kernel_mmap(event__handler_t process, | |||
340 | return process(&ev, session); | 334 | return process(&ev, session); |
341 | } | 335 | } |
342 | 336 | ||
343 | static void thread__comm_adjust(struct thread *self) | 337 | static void thread__comm_adjust(struct thread *self, struct hists *hists) |
344 | { | 338 | { |
345 | char *comm = self->comm; | 339 | char *comm = self->comm; |
346 | 340 | ||
347 | if (!symbol_conf.col_width_list_str && !symbol_conf.field_sep && | 341 | if (!symbol_conf.col_width_list_str && !symbol_conf.field_sep && |
348 | (!symbol_conf.comm_list || | 342 | (!symbol_conf.comm_list || |
349 | strlist__has_entry(symbol_conf.comm_list, comm))) { | 343 | strlist__has_entry(symbol_conf.comm_list, comm))) { |
350 | unsigned int slen = strlen(comm); | 344 | u16 slen = strlen(comm); |
351 | 345 | ||
352 | if (slen > comms__col_width) { | 346 | if (hists__new_col_len(hists, HISTC_COMM, slen)) |
353 | comms__col_width = slen; | 347 | hists__set_col_len(hists, HISTC_THREAD, slen + 6); |
354 | threads__col_width = slen + 6; | ||
355 | } | ||
356 | } | 348 | } |
357 | } | 349 | } |
358 | 350 | ||
359 | static int thread__set_comm_adjust(struct thread *self, const char *comm) | 351 | static int thread__set_comm_adjust(struct thread *self, const char *comm, |
352 | struct hists *hists) | ||
360 | { | 353 | { |
361 | int ret = thread__set_comm(self, comm); | 354 | int ret = thread__set_comm(self, comm); |
362 | 355 | ||
363 | if (ret) | 356 | if (ret) |
364 | return ret; | 357 | return ret; |
365 | 358 | ||
366 | thread__comm_adjust(self); | 359 | thread__comm_adjust(self, hists); |
367 | 360 | ||
368 | return 0; | 361 | return 0; |
369 | } | 362 | } |
@@ -374,7 +367,8 @@ int event__process_comm(event_t *self, struct perf_session *session) | |||
374 | 367 | ||
375 | dump_printf(": %s:%d\n", self->comm.comm, self->comm.tid); | 368 | dump_printf(": %s:%d\n", self->comm.comm, self->comm.tid); |
376 | 369 | ||
377 | if (thread == NULL || thread__set_comm_adjust(thread, self->comm.comm)) { | 370 | if (thread == NULL || thread__set_comm_adjust(thread, self->comm.comm, |
371 | &session->hists)) { | ||
378 | dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n"); | 372 | dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n"); |
379 | return -1; | 373 | return -1; |
380 | } | 374 | } |
@@ -456,6 +450,7 @@ static int event__process_kernel_mmap(event_t *self, | |||
456 | goto out_problem; | 450 | goto out_problem; |
457 | 451 | ||
458 | map->dso->short_name = name; | 452 | map->dso->short_name = name; |
453 | map->dso->sname_alloc = 1; | ||
459 | map->end = map->start + self->mmap.len; | 454 | map->end = map->start + self->mmap.len; |
460 | } else if (is_kernel_mmap) { | 455 | } else if (is_kernel_mmap) { |
461 | const char *symbol_name = (self->mmap.filename + | 456 | const char *symbol_name = (self->mmap.filename + |
@@ -514,12 +509,13 @@ int event__process_mmap(event_t *self, struct perf_session *session) | |||
514 | if (machine == NULL) | 509 | if (machine == NULL) |
515 | goto out_problem; | 510 | goto out_problem; |
516 | thread = perf_session__findnew(session, self->mmap.pid); | 511 | thread = perf_session__findnew(session, self->mmap.pid); |
512 | if (thread == NULL) | ||
513 | goto out_problem; | ||
517 | map = map__new(&machine->user_dsos, self->mmap.start, | 514 | map = map__new(&machine->user_dsos, self->mmap.start, |
518 | self->mmap.len, self->mmap.pgoff, | 515 | self->mmap.len, self->mmap.pgoff, |
519 | self->mmap.pid, self->mmap.filename, | 516 | self->mmap.pid, self->mmap.filename, |
520 | MAP__FUNCTION, session->cwd, session->cwdlen); | 517 | MAP__FUNCTION); |
521 | 518 | if (map == NULL) | |
522 | if (thread == NULL || map == NULL) | ||
523 | goto out_problem; | 519 | goto out_problem; |
524 | 520 | ||
525 | thread__insert_map(thread, map); | 521 | thread__insert_map(thread, map); |
@@ -552,6 +548,26 @@ int event__process_task(event_t *self, struct perf_session *session) | |||
552 | return 0; | 548 | return 0; |
553 | } | 549 | } |
554 | 550 | ||
551 | int event__process(event_t *event, struct perf_session *session) | ||
552 | { | ||
553 | switch (event->header.type) { | ||
554 | case PERF_RECORD_COMM: | ||
555 | event__process_comm(event, session); | ||
556 | break; | ||
557 | case PERF_RECORD_MMAP: | ||
558 | event__process_mmap(event, session); | ||
559 | break; | ||
560 | case PERF_RECORD_FORK: | ||
561 | case PERF_RECORD_EXIT: | ||
562 | event__process_task(event, session); | ||
563 | break; | ||
564 | default: | ||
565 | break; | ||
566 | } | ||
567 | |||
568 | return 0; | ||
569 | } | ||
570 | |||
555 | void thread__find_addr_map(struct thread *self, | 571 | void thread__find_addr_map(struct thread *self, |
556 | struct perf_session *session, u8 cpumode, | 572 | struct perf_session *session, u8 cpumode, |
557 | enum map_type type, pid_t pid, u64 addr, | 573 | enum map_type type, pid_t pid, u64 addr, |
@@ -641,27 +657,49 @@ void thread__find_addr_location(struct thread *self, | |||
641 | al->sym = NULL; | 657 | al->sym = NULL; |
642 | } | 658 | } |
643 | 659 | ||
644 | static void dso__calc_col_width(struct dso *self) | 660 | static void dso__calc_col_width(struct dso *self, struct hists *hists) |
645 | { | 661 | { |
646 | if (!symbol_conf.col_width_list_str && !symbol_conf.field_sep && | 662 | if (!symbol_conf.col_width_list_str && !symbol_conf.field_sep && |
647 | (!symbol_conf.dso_list || | 663 | (!symbol_conf.dso_list || |
648 | strlist__has_entry(symbol_conf.dso_list, self->name))) { | 664 | strlist__has_entry(symbol_conf.dso_list, self->name))) { |
649 | u16 slen = self->short_name_len; | 665 | u16 slen = dso__name_len(self); |
650 | if (verbose) | 666 | hists__new_col_len(hists, HISTC_DSO, slen); |
651 | slen = self->long_name_len; | ||
652 | if (dsos__col_width < slen) | ||
653 | dsos__col_width = slen; | ||
654 | } | 667 | } |
655 | 668 | ||
656 | self->slen_calculated = 1; | 669 | self->slen_calculated = 1; |
657 | } | 670 | } |
658 | 671 | ||
659 | int event__preprocess_sample(const event_t *self, struct perf_session *session, | 672 | int event__preprocess_sample(const event_t *self, struct perf_session *session, |
660 | struct addr_location *al, symbol_filter_t filter) | 673 | struct addr_location *al, struct sample_data *data, |
674 | symbol_filter_t filter) | ||
661 | { | 675 | { |
662 | u8 cpumode = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; | 676 | u8 cpumode = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; |
663 | struct thread *thread = perf_session__findnew(session, self->ip.pid); | 677 | struct thread *thread; |
664 | 678 | ||
679 | event__parse_sample(self, session->sample_type, data); | ||
680 | |||
681 | dump_printf("(IP, %d): %d/%d: %#Lx period: %Ld cpu:%d\n", | ||
682 | self->header.misc, data->pid, data->tid, data->ip, | ||
683 | data->period, data->cpu); | ||
684 | |||
685 | if (session->sample_type & PERF_SAMPLE_CALLCHAIN) { | ||
686 | unsigned int i; | ||
687 | |||
688 | dump_printf("... chain: nr:%Lu\n", data->callchain->nr); | ||
689 | |||
690 | if (!ip_callchain__valid(data->callchain, self)) { | ||
691 | pr_debug("call-chain problem with event, " | ||
692 | "skipping it.\n"); | ||
693 | goto out_filtered; | ||
694 | } | ||
695 | |||
696 | if (dump_trace) { | ||
697 | for (i = 0; i < data->callchain->nr; i++) | ||
698 | dump_printf("..... %2d: %016Lx\n", | ||
699 | i, data->callchain->ips[i]); | ||
700 | } | ||
701 | } | ||
702 | thread = perf_session__findnew(session, self->ip.pid); | ||
665 | if (thread == NULL) | 703 | if (thread == NULL) |
666 | return -1; | 704 | return -1; |
667 | 705 | ||
@@ -687,6 +725,7 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session, | |||
687 | al->map ? al->map->dso->long_name : | 725 | al->map ? al->map->dso->long_name : |
688 | al->level == 'H' ? "[hypervisor]" : "<not found>"); | 726 | al->level == 'H' ? "[hypervisor]" : "<not found>"); |
689 | al->sym = NULL; | 727 | al->sym = NULL; |
728 | al->cpu = data->cpu; | ||
690 | 729 | ||
691 | if (al->map) { | 730 | if (al->map) { |
692 | if (symbol_conf.dso_list && | 731 | if (symbol_conf.dso_list && |
@@ -703,16 +742,17 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session, | |||
703 | * sampled. | 742 | * sampled. |
704 | */ | 743 | */ |
705 | if (!sort_dso.elide && !al->map->dso->slen_calculated) | 744 | if (!sort_dso.elide && !al->map->dso->slen_calculated) |
706 | dso__calc_col_width(al->map->dso); | 745 | dso__calc_col_width(al->map->dso, &session->hists); |
707 | 746 | ||
708 | al->sym = map__find_symbol(al->map, al->addr, filter); | 747 | al->sym = map__find_symbol(al->map, al->addr, filter); |
709 | } else { | 748 | } else { |
710 | const unsigned int unresolved_col_width = BITS_PER_LONG / 4; | 749 | const unsigned int unresolved_col_width = BITS_PER_LONG / 4; |
711 | 750 | ||
712 | if (dsos__col_width < unresolved_col_width && | 751 | if (hists__col_len(&session->hists, HISTC_DSO) < unresolved_col_width && |
713 | !symbol_conf.col_width_list_str && !symbol_conf.field_sep && | 752 | !symbol_conf.col_width_list_str && !symbol_conf.field_sep && |
714 | !symbol_conf.dso_list) | 753 | !symbol_conf.dso_list) |
715 | dsos__col_width = unresolved_col_width; | 754 | hists__set_col_len(&session->hists, HISTC_DSO, |
755 | unresolved_col_width); | ||
716 | } | 756 | } |
717 | 757 | ||
718 | if (symbol_conf.sym_list && al->sym && | 758 | if (symbol_conf.sym_list && al->sym && |
@@ -726,9 +766,9 @@ out_filtered: | |||
726 | return 0; | 766 | return 0; |
727 | } | 767 | } |
728 | 768 | ||
729 | int event__parse_sample(event_t *event, u64 type, struct sample_data *data) | 769 | int event__parse_sample(const event_t *event, u64 type, struct sample_data *data) |
730 | { | 770 | { |
731 | u64 *array = event->sample.array; | 771 | const u64 *array = event->sample.array; |
732 | 772 | ||
733 | if (type & PERF_SAMPLE_IP) { | 773 | if (type & PERF_SAMPLE_IP) { |
734 | data->ip = event->ip.ip; | 774 | data->ip = event->ip.ip; |
@@ -767,7 +807,8 @@ int event__parse_sample(event_t *event, u64 type, struct sample_data *data) | |||
767 | u32 *p = (u32 *)array; | 807 | u32 *p = (u32 *)array; |
768 | data->cpu = *p; | 808 | data->cpu = *p; |
769 | array++; | 809 | array++; |
770 | } | 810 | } else |
811 | data->cpu = -1; | ||
771 | 812 | ||
772 | if (type & PERF_SAMPLE_PERIOD) { | 813 | if (type & PERF_SAMPLE_PERIOD) { |
773 | data->period = *array; | 814 | data->period = *array; |