aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@redhat.com>2012-05-30 08:23:44 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2012-05-31 10:59:01 -0400
commit37073f9e449bc430e6c40b9cffc2558002a0256a (patch)
treedb83bb7761ff456da7eda2bb1aa44388d1b1d588 /tools/perf/util
parent268fb20f832e1eb4afd5113ee31fef9332986b13 (diff)
perf evsel: Fix 32 bit values endianity swap for sample_id_all header
We swap the sample_id_all header by u64 pointers. Some members of the header happen to be 32 bit values. We need to handle them separatelly. Together with other endianity patches, this change fixies perf report discrepancies on origin and target systems as described in test 1 below, e.g. following perf report diff: ... 0.12% ps [kernel.kallsyms] [k] clear_page - 0.12% awk bash [.] alloc_word_desc + 0.12% awk bash [.] yyparse 0.11% beah-rhts-task libpython2.6.so.1.0 [.] 0x5560e 0.10% perf libc-2.12.so [.] __ctype_toupper_loc - 0.09% rhts-test-runne bash [.] maybe_make_export_env + 0.09% rhts-test-runne bash [.] 0x385a0 0.09% ps [kernel.kallsyms] [k] page_fault ... Note, running following to test perf endianity handling: test 1) - origin system: # perf record -a -- sleep 10 (any perf record will do) # perf report > report.origin # perf archive perf.data - copy the perf.data, report.origin and perf.data.tar.bz2 to a target system and run: # tar xjvf perf.data.tar.bz2 -C ~/.debug # perf report > report.target # diff -u report.origin report.target - the diff should produce no output (besides some white space stuff and possibly different date/TZ output) test 2) - origin system: # perf record -ag -fo /tmp/perf.data -- sleep 1 - mount origin system root to the target system on /mnt/origin - target system: # perf script --symfs /mnt/origin -I -i /mnt/origin/tmp/perf.data \ --kallsyms /mnt/origin/proc/kallsyms - complete perf.data header is displayed Signed-off-by: Jiri Olsa <jolsa@redhat.com> Reviewed-by: David Ahern <dsahern@gmail.com> Tested-by: David Ahern <dsahern@gmail.com> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1338380624-7443-4-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util')
-rw-r--r--tools/perf/util/evsel.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 91d19138f3ec..9f6cebd798ee 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -494,16 +494,24 @@ int perf_evsel__open_per_thread(struct perf_evsel *evsel,
494} 494}
495 495
496static int perf_event__parse_id_sample(const union perf_event *event, u64 type, 496static int perf_event__parse_id_sample(const union perf_event *event, u64 type,
497 struct perf_sample *sample) 497 struct perf_sample *sample,
498 bool swapped)
498{ 499{
499 const u64 *array = event->sample.array; 500 const u64 *array = event->sample.array;
501 union u64_swap u;
500 502
501 array += ((event->header.size - 503 array += ((event->header.size -
502 sizeof(event->header)) / sizeof(u64)) - 1; 504 sizeof(event->header)) / sizeof(u64)) - 1;
503 505
504 if (type & PERF_SAMPLE_CPU) { 506 if (type & PERF_SAMPLE_CPU) {
505 u32 *p = (u32 *)array; 507 u.val64 = *array;
506 sample->cpu = *p; 508 if (swapped) {
509 /* undo swap of u64, then swap on individual u32s */
510 u.val64 = bswap_64(u.val64);
511 u.val32[0] = bswap_32(u.val32[0]);
512 }
513
514 sample->cpu = u.val32[0];
507 array--; 515 array--;
508 } 516 }
509 517
@@ -523,9 +531,16 @@ static int perf_event__parse_id_sample(const union perf_event *event, u64 type,
523 } 531 }
524 532
525 if (type & PERF_SAMPLE_TID) { 533 if (type & PERF_SAMPLE_TID) {
526 u32 *p = (u32 *)array; 534 u.val64 = *array;
527 sample->pid = p[0]; 535 if (swapped) {
528 sample->tid = p[1]; 536 /* undo swap of u64, then swap on individual u32s */
537 u.val64 = bswap_64(u.val64);
538 u.val32[0] = bswap_32(u.val32[0]);
539 u.val32[1] = bswap_32(u.val32[1]);
540 }
541
542 sample->pid = u.val32[0];
543 sample->tid = u.val32[1];
529 } 544 }
530 545
531 return 0; 546 return 0;
@@ -562,7 +577,7 @@ int perf_event__parse_sample(const union perf_event *event, u64 type,
562 if (event->header.type != PERF_RECORD_SAMPLE) { 577 if (event->header.type != PERF_RECORD_SAMPLE) {
563 if (!sample_id_all) 578 if (!sample_id_all)
564 return 0; 579 return 0;
565 return perf_event__parse_id_sample(event, type, data); 580 return perf_event__parse_id_sample(event, type, data, swapped);
566 } 581 }
567 582
568 array = event->sample.array; 583 array = event->sample.array;