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

perf tests: Add dwarf unwind test on ARM

Adding dwarf unwind test, that setups live machine data over
the perf test thread and does the remote unwind.

Need to use -fno-optimize-sibling-calls for test compilation,
otherwise 'krava_*' function calls are optimized into jumps
and omitted from the stack unwind.

So far it was enabled only for x86.

Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
Reviewed-by: Will Deacon <will.deacon@arm.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1400229672-16104-3-git-send-email-jean.pihet@linaro.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>

authored by

Jean Pihet and committed by
Jiri Olsa
90fa9deb 3418f966

+69 -5
+1 -1
tools/perf/Makefile.perf
··· 411 411 LIB_OBJS += $(OUTPUT)tests/sample-parsing.o 412 412 LIB_OBJS += $(OUTPUT)tests/parse-no-sample-id-all.o 413 413 ifndef NO_DWARF_UNWIND 414 - ifeq ($(ARCH),x86) 414 + ifeq ($(ARCH),$(filter $(ARCH),x86 arm)) 415 415 LIB_OBJS += $(OUTPUT)tests/dwarf-unwind.o 416 416 endif 417 417 endif
+1
tools/perf/arch/arm/Makefile
··· 5 5 ifndef NO_LIBUNWIND 6 6 LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/unwind-libunwind.o 7 7 LIB_OBJS += $(OUTPUT)arch/$(ARCH)/tests/regs_load.o 8 + LIB_OBJS += $(OUTPUT)arch/$(ARCH)/tests/dwarf-unwind.o 8 9 endif
+3
tools/perf/arch/arm/include/perf_regs.h
··· 8 8 void perf_regs_load(u64 *regs); 9 9 10 10 #define PERF_REGS_MASK ((1ULL << PERF_REG_ARM_MAX) - 1) 11 + #define PERF_REGS_MAX PERF_REG_ARM_MAX 12 + #define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_32 13 + 11 14 #define PERF_REG_IP PERF_REG_ARM_PC 12 15 #define PERF_REG_SP PERF_REG_ARM_SP 13 16
+60
tools/perf/arch/arm/tests/dwarf-unwind.c
··· 1 + #include <string.h> 2 + #include "perf_regs.h" 3 + #include "thread.h" 4 + #include "map.h" 5 + #include "event.h" 6 + #include "tests/tests.h" 7 + 8 + #define STACK_SIZE 8192 9 + 10 + static int sample_ustack(struct perf_sample *sample, 11 + struct thread *thread, u64 *regs) 12 + { 13 + struct stack_dump *stack = &sample->user_stack; 14 + struct map *map; 15 + unsigned long sp; 16 + u64 stack_size, *buf; 17 + 18 + buf = malloc(STACK_SIZE); 19 + if (!buf) { 20 + pr_debug("failed to allocate sample uregs data\n"); 21 + return -1; 22 + } 23 + 24 + sp = (unsigned long) regs[PERF_REG_ARM_SP]; 25 + 26 + map = map_groups__find(thread->mg, MAP__VARIABLE, (u64) sp); 27 + if (!map) { 28 + pr_debug("failed to get stack map\n"); 29 + free(buf); 30 + return -1; 31 + } 32 + 33 + stack_size = map->end - sp; 34 + stack_size = stack_size > STACK_SIZE ? STACK_SIZE : stack_size; 35 + 36 + memcpy(buf, (void *) sp, stack_size); 37 + stack->data = (char *) buf; 38 + stack->size = stack_size; 39 + return 0; 40 + } 41 + 42 + int test__arch_unwind_sample(struct perf_sample *sample, 43 + struct thread *thread) 44 + { 45 + struct regs_dump *regs = &sample->user_regs; 46 + u64 *buf; 47 + 48 + buf = calloc(1, sizeof(u64) * PERF_REGS_MAX); 49 + if (!buf) { 50 + pr_debug("failed to allocate sample uregs data\n"); 51 + return -1; 52 + } 53 + 54 + perf_regs_load(buf); 55 + regs->abi = PERF_SAMPLE_REGS_ABI; 56 + regs->regs = buf; 57 + regs->mask = PERF_REGS_MASK; 58 + 59 + return sample_ustack(sample, thread, buf); 60 + }
+2 -2
tools/perf/config/Makefile
··· 40 40 LIBUNWIND_LIBS = -lunwind -lunwind-aarch64 41 41 endif 42 42 43 - # So far there's only x86 libdw unwind support merged in perf. 43 + # So far there's only x86 and arm libdw unwind support merged in perf. 44 44 # Disable it on all other architectures in case libdw unwind 45 45 # support is detected in system. Add supported architectures 46 46 # to the check. 47 - ifneq ($(ARCH),x86) 47 + ifneq ($(ARCH),$(filter $(ARCH),x86 arm)) 48 48 NO_LIBDW_DWARF_UNWIND := 1 49 49 endif 50 50
+1 -1
tools/perf/tests/builtin-test.c
··· 115 115 .desc = "Test parsing with no sample_id_all bit set", 116 116 .func = test__parse_no_sample_id_all, 117 117 }, 118 - #if defined(__x86_64__) || defined(__i386__) 118 + #if defined(__x86_64__) || defined(__i386__) || defined(__arm__) 119 119 #ifdef HAVE_DWARF_UNWIND_SUPPORT 120 120 { 121 121 .desc = "Test dwarf unwind",
+1 -1
tools/perf/tests/tests.h
··· 45 45 int test__mmap_thread_lookup(void); 46 46 int test__thread_mg_share(void); 47 47 48 - #if defined(__x86_64__) || defined(__i386__) 48 + #if defined(__x86_64__) || defined(__i386__) || defined(__arm__) 49 49 #ifdef HAVE_DWARF_UNWIND_SUPPORT 50 50 struct thread; 51 51 struct perf_sample;