diff options
| author | Li Zefan <lizf@cn.fujitsu.com> | 2009-12-01 01:04:49 -0500 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-12-01 02:14:08 -0500 |
| commit | bab81b624e970f1138535a465ad2b26b6bb0dd6c (patch) | |
| tree | 4e62c0dd293b18c7bc1593437e2a6fd18e811b5b /tools/perf/builtin-annotate.c | |
| parent | 1ed091c45ae33b2179d387573c3fe3f3b4adf60a (diff) | |
perf annotate: Fix perf data parsing
perf-annotate doesn't parse perf.data correctly in that it
doesn't read perf header. Fix this by using
mmap_dispatch_perf_file().
Before:
TOTAL events: 17565
MMAP events: 3221
LOST events: 10
COMM events: 235
EXIT events: 2
THROTTLE events: 1
UNTHROTTLE events: 2
FORK events: 10
READ events: 1
SAMPLE events: 14083
After:
TOTAL events: 17290
MMAP events: 3203
LOST events: 0
COMM events: 234
EXIT events: 1
THROTTLE events: 0
UNTHROTTLE events: 0
FORK events: 0
READ events: 0
SAMPLE events: 13852
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Arjan van de Ven <arjan@infradead.org>
LKML-Reference: <4B14B201.9030708@cn.fujitsu.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/builtin-annotate.c')
| -rw-r--r-- | tools/perf/builtin-annotate.c | 143 |
1 files changed, 18 insertions, 125 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 7f85c6e159a4..0bf2e8f9af57 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
| @@ -25,19 +25,16 @@ | |||
| 25 | #include "util/thread.h" | 25 | #include "util/thread.h" |
| 26 | #include "util/sort.h" | 26 | #include "util/sort.h" |
| 27 | #include "util/hist.h" | 27 | #include "util/hist.h" |
| 28 | #include "util/data_map.h" | ||
| 28 | 29 | ||
| 29 | static char const *input_name = "perf.data"; | 30 | static char const *input_name = "perf.data"; |
| 30 | 31 | ||
| 31 | static int force; | 32 | static int force; |
| 32 | static int input; | ||
| 33 | 33 | ||
| 34 | static int full_paths; | 34 | static int full_paths; |
| 35 | 35 | ||
| 36 | static int print_line; | 36 | static int print_line; |
| 37 | 37 | ||
| 38 | static unsigned long page_size; | ||
| 39 | static unsigned long mmap_window = 32; | ||
| 40 | |||
| 41 | struct sym_hist { | 38 | struct sym_hist { |
| 42 | u64 sum; | 39 | u64 sum; |
| 43 | u64 ip[0]; | 40 | u64 ip[0]; |
| @@ -156,35 +153,6 @@ static int process_sample_event(event_t *event) | |||
| 156 | return 0; | 153 | return 0; |
| 157 | } | 154 | } |
| 158 | 155 | ||
| 159 | static int event__process(event_t *self) | ||
| 160 | { | ||
| 161 | switch (self->header.type) { | ||
| 162 | case PERF_RECORD_SAMPLE: | ||
| 163 | return process_sample_event(self); | ||
| 164 | |||
| 165 | case PERF_RECORD_MMAP: | ||
| 166 | return event__process_mmap(self); | ||
| 167 | |||
| 168 | case PERF_RECORD_COMM: | ||
| 169 | return event__process_comm(self); | ||
| 170 | |||
| 171 | case PERF_RECORD_FORK: | ||
| 172 | return event__process_task(self); | ||
| 173 | /* | ||
| 174 | * We dont process them right now but they are fine: | ||
| 175 | */ | ||
| 176 | |||
| 177 | case PERF_RECORD_THROTTLE: | ||
| 178 | case PERF_RECORD_UNTHROTTLE: | ||
| 179 | return 0; | ||
| 180 | |||
| 181 | default: | ||
| 182 | return -1; | ||
| 183 | } | ||
| 184 | |||
| 185 | return 0; | ||
| 186 | } | ||
| 187 | |||
| 188 | static int parse_line(FILE *file, struct hist_entry *he, u64 len) | 156 | static int parse_line(FILE *file, struct hist_entry *he, u64 len) |
| 189 | { | 157 | { |
| 190 | struct symbol *sym = he->sym; | 158 | struct symbol *sym = he->sym; |
| @@ -485,99 +453,26 @@ static void find_annotations(void) | |||
| 485 | } | 453 | } |
| 486 | } | 454 | } |
| 487 | 455 | ||
| 456 | static struct perf_file_handler file_handler = { | ||
| 457 | .process_sample_event = process_sample_event, | ||
| 458 | .process_mmap_event = event__process_mmap, | ||
| 459 | .process_comm_event = event__process_comm, | ||
| 460 | .process_fork_event = event__process_task, | ||
| 461 | }; | ||
| 462 | |||
| 488 | static int __cmd_annotate(void) | 463 | static int __cmd_annotate(void) |
| 489 | { | 464 | { |
| 490 | int ret, rc = EXIT_FAILURE; | 465 | struct perf_header *header; |
| 491 | unsigned long offset = 0; | 466 | struct thread *idle; |
| 492 | unsigned long head = 0; | 467 | int ret; |
| 493 | struct stat input_stat; | ||
| 494 | event_t *event; | ||
| 495 | uint32_t size; | ||
| 496 | char *buf; | ||
| 497 | |||
| 498 | register_idle_thread(); | ||
| 499 | |||
| 500 | input = open(input_name, O_RDONLY); | ||
| 501 | if (input < 0) { | ||
| 502 | perror("failed to open file"); | ||
| 503 | exit(-1); | ||
| 504 | } | ||
| 505 | |||
| 506 | ret = fstat(input, &input_stat); | ||
| 507 | if (ret < 0) { | ||
| 508 | perror("failed to stat file"); | ||
| 509 | exit(-1); | ||
| 510 | } | ||
| 511 | |||
| 512 | if (!force && input_stat.st_uid && (input_stat.st_uid != geteuid())) { | ||
| 513 | fprintf(stderr, "file: %s not owned by current user or root\n", input_name); | ||
| 514 | exit(-1); | ||
| 515 | } | ||
| 516 | |||
| 517 | if (!input_stat.st_size) { | ||
| 518 | fprintf(stderr, "zero-sized file, nothing to do!\n"); | ||
| 519 | exit(0); | ||
| 520 | } | ||
| 521 | |||
| 522 | remap: | ||
| 523 | buf = (char *)mmap(NULL, page_size * mmap_window, PROT_READ, | ||
| 524 | MAP_SHARED, input, offset); | ||
| 525 | if (buf == MAP_FAILED) { | ||
| 526 | perror("failed to mmap file"); | ||
| 527 | exit(-1); | ||
| 528 | } | ||
| 529 | |||
| 530 | more: | ||
| 531 | event = (event_t *)(buf + head); | ||
| 532 | |||
| 533 | size = event->header.size; | ||
| 534 | if (!size) | ||
| 535 | size = 8; | ||
| 536 | |||
| 537 | if (head + event->header.size >= page_size * mmap_window) { | ||
| 538 | unsigned long shift = page_size * (head / page_size); | ||
| 539 | int munmap_ret; | ||
| 540 | |||
| 541 | munmap_ret = munmap(buf, page_size * mmap_window); | ||
| 542 | assert(munmap_ret == 0); | ||
| 543 | |||
| 544 | offset += shift; | ||
| 545 | head -= shift; | ||
| 546 | goto remap; | ||
| 547 | } | ||
| 548 | |||
| 549 | size = event->header.size; | ||
| 550 | |||
| 551 | dump_printf("%p [%p]: event: %d\n", | ||
| 552 | (void *)(offset + head), | ||
| 553 | (void *)(long)event->header.size, | ||
| 554 | event->header.type); | ||
| 555 | |||
| 556 | if (!size || event__process(event) < 0) { | ||
| 557 | |||
| 558 | dump_printf("%p [%p]: skipping unknown header type: %d\n", | ||
| 559 | (void *)(offset + head), | ||
| 560 | (void *)(long)(event->header.size), | ||
| 561 | event->header.type); | ||
| 562 | /* | ||
| 563 | * assume we lost track of the stream, check alignment, and | ||
| 564 | * increment a single u64 in the hope to catch on again 'soon'. | ||
| 565 | */ | ||
| 566 | |||
| 567 | if (unlikely(head & 7)) | ||
| 568 | head &= ~7ULL; | ||
| 569 | |||
| 570 | size = 8; | ||
| 571 | } | ||
| 572 | |||
| 573 | head += size; | ||
| 574 | |||
| 575 | if (offset + head < (unsigned long)input_stat.st_size) | ||
| 576 | goto more; | ||
| 577 | 468 | ||
| 578 | rc = EXIT_SUCCESS; | 469 | idle = register_idle_thread(); |
| 579 | close(input); | 470 | register_perf_file_handler(&file_handler); |
| 580 | 471 | ||
| 472 | ret = mmap_dispatch_perf_file(&header, input_name, 0, 0, | ||
| 473 | &event__cwdlen, &event__cwd); | ||
| 474 | if (ret) | ||
| 475 | return ret; | ||
| 581 | 476 | ||
| 582 | if (dump_trace) { | 477 | if (dump_trace) { |
| 583 | event__print_totals(); | 478 | event__print_totals(); |
| @@ -595,7 +490,7 @@ more: | |||
| 595 | 490 | ||
| 596 | find_annotations(); | 491 | find_annotations(); |
| 597 | 492 | ||
| 598 | return rc; | 493 | return ret; |
| 599 | } | 494 | } |
| 600 | 495 | ||
| 601 | static const char * const annotate_usage[] = { | 496 | static const char * const annotate_usage[] = { |
| @@ -644,8 +539,6 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __used) | |||
| 644 | if (symbol__init(&symbol_conf) < 0) | 539 | if (symbol__init(&symbol_conf) < 0) |
| 645 | return -1; | 540 | return -1; |
| 646 | 541 | ||
| 647 | page_size = getpagesize(); | ||
| 648 | |||
| 649 | argc = parse_options(argc, argv, options, annotate_usage, 0); | 542 | argc = parse_options(argc, argv, options, annotate_usage, 0); |
| 650 | 543 | ||
| 651 | setup_sorting(); | 544 | setup_sorting(); |
