Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf evsel: Fix swap for samples with raw data

When we detect a different endianity we swap event before processing.
It's tricky for samples because we have no idea what's inside. We treat
it as an array of u64s, swap them and later on we swap back parts which
are different.

We mangle this way also the tracepoint raw data, which ends up in report
showing wrong data:

1.95% comm=Q^B pid=29285 prio=16777216 target_cpu=000
1.67% comm=l^B pid=0 prio=16777216 target_cpu=000

Luckily the traceevent library handles the endianity by itself (thank
you Steven!), so we can pass the RAW data directly in the other
endianity.

2.51% comm=beah-rhts-task pid=1175 prio=120 target_cpu=002
2.23% comm=kworker/0:0 pid=11566 prio=120 target_cpu=000

The fix is basically to swap back the raw data if different endianity is
detected.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Link: http://lkml.kernel.org/r/20171129184346.3656-1-jolsa@kernel.org
[ Add util/memswap.c to python-ext-sources to link missing mem_bswap_64() ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Jiri Olsa and committed by
Arnaldo Carvalho de Melo
f9d8adb3 c588d158

+18 -3
+17 -3
tools/perf/util/evsel.c
··· 36 36 #include "debug.h" 37 37 #include "trace-event.h" 38 38 #include "stat.h" 39 + #include "memswap.h" 39 40 #include "util/parse-branch-options.h" 40 41 41 42 #include "sane_ctype.h" ··· 2132 2131 if (type & PERF_SAMPLE_RAW) { 2133 2132 OVERFLOW_CHECK_u64(array); 2134 2133 u.val64 = *array; 2135 - if (WARN_ONCE(swapped, 2136 - "Endianness of raw data not corrected!\n")) { 2137 - /* undo swap of u64, then swap on individual u32s */ 2134 + 2135 + /* 2136 + * Undo swap of u64, then swap on individual u32s, 2137 + * get the size of the raw area and undo all of the 2138 + * swap. The pevent interface handles endianity by 2139 + * itself. 2140 + */ 2141 + if (swapped) { 2138 2142 u.val64 = bswap_64(u.val64); 2139 2143 u.val32[0] = bswap_32(u.val32[0]); 2140 2144 u.val32[1] = bswap_32(u.val32[1]); 2141 2145 } 2142 2146 data->raw_size = u.val32[0]; 2147 + 2148 + /* 2149 + * The raw data is aligned on 64bits including the 2150 + * u32 size, so it's safe to use mem_bswap_64. 2151 + */ 2152 + if (swapped) 2153 + mem_bswap_64((void *) array, data->raw_size); 2154 + 2143 2155 array = (void *)array + sizeof(u32); 2144 2156 2145 2157 OVERFLOW_CHECK(array, data->raw_size, max_size);
+1
tools/perf/util/python-ext-sources
··· 10 10 util/evlist.c 11 11 util/evsel.c 12 12 util/cpumap.c 13 + util/memswap.c 13 14 util/mmap.c 14 15 util/namespaces.c 15 16 ../lib/bitmap.c