aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-report.c
diff options
context:
space:
mode:
authorOGAWA Hirofumi <hirofumi@mail.parknet.co.jp>2009-12-06 06:08:24 -0500
committerIngo Molnar <mingo@elte.hu>2009-12-06 12:15:01 -0500
commit180f95e29aa8782c019caa64ede2a28d8ab62564 (patch)
treeeefd1631820b00992f4495cc8cdba66a9155ee6c /tools/perf/builtin-report.c
parent028c515253761084c6594bf9ac9b194b51d87065 (diff)
perf: Make common SAMPLE_EVENT parser
Currently, sample event data is parsed for each commands, and it is assuming that the data is not including other data. (E.g. timechart, trace, etc. can't parse the event if it has PERF_SAMPLE_CALLCHAIN) So, even if we record the superset data for multiple commands at a time, commands can't parse. etc. To fix it, this makes common sample event parser, and use it to parse sample event correctly. (PERF_SAMPLE_READ is unsupported for now though, it seems to be not using.) Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Paul Mackerras <paulus@samba.org> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> LKML-Reference: <87hbs48imv.fsf@devron.myhome.or.jp> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/builtin-report.c')
-rw-r--r--tools/perf/builtin-report.c39
1 files changed, 18 insertions, 21 deletions
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 383c4ab4f9af..2b9eb3a553ed 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -605,44 +605,41 @@ static int validate_chain(struct ip_callchain *chain, event_t *event)
605 605
606static int process_sample_event(event_t *event) 606static int process_sample_event(event_t *event)
607{ 607{
608 u64 ip = event->ip.ip; 608 struct sample_data data;
609 u64 period = 1;
610 void *more_data = event->ip.__more_data;
611 struct ip_callchain *chain = NULL;
612 int cpumode; 609 int cpumode;
613 struct addr_location al; 610 struct addr_location al;
614 struct thread *thread = threads__findnew(event->ip.pid); 611 struct thread *thread;
615 612
616 if (sample_type & PERF_SAMPLE_PERIOD) { 613 memset(&data, 0, sizeof(data));
617 period = *(u64 *)more_data; 614 data.period = 1;
618 more_data += sizeof(u64); 615
619 } 616 event__parse_sample(event, sample_type, &data);
620 617
621 dump_printf("(IP, %d): %d/%d: %p period: %Ld\n", 618 dump_printf("(IP, %d): %d/%d: %p period: %Ld\n",
622 event->header.misc, 619 event->header.misc,
623 event->ip.pid, event->ip.tid, 620 data.pid, data.tid,
624 (void *)(long)ip, 621 (void *)(long)data.ip,
625 (long long)period); 622 (long long)data.period);
626 623
627 if (sample_type & PERF_SAMPLE_CALLCHAIN) { 624 if (sample_type & PERF_SAMPLE_CALLCHAIN) {
628 unsigned int i; 625 unsigned int i;
629 626
630 chain = (void *)more_data; 627 dump_printf("... chain: nr:%Lu\n", data.callchain->nr);
631
632 dump_printf("... chain: nr:%Lu\n", chain->nr);
633 628
634 if (validate_chain(chain, event) < 0) { 629 if (validate_chain(data.callchain, event) < 0) {
635 pr_debug("call-chain problem with event, " 630 pr_debug("call-chain problem with event, "
636 "skipping it.\n"); 631 "skipping it.\n");
637 return 0; 632 return 0;
638 } 633 }
639 634
640 if (dump_trace) { 635 if (dump_trace) {
641 for (i = 0; i < chain->nr; i++) 636 for (i = 0; i < data.callchain->nr; i++)
642 dump_printf("..... %2d: %016Lx\n", i, chain->ips[i]); 637 dump_printf("..... %2d: %016Lx\n",
638 i, data.callchain->ips[i]);
643 } 639 }
644 } 640 }
645 641
642 thread = threads__findnew(data.pid);
646 if (thread == NULL) { 643 if (thread == NULL) {
647 pr_debug("problem processing %d event, skipping it.\n", 644 pr_debug("problem processing %d event, skipping it.\n",
648 event->header.type); 645 event->header.type);
@@ -657,7 +654,7 @@ static int process_sample_event(event_t *event)
657 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 654 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
658 655
659 thread__find_addr_location(thread, cpumode, 656 thread__find_addr_location(thread, cpumode,
660 MAP__FUNCTION, ip, &al, NULL); 657 MAP__FUNCTION, data.ip, &al, NULL);
661 /* 658 /*
662 * We have to do this here as we may have a dso with no symbol hit that 659 * We have to do this here as we may have a dso with no symbol hit that
663 * has a name longer than the ones with symbols sampled. 660 * has a name longer than the ones with symbols sampled.
@@ -675,12 +672,12 @@ static int process_sample_event(event_t *event)
675 if (sym_list && al.sym && !strlist__has_entry(sym_list, al.sym->name)) 672 if (sym_list && al.sym && !strlist__has_entry(sym_list, al.sym->name))
676 return 0; 673 return 0;
677 674
678 if (hist_entry__add(&al, chain, period)) { 675 if (hist_entry__add(&al, data.callchain, data.period)) {
679 pr_debug("problem incrementing symbol count, skipping event\n"); 676 pr_debug("problem incrementing symbol count, skipping event\n");
680 return -1; 677 return -1;
681 } 678 }
682 679
683 event__stats.total += period; 680 event__stats.total += data.period;
684 681
685 return 0; 682 return 0;
686} 683}