* [PATCH v3 0/4] perf: parse the dwarf backtrace info from .debug_frame section @ 2013-09-26 11:36 Jean Pihet 2013-09-26 11:36 ` [PATCH 1/4] ARM: perf: add support for perf registers API Jean Pihet ` (3 more replies) 0 siblings, 4 replies; 14+ messages in thread From: Jean Pihet @ 2013-09-26 11:36 UTC (permalink / raw) To: linux-arm-kernel On ARM the debug info is not present in the .eh_frame sections but in .debug_frame instead, in dwarf format. This patch set uses libunwind to load and parse the dwarf debug info from the .debug_frame section if no .eh_frame_hdr section is found; also it sets the hooks in the perf_regs and libunwind code for ARMv7. Dependencies: . if present, libunwind >= 1.1 is needed to prevent a segfault when parsing the dwarf info, . libunwind needs to be configured with --enable-debug-frame. Note: --enable-debug-frame is automatically selected on ARM. The generated perf binary has been tested on ARMv7 (OMAP4, Marvell Armada XP) and x86_64, using the following commands: perf record -g [dwarf] -- <binary> perf report --sort symbol --call-graph --stdio Jean Pihet (2): perf tools: Check libunwind for availability of dwarf parsing feature perf: parse the .debug_frame section in case .eh_frame is not present Will Deacon (2): ARM: perf: add support for perf registers API ARM: perf: wire up perf_regs and unwind support for ARM arch/arm/Kconfig | 2 + arch/arm/include/uapi/asm/Kbuild | 1 + arch/arm/include/uapi/asm/perf_regs.h | 23 ++++++++++ arch/arm/kernel/Makefile | 1 + arch/arm/kernel/perf_regs.c | 30 +++++++++++++ tools/perf/arch/arm/Makefile | 3 ++ tools/perf/arch/arm/include/perf_regs.h | 54 ++++++++++++++++++++++++ tools/perf/arch/arm/util/unwind.c | 48 +++++++++++++++++++++ tools/perf/config/Makefile | 13 ++++-- tools/perf/config/feature-tests.mak | 21 ++++++++- tools/perf/util/unwind.c | 75 ++++++++++++++++++++++++++------- 11 files changed, 251 insertions(+), 20 deletions(-) create mode 100644 arch/arm/include/uapi/asm/perf_regs.h create mode 100644 arch/arm/kernel/perf_regs.c create mode 100644 tools/perf/arch/arm/include/perf_regs.h create mode 100644 tools/perf/arch/arm/util/unwind.c -- 1.7.11.7 ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 1/4] ARM: perf: add support for perf registers API 2013-09-26 11:36 [PATCH v3 0/4] perf: parse the dwarf backtrace info from .debug_frame section Jean Pihet @ 2013-09-26 11:36 ` Jean Pihet 2013-09-26 11:36 ` [PATCH 2/4] ARM: perf: wire up perf_regs and unwind support for ARM Jean Pihet ` (2 subsequent siblings) 3 siblings, 0 replies; 14+ messages in thread From: Jean Pihet @ 2013-09-26 11:36 UTC (permalink / raw) To: linux-arm-kernel From: Will Deacon <will.deacon@arm.com> This patch implements the functions required for the perf registers API, allowing the perf tool to interface kernel register dumps with libunwind in order to provide userspace backtracing. Signed-off-by: Will Deacon <will.deacon@arm.com> Cc: Jean Pihet <jean.pihet@linaro.org> --- arch/arm/Kconfig | 2 ++ arch/arm/include/uapi/asm/Kbuild | 1 + arch/arm/include/uapi/asm/perf_regs.h | 23 +++++++++++++++++++++++ arch/arm/kernel/Makefile | 1 + arch/arm/kernel/perf_regs.c | 30 ++++++++++++++++++++++++++++++ 5 files changed, 57 insertions(+) create mode 100644 arch/arm/include/uapi/asm/perf_regs.h create mode 100644 arch/arm/kernel/perf_regs.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 3f7714d..5595888 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -51,6 +51,8 @@ config ARM select HAVE_MOD_ARCH_SPECIFIC if ARM_UNWIND select HAVE_OPROFILE if (HAVE_PERF_EVENTS) select HAVE_PERF_EVENTS + select HAVE_PERF_REGS + select HAVE_PERF_USER_STACK_DUMP select HAVE_REGS_AND_STACK_ACCESS_API select HAVE_SYSCALL_TRACEPOINTS select HAVE_UID16 diff --git a/arch/arm/include/uapi/asm/Kbuild b/arch/arm/include/uapi/asm/Kbuild index 18d76fd..70a1c9d 100644 --- a/arch/arm/include/uapi/asm/Kbuild +++ b/arch/arm/include/uapi/asm/Kbuild @@ -7,6 +7,7 @@ header-y += hwcap.h header-y += ioctls.h header-y += kvm_para.h header-y += mman.h +header-y += perf_regs.h header-y += posix_types.h header-y += ptrace.h header-y += setup.h diff --git a/arch/arm/include/uapi/asm/perf_regs.h b/arch/arm/include/uapi/asm/perf_regs.h new file mode 100644 index 0000000..ce59448 --- /dev/null +++ b/arch/arm/include/uapi/asm/perf_regs.h @@ -0,0 +1,23 @@ +#ifndef _ASM_ARM_PERF_REGS_H +#define _ASM_ARM_PERF_REGS_H + +enum perf_event_arm_regs { + PERF_REG_ARM_R0, + PERF_REG_ARM_R1, + PERF_REG_ARM_R2, + PERF_REG_ARM_R3, + PERF_REG_ARM_R4, + PERF_REG_ARM_R5, + PERF_REG_ARM_R6, + PERF_REG_ARM_R7, + PERF_REG_ARM_R8, + PERF_REG_ARM_R9, + PERF_REG_ARM_R10, + PERF_REG_ARM_FP, + PERF_REG_ARM_IP, + PERF_REG_ARM_SP, + PERF_REG_ARM_LR, + PERF_REG_ARM_PC, + PERF_REG_ARM_MAX, +}; +#endif /* _ASM_ARM_PERF_REGS_H */ diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 5140df5f..9b818ca 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -78,6 +78,7 @@ obj-$(CONFIG_CPU_XSC3) += xscale-cp0.o obj-$(CONFIG_CPU_MOHAWK) += xscale-cp0.o obj-$(CONFIG_CPU_PJ4) += pj4-cp0.o obj-$(CONFIG_IWMMXT) += iwmmxt.o +obj-$(CONFIG_PERF_EVENTS) += perf_regs.o obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o perf_event_cpu.o AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt obj-$(CONFIG_ARM_CPU_TOPOLOGY) += topology.o diff --git a/arch/arm/kernel/perf_regs.c b/arch/arm/kernel/perf_regs.c new file mode 100644 index 0000000..6e4379c --- /dev/null +++ b/arch/arm/kernel/perf_regs.c @@ -0,0 +1,30 @@ + +#include <linux/errno.h> +#include <linux/kernel.h> +#include <linux/perf_event.h> +#include <linux/bug.h> +#include <asm/perf_regs.h> +#include <asm/ptrace.h> + +u64 perf_reg_value(struct pt_regs *regs, int idx) +{ + if (WARN_ON_ONCE((u32)idx >= PERF_REG_ARM_MAX)) + return 0; + + return regs->uregs[idx]; +} + +#define REG_RESERVED (~((1ULL << PERF_REG_ARM_MAX) - 1)) + +int perf_reg_validate(u64 mask) +{ + if (!mask || mask & REG_RESERVED) + return -EINVAL; + + return 0; +} + +u64 perf_reg_abi(struct task_struct *task) +{ + return PERF_SAMPLE_REGS_ABI_32; +} -- 1.7.11.7 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 2/4] ARM: perf: wire up perf_regs and unwind support for ARM 2013-09-26 11:36 [PATCH v3 0/4] perf: parse the dwarf backtrace info from .debug_frame section Jean Pihet 2013-09-26 11:36 ` [PATCH 1/4] ARM: perf: add support for perf registers API Jean Pihet @ 2013-09-26 11:36 ` Jean Pihet 2013-09-26 11:36 ` [PATCH 3/4] perf tools: Check libunwind for availability of dwarf parsing feature Jean Pihet 2013-09-26 11:36 ` [PATCH 4/4] perf: parse the .debug_frame section in case .eh_frame is not present Jean Pihet 3 siblings, 0 replies; 14+ messages in thread From: Jean Pihet @ 2013-09-26 11:36 UTC (permalink / raw) To: linux-arm-kernel From: Will Deacon <will.deacon@arm.com> This patch hooks in the perf_regs and libunwind code for ARM. Signed-off-by: Will Deacon <will.deacon@arm.com> Cc: Jean Pihet <jean.pihet@linaro.org> --- tools/perf/arch/arm/Makefile | 3 ++ tools/perf/arch/arm/include/perf_regs.h | 54 +++++++++++++++++++++++++++++++++ tools/perf/arch/arm/util/unwind.c | 48 +++++++++++++++++++++++++++++ tools/perf/config/Makefile | 7 +++-- 4 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 tools/perf/arch/arm/include/perf_regs.h create mode 100644 tools/perf/arch/arm/util/unwind.c diff --git a/tools/perf/arch/arm/Makefile b/tools/perf/arch/arm/Makefile index 15130b5..fe9b61e 100644 --- a/tools/perf/arch/arm/Makefile +++ b/tools/perf/arch/arm/Makefile @@ -2,3 +2,6 @@ ifndef NO_DWARF PERF_HAVE_DWARF_REGS := 1 LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o endif +ifndef NO_LIBUNWIND +LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/unwind.o +endif diff --git a/tools/perf/arch/arm/include/perf_regs.h b/tools/perf/arch/arm/include/perf_regs.h new file mode 100644 index 0000000..2a1cfde --- /dev/null +++ b/tools/perf/arch/arm/include/perf_regs.h @@ -0,0 +1,54 @@ +#ifndef ARCH_PERF_REGS_H +#define ARCH_PERF_REGS_H + +#include <stdlib.h> +#include "../../util/types.h" +#include <asm/perf_regs.h> + +#define PERF_REGS_MASK ((1ULL << PERF_REG_ARM_MAX) - 1) +#define PERF_REG_IP PERF_REG_ARM_PC +#define PERF_REG_SP PERF_REG_ARM_SP + +static inline const char *perf_reg_name(int id) +{ + switch (id) { + case PERF_REG_ARM_R0: + return "r0"; + case PERF_REG_ARM_R1: + return "r1"; + case PERF_REG_ARM_R2: + return "r2"; + case PERF_REG_ARM_R3: + return "r3"; + case PERF_REG_ARM_R4: + return "r4"; + case PERF_REG_ARM_R5: + return "r5"; + case PERF_REG_ARM_R6: + return "r6"; + case PERF_REG_ARM_R7: + return "r7"; + case PERF_REG_ARM_R8: + return "r8"; + case PERF_REG_ARM_R9: + return "r9"; + case PERF_REG_ARM_R10: + return "r10"; + case PERF_REG_ARM_FP: + return "fp"; + case PERF_REG_ARM_IP: + return "ip"; + case PERF_REG_ARM_SP: + return "sp"; + case PERF_REG_ARM_LR: + return "lr"; + case PERF_REG_ARM_PC: + return "pc"; + default: + return NULL; + } + + return NULL; +} + +#endif /* ARCH_PERF_REGS_H */ diff --git a/tools/perf/arch/arm/util/unwind.c b/tools/perf/arch/arm/util/unwind.c new file mode 100644 index 0000000..da3dc95 --- /dev/null +++ b/tools/perf/arch/arm/util/unwind.c @@ -0,0 +1,48 @@ + +#include <errno.h> +#include <libunwind.h> +#include "perf_regs.h" +#include "../../util/unwind.h" + +int unwind__arch_reg_id(int regnum) +{ + switch (regnum) { + case UNW_ARM_R0: + return PERF_REG_ARM_R0; + case UNW_ARM_R1: + return PERF_REG_ARM_R1; + case UNW_ARM_R2: + return PERF_REG_ARM_R2; + case UNW_ARM_R3: + return PERF_REG_ARM_R3; + case UNW_ARM_R4: + return PERF_REG_ARM_R4; + case UNW_ARM_R5: + return PERF_REG_ARM_R5; + case UNW_ARM_R6: + return PERF_REG_ARM_R6; + case UNW_ARM_R7: + return PERF_REG_ARM_R7; + case UNW_ARM_R8: + return PERF_REG_ARM_R8; + case UNW_ARM_R9: + return PERF_REG_ARM_R9; + case UNW_ARM_R10: + return PERF_REG_ARM_R10; + case UNW_ARM_R11: + return PERF_REG_ARM_FP; + case UNW_ARM_R12: + return PERF_REG_ARM_IP; + case UNW_ARM_R13: + return PERF_REG_ARM_SP; + case UNW_ARM_R14: + return PERF_REG_ARM_LR; + case UNW_ARM_R15: + return PERF_REG_ARM_PC; + default: + pr_err("unwind: invalid reg id %d\n", regnum); + return -EINVAL; + } + + return -EINVAL; +} diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 214e17e..4b65710 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -29,6 +29,10 @@ ifeq ($(ARCH),x86_64) NO_PERF_REGS := 0 LIBUNWIND_LIBS = -lunwind -lunwind-x86_64 endif +ifeq ($(ARCH),arm) + NO_PERF_REGS := 0 + LIBUNWIND_LIBS = -lunwind -lunwind-arm +endif ifeq ($(NO_PERF_REGS),0) CFLAGS += -DHAVE_PERF_REGS @@ -205,8 +209,7 @@ ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y) endif # try-cc endif # NO_LIBELF -# There's only x86 (both 32 and 64) support for CFI unwind so far -ifneq ($(ARCH),x86) +ifeq ($(LIBUNWIND_LIBS),) NO_LIBUNWIND := 1 endif -- 1.7.11.7 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 3/4] perf tools: Check libunwind for availability of dwarf parsing feature 2013-09-26 11:36 [PATCH v3 0/4] perf: parse the dwarf backtrace info from .debug_frame section Jean Pihet 2013-09-26 11:36 ` [PATCH 1/4] ARM: perf: add support for perf registers API Jean Pihet 2013-09-26 11:36 ` [PATCH 2/4] ARM: perf: wire up perf_regs and unwind support for ARM Jean Pihet @ 2013-09-26 11:36 ` Jean Pihet 2013-09-26 12:48 ` Jiri Olsa 2013-09-26 11:36 ` [PATCH 4/4] perf: parse the .debug_frame section in case .eh_frame is not present Jean Pihet 3 siblings, 1 reply; 14+ messages in thread From: Jean Pihet @ 2013-09-26 11:36 UTC (permalink / raw) To: linux-arm-kernel The newly added dwarf unwinding feature [1] requires: . a recent version (>= 1.1) of libunwind, . libunwind to be configured with --enable-debug-frame. [1] http://www.spinics.net/lists/kernel/msg1598951.html Add the corresponding API tests in the feature check list. Signed-off-by: Jean Pihet <jean.pihet@linaro.org> --- tools/perf/config/Makefile | 6 +++++- tools/perf/config/feature-tests.mak | 21 ++++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 4b65710..bbaeb04 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -223,9 +223,13 @@ endif FLAGS_UNWIND=$(LIBUNWIND_CFLAGS) $(CFLAGS) $(LIBUNWIND_LDFLAGS) $(LDFLAGS) $(EXTLIBS) $(LIBUNWIND_LIBS) ifneq ($(call try-cc,$(SOURCE_LIBUNWIND),$(FLAGS_UNWIND),libunwind),y) - msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 0.99); + msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 1.1); NO_LIBUNWIND := 1 endif # Libunwind support +ifneq ($(call try-cc,$(SOURCE_LIBUNWIND_DEBUG_FRAME),$(FLAGS_UNWIND),libunwind debug_frame),y) + msg := $(warning No debug_frame support found in libunwind); +CFLAGS += -DNO_LIBUNWIND_DEBUG_FRAME +endif # debug_frame support in libunwind endif # NO_LIBUNWIND ifndef NO_LIBUNWIND diff --git a/tools/perf/config/feature-tests.mak b/tools/perf/config/feature-tests.mak index 708fb8e..cde75f5 100644 --- a/tools/perf/config/feature-tests.mak +++ b/tools/perf/config/feature-tests.mak @@ -176,7 +176,6 @@ extern int UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as, unw_proc_info_t *pi, int need_unwind_info, void *arg); - #define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table) int main(void) @@ -188,6 +187,26 @@ int main(void) return 0; } endef + +define SOURCE_LIBUNWIND_DEBUG_FRAME +#include <libunwind.h> +#include <stdlib.h> + +extern int +UNW_OBJ(dwarf_find_debug_frame) (int found, unw_dyn_info_t *di_debug, + unw_word_t ip, unw_word_t segbase, + const char *obj_name, unw_word_t start, + unw_word_t end); + +#define dwarf_find_debug_frame UNW_OBJ(dwarf_find_debug_frame) + +int main(void) +{ + dwarf_find_debug_frame(0, NULL, 0, 0, NULL, 0, 0); + return 0; +} +endef + endif ifndef NO_BACKTRACE -- 1.7.11.7 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 3/4] perf tools: Check libunwind for availability of dwarf parsing feature 2013-09-26 11:36 ` [PATCH 3/4] perf tools: Check libunwind for availability of dwarf parsing feature Jean Pihet @ 2013-09-26 12:48 ` Jiri Olsa 2013-10-08 10:44 ` Jean Pihet 0 siblings, 1 reply; 14+ messages in thread From: Jiri Olsa @ 2013-09-26 12:48 UTC (permalink / raw) To: linux-arm-kernel On Thu, Sep 26, 2013 at 01:36:37PM +0200, Jean Pihet wrote: > The newly added dwarf unwinding feature [1] requires: > . a recent version (>= 1.1) of libunwind, > . libunwind to be configured with --enable-debug-frame. > > [1] http://www.spinics.net/lists/kernel/msg1598951.html > > Add the corresponding API tests in the feature check list. Acked-by: Jiri Olsa <jolsa@redhat.com> thanks, jirka ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 3/4] perf tools: Check libunwind for availability of dwarf parsing feature 2013-09-26 12:48 ` Jiri Olsa @ 2013-10-08 10:44 ` Jean Pihet 2013-10-08 10:47 ` Peter Zijlstra 0 siblings, 1 reply; 14+ messages in thread From: Jean Pihet @ 2013-10-08 10:44 UTC (permalink / raw) To: linux-arm-kernel Hi, On 26 September 2013 14:48, Jiri Olsa <jolsa@redhat.com> wrote: > On Thu, Sep 26, 2013 at 01:36:37PM +0200, Jean Pihet wrote: >> The newly added dwarf unwinding feature [1] requires: >> . a recent version (>= 1.1) of libunwind, >> . libunwind to be configured with --enable-debug-frame. >> >> [1] http://www.spinics.net/lists/kernel/msg1598951.html >> >> Add the corresponding API tests in the feature check list. > > Acked-by: Jiri Olsa <jolsa@redhat.com> > > thanks, > jirka Thanks for the ack! Is it possible to get an ack from the perf core maintainers? Also, is the patch going in Will's tree? Regards, Jean ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 3/4] perf tools: Check libunwind for availability of dwarf parsing feature 2013-10-08 10:44 ` Jean Pihet @ 2013-10-08 10:47 ` Peter Zijlstra 2013-10-08 14:15 ` Jean Pihet 0 siblings, 1 reply; 14+ messages in thread From: Peter Zijlstra @ 2013-10-08 10:47 UTC (permalink / raw) To: linux-arm-kernel On Tue, Oct 08, 2013 at 12:44:32PM +0200, Jean Pihet wrote: > Hi, > > On 26 September 2013 14:48, Jiri Olsa <jolsa@redhat.com> wrote: > > On Thu, Sep 26, 2013 at 01:36:37PM +0200, Jean Pihet wrote: > >> The newly added dwarf unwinding feature [1] requires: > >> . a recent version (>= 1.1) of libunwind, > >> . libunwind to be configured with --enable-debug-frame. > >> > >> [1] http://www.spinics.net/lists/kernel/msg1598951.html > >> > >> Add the corresponding API tests in the feature check list. > > > > Acked-by: Jiri Olsa <jolsa@redhat.com> > > > > thanks, > > jirka > > Thanks for the ack! > > Is it possible to get an ack from the perf core maintainers? > Also, is the patch going in Will's tree? This being a tools patch you'd have to ask acme; also I know next to nothing about all this unwind business except that its stupid expensive ;-) ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 3/4] perf tools: Check libunwind for availability of dwarf parsing feature 2013-10-08 10:47 ` Peter Zijlstra @ 2013-10-08 14:15 ` Jean Pihet 2013-10-08 14:28 ` Arnaldo Carvalho de Melo 0 siblings, 1 reply; 14+ messages in thread From: Jean Pihet @ 2013-10-08 14:15 UTC (permalink / raw) To: linux-arm-kernel Hi, On 8 October 2013 12:47, Peter Zijlstra <peterz@infradead.org> wrote: > On Tue, Oct 08, 2013 at 12:44:32PM +0200, Jean Pihet wrote: >> Hi, >> >> On 26 September 2013 14:48, Jiri Olsa <jolsa@redhat.com> wrote: >> > On Thu, Sep 26, 2013 at 01:36:37PM +0200, Jean Pihet wrote: >> >> The newly added dwarf unwinding feature [1] requires: >> >> . a recent version (>= 1.1) of libunwind, >> >> . libunwind to be configured with --enable-debug-frame. >> >> >> >> [1] http://www.spinics.net/lists/kernel/msg1598951.html >> >> >> >> Add the corresponding API tests in the feature check list. >> > >> > Acked-by: Jiri Olsa <jolsa@redhat.com> >> > >> > thanks, >> > jirka >> >> Thanks for the ack! >> >> Is it possible to get an ack from the perf core maintainers? >> Also, is the patch going in Will's tree? > > This being a tools patch you'd have to ask acme; also I know next to > nothing about all this unwind business except that its stupid expensive > ;-) You are right! It brings some more info on the trace though. -- adding Arnaldo in the loop -- Arnaldo, are you OK with the changes [1]? Jiri acked the patches already; Will is willing (no pun intended) to take the ARM specific patches [2] in his tree. [1] http://www.spinics.net/lists/kernel/msg1608921.html and http://www.spinics.net/lists/kernel/msg1608922.html [2] http://www.spinics.net/lists/kernel/msg1608920.html and http://www.spinics.net/lists/kernel/msg1608923.html Regards, Jean ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 3/4] perf tools: Check libunwind for availability of dwarf parsing feature 2013-10-08 14:15 ` Jean Pihet @ 2013-10-08 14:28 ` Arnaldo Carvalho de Melo 2013-10-08 14:31 ` Will Deacon 0 siblings, 1 reply; 14+ messages in thread From: Arnaldo Carvalho de Melo @ 2013-10-08 14:28 UTC (permalink / raw) To: linux-arm-kernel Em Tue, Oct 08, 2013 at 04:15:40PM +0200, Jean Pihet escreveu: > On 8 October 2013 12:47, Peter Zijlstra <peterz@infradead.org> wrote: > > On Tue, Oct 08, 2013 at 12:44:32PM +0200, Jean Pihet wrote: > >> On 26 September 2013 14:48, Jiri Olsa <jolsa@redhat.com> wrote: > >> > On Thu, Sep 26, 2013 at 01:36:37PM +0200, Jean Pihet wrote: > >> >> The newly added dwarf unwinding feature [1] requires: > >> >> . a recent version (>= 1.1) of libunwind, > >> >> . libunwind to be configured with --enable-debug-frame. > >> >> [1] http://www.spinics.net/lists/kernel/msg1598951.html > >> >> Add the corresponding API tests in the feature check list. > >> > Acked-by: Jiri Olsa <jolsa@redhat.com> > >> Thanks for the ack! > >> Is it possible to get an ack from the perf core maintainers? > >> Also, is the patch going in Will's tree? > > This being a tools patch you'd have to ask acme; also I know next to > > nothing about all this unwind business except that its stupid expensive > > ;-) > You are right! It brings some more info on the trace though. > -- adding Arnaldo in the loop -- > Arnaldo, are you OK with the changes [1]? Jiri acked the patches > already; Will is willing (no pun intended) to take the ARM specific > patches [2] in his tree. As Jiri acked, go ahead and pick as much as you can via Will's tree, I'd say. :-) - Arnaldo > [1] http://www.spinics.net/lists/kernel/msg1608921.html and > http://www.spinics.net/lists/kernel/msg1608922.html > [2] http://www.spinics.net/lists/kernel/msg1608920.html and > http://www.spinics.net/lists/kernel/msg1608923.html > > Regards, > Jean ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 3/4] perf tools: Check libunwind for availability of dwarf parsing feature 2013-10-08 14:28 ` Arnaldo Carvalho de Melo @ 2013-10-08 14:31 ` Will Deacon 0 siblings, 0 replies; 14+ messages in thread From: Will Deacon @ 2013-10-08 14:31 UTC (permalink / raw) To: linux-arm-kernel On Tue, Oct 08, 2013 at 03:28:30PM +0100, Arnaldo Carvalho de Melo wrote: > Em Tue, Oct 08, 2013 at 04:15:40PM +0200, Jean Pihet escreveu: > > >> On 26 September 2013 14:48, Jiri Olsa <jolsa@redhat.com> wrote: > > > >> > Acked-by: Jiri Olsa <jolsa@redhat.com> > > > -- adding Arnaldo in the loop -- > > Arnaldo, are you OK with the changes [1]? Jiri acked the patches > > already; Will is willing (no pun intended) to take the ARM specific > > patches [2] in his tree. > > As Jiri acked, go ahead and pick as much as you can via Will's tree, I'd > say. :-) Cheers guys, that suits me! Will ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 4/4] perf: parse the .debug_frame section in case .eh_frame is not present 2013-09-26 11:36 [PATCH v3 0/4] perf: parse the dwarf backtrace info from .debug_frame section Jean Pihet ` (2 preceding siblings ...) 2013-09-26 11:36 ` [PATCH 3/4] perf tools: Check libunwind for availability of dwarf parsing feature Jean Pihet @ 2013-09-26 11:36 ` Jean Pihet 2013-09-26 12:49 ` Jiri Olsa 3 siblings, 1 reply; 14+ messages in thread From: Jean Pihet @ 2013-09-26 11:36 UTC (permalink / raw) To: linux-arm-kernel On ARM the debug info is not present in the .eh_frame sections but in .debug_frame instead, in dwarf format. Use libunwind to load and parse the debug info. Dependencies: . if present, libunwind >= 1.1 is needed to prevent a segfault when parsing the dwarf info, . libunwind needs to be configured with --enable-debug-frame. Note: --enable-debug-frame is automatically selected on ARM. Signed-off-by: Jean Pihet <jean.pihet@linaro.org> --- tools/perf/util/unwind.c | 75 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 59 insertions(+), 16 deletions(-) diff --git a/tools/perf/util/unwind.c b/tools/perf/util/unwind.c index 2f891f7..5390d0b 100644 --- a/tools/perf/util/unwind.c +++ b/tools/perf/util/unwind.c @@ -39,6 +39,15 @@ UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as, #define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table) +extern int +UNW_OBJ(dwarf_find_debug_frame) (int found, unw_dyn_info_t *di_debug, + unw_word_t ip, + unw_word_t segbase, + const char *obj_name, unw_word_t start, + unw_word_t end); + +#define dwarf_find_debug_frame UNW_OBJ(dwarf_find_debug_frame) + #define DW_EH_PE_FORMAT_MASK 0x0f /* format of the encoded value */ #define DW_EH_PE_APPL_MASK 0x70 /* how the value is to be applied */ @@ -245,8 +254,9 @@ static int unwind_spec_ehframe(struct dso *dso, struct machine *machine, return 0; } -static int read_unwind_spec(struct dso *dso, struct machine *machine, - u64 *table_data, u64 *segbase, u64 *fde_count) +static int read_unwind_spec_eh_frame(struct dso *dso, struct machine *machine, + u64 *table_data, u64 *segbase, + u64 *fde_count) { int ret = -EINVAL, fd; u64 offset; @@ -255,6 +265,7 @@ static int read_unwind_spec(struct dso *dso, struct machine *machine, if (fd < 0) return -EINVAL; + /* Check the .eh_frame section for unwinding info */ offset = elf_section_offset(fd, ".eh_frame_hdr"); close(fd); @@ -263,10 +274,29 @@ static int read_unwind_spec(struct dso *dso, struct machine *machine, table_data, segbase, fde_count); - /* TODO .debug_frame check if eh_frame_hdr fails */ return ret; } +#ifndef NO_LIBUNWIND_DEBUG_FRAME +static int read_unwind_spec_debug_frame(struct dso *dso, + struct machine *machine, u64 *offset) +{ + int fd = dso__data_fd(dso, machine); + + if (fd < 0) + return -EINVAL; + + /* Check the .debug_frame section for unwinding info */ + *offset = elf_section_offset(fd, ".debug_frame"); + close(fd); + + if (*offset) + return 0; + + return -EINVAL; +} +#endif + static struct map *find_map(unw_word_t ip, struct unwind_info *ui) { struct addr_location al; @@ -291,20 +321,33 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, pr_debug("unwind: find_proc_info dso %s\n", map->dso->name); - if (read_unwind_spec(map->dso, ui->machine, - &table_data, &segbase, &fde_count)) - return -EINVAL; + /* Check the .eh_frame section for unwinding info */ + if (!read_unwind_spec_eh_frame(map->dso, ui->machine, + &table_data, &segbase, &fde_count)) { + memset(&di, 0, sizeof(di)); + di.format = UNW_INFO_FORMAT_REMOTE_TABLE; + di.start_ip = map->start; + di.end_ip = map->end; + di.u.rti.segbase = map->start + segbase; + di.u.rti.table_data = map->start + table_data; + di.u.rti.table_len = fde_count * sizeof(struct table_entry) + / sizeof(unw_word_t); + return dwarf_search_unwind_table(as, ip, &di, pi, + need_unwind_info, arg); + } + +#ifndef NO_LIBUNWIND_DEBUG_FRAME + /* Check the .debug_frame section for unwinding info */ + if (!read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) { + memset(&di, 0, sizeof(di)); + dwarf_find_debug_frame(0, &di, ip, 0, map->dso->name, + map->start, map->end); + return dwarf_search_unwind_table(as, ip, &di, pi, + need_unwind_info, arg); + } +#endif - memset(&di, 0, sizeof(di)); - di.format = UNW_INFO_FORMAT_REMOTE_TABLE; - di.start_ip = map->start; - di.end_ip = map->end; - di.u.rti.segbase = map->start + segbase; - di.u.rti.table_data = map->start + table_data; - di.u.rti.table_len = fde_count * sizeof(struct table_entry) - / sizeof(unw_word_t); - return dwarf_search_unwind_table(as, ip, &di, pi, - need_unwind_info, arg); + return -EINVAL; } static int access_fpreg(unw_addr_space_t __maybe_unused as, -- 1.7.11.7 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 4/4] perf: parse the .debug_frame section in case .eh_frame is not present 2013-09-26 11:36 ` [PATCH 4/4] perf: parse the .debug_frame section in case .eh_frame is not present Jean Pihet @ 2013-09-26 12:49 ` Jiri Olsa 2013-10-08 10:44 ` Jean Pihet 0 siblings, 1 reply; 14+ messages in thread From: Jiri Olsa @ 2013-09-26 12:49 UTC (permalink / raw) To: linux-arm-kernel On Thu, Sep 26, 2013 at 01:36:38PM +0200, Jean Pihet wrote: > On ARM the debug info is not present in the .eh_frame sections but > in .debug_frame instead, in dwarf format. > Use libunwind to load and parse the debug info. > > Dependencies: > . if present, libunwind >= 1.1 is needed to prevent a segfault when > parsing the dwarf info, > . libunwind needs to be configured with --enable-debug-frame. Note: > --enable-debug-frame is automatically selected on ARM. Acked-by: Jiri Olsa <jolsa@redhat.com> thanks, jirka ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 4/4] perf: parse the .debug_frame section in case .eh_frame is not present 2013-09-26 12:49 ` Jiri Olsa @ 2013-10-08 10:44 ` Jean Pihet 0 siblings, 0 replies; 14+ messages in thread From: Jean Pihet @ 2013-10-08 10:44 UTC (permalink / raw) To: linux-arm-kernel Hi, On 26 September 2013 14:49, Jiri Olsa <jolsa@redhat.com> wrote: > On Thu, Sep 26, 2013 at 01:36:38PM +0200, Jean Pihet wrote: >> On ARM the debug info is not present in the .eh_frame sections but >> in .debug_frame instead, in dwarf format. >> Use libunwind to load and parse the debug info. >> >> Dependencies: >> . if present, libunwind >= 1.1 is needed to prevent a segfault when >> parsing the dwarf info, >> . libunwind needs to be configured with --enable-debug-frame. Note: >> --enable-debug-frame is automatically selected on ARM. > > Acked-by: Jiri Olsa <jolsa@redhat.com> > > thanks, > jirka Thanks for the ack! Is it possible to get an ack from the perf core maintainers? Also, is the patch going in Will's tree? Regards, Jean ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v2 0/4] perf: parse the dwarf backtrace info from .debug_frame section @ 2013-09-16 9:17 Jean Pihet 2013-09-16 9:17 ` [PATCH 1/4] ARM: perf: add support for perf registers API Jean Pihet 0 siblings, 1 reply; 14+ messages in thread From: Jean Pihet @ 2013-09-16 9:17 UTC (permalink / raw) To: linux-arm-kernel On ARM the debug info is not present in the .eh_frame sections but in .debug_frame instead, in dwarf format. This patch set uses libunwind to load and parse the dwarf debug info from the .debug_frame section if no .eh_frame_hdr section is found; also it sets the hooks in the perf_regs and libunwind code for ARMv7. Dependencies: . if present, libunwind >= 1.1 is needed to prevent a segfault when parsing the dwarf info, . libunwind needs to be configured with --enable-debug-frame to prevent a linkage error. Note: --enable-debug-frame is automatically selected on ARM). The generated perf has been tested on ARMv7 (OMAP4, Marvell Armada XP) and x86_64, using the following commands: perf record -g [dwarf] -- <binary> perf report --sort symbol --call-graph --stdio Jean Pihet (2): perf tools: Check libunwind for availability of dwarf parsing feature perf: parse the .debug_frame section in case .eh_frame is not present Will Deacon (2): ARM: perf: add support for perf registers API ARM: perf: wire up perf_regs and unwind support for ARM arch/arm/Kconfig | 2 + arch/arm/include/uapi/asm/Kbuild | 1 + arch/arm/include/uapi/asm/perf_regs.h | 23 +++++++++++ arch/arm/kernel/Makefile | 1 + arch/arm/kernel/perf_regs.c | 30 ++++++++++++++ tools/perf/arch/arm/Makefile | 3 ++ tools/perf/arch/arm/include/perf_regs.h | 54 +++++++++++++++++++++++++ tools/perf/arch/arm/util/unwind.c | 48 ++++++++++++++++++++++ tools/perf/config/Makefile | 7 +++- tools/perf/config/feature-tests.mak | 11 ++++- tools/perf/util/unwind.c | 71 +++++++++++++++++++++++++-------- 11 files changed, 232 insertions(+), 19 deletions(-) create mode 100644 arch/arm/include/uapi/asm/perf_regs.h create mode 100644 arch/arm/kernel/perf_regs.c create mode 100644 tools/perf/arch/arm/include/perf_regs.h create mode 100644 tools/perf/arch/arm/util/unwind.c -- 1.7.11.7 ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 1/4] ARM: perf: add support for perf registers API 2013-09-16 9:17 [PATCH v2 0/4] perf: parse the dwarf backtrace info from .debug_frame section Jean Pihet @ 2013-09-16 9:17 ` Jean Pihet 0 siblings, 0 replies; 14+ messages in thread From: Jean Pihet @ 2013-09-16 9:17 UTC (permalink / raw) To: linux-arm-kernel From: Will Deacon <will.deacon@arm.com> This patch implements the functions required for the perf registers API, allowing the perf tool to interface kernel register dumps with libunwind in order to provide userspace backtracing. Signed-off-by: Will Deacon <will.deacon@arm.com> Cc: Jean Pihet <jean.pihet@linaro.org> --- arch/arm/Kconfig | 2 ++ arch/arm/include/uapi/asm/Kbuild | 1 + arch/arm/include/uapi/asm/perf_regs.h | 23 +++++++++++++++++++++++ arch/arm/kernel/Makefile | 1 + arch/arm/kernel/perf_regs.c | 30 ++++++++++++++++++++++++++++++ 5 files changed, 57 insertions(+) create mode 100644 arch/arm/include/uapi/asm/perf_regs.h create mode 100644 arch/arm/kernel/perf_regs.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 3f7714d..5595888 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -51,6 +51,8 @@ config ARM select HAVE_MOD_ARCH_SPECIFIC if ARM_UNWIND select HAVE_OPROFILE if (HAVE_PERF_EVENTS) select HAVE_PERF_EVENTS + select HAVE_PERF_REGS + select HAVE_PERF_USER_STACK_DUMP select HAVE_REGS_AND_STACK_ACCESS_API select HAVE_SYSCALL_TRACEPOINTS select HAVE_UID16 diff --git a/arch/arm/include/uapi/asm/Kbuild b/arch/arm/include/uapi/asm/Kbuild index 18d76fd..70a1c9d 100644 --- a/arch/arm/include/uapi/asm/Kbuild +++ b/arch/arm/include/uapi/asm/Kbuild @@ -7,6 +7,7 @@ header-y += hwcap.h header-y += ioctls.h header-y += kvm_para.h header-y += mman.h +header-y += perf_regs.h header-y += posix_types.h header-y += ptrace.h header-y += setup.h diff --git a/arch/arm/include/uapi/asm/perf_regs.h b/arch/arm/include/uapi/asm/perf_regs.h new file mode 100644 index 0000000..ce59448 --- /dev/null +++ b/arch/arm/include/uapi/asm/perf_regs.h @@ -0,0 +1,23 @@ +#ifndef _ASM_ARM_PERF_REGS_H +#define _ASM_ARM_PERF_REGS_H + +enum perf_event_arm_regs { + PERF_REG_ARM_R0, + PERF_REG_ARM_R1, + PERF_REG_ARM_R2, + PERF_REG_ARM_R3, + PERF_REG_ARM_R4, + PERF_REG_ARM_R5, + PERF_REG_ARM_R6, + PERF_REG_ARM_R7, + PERF_REG_ARM_R8, + PERF_REG_ARM_R9, + PERF_REG_ARM_R10, + PERF_REG_ARM_FP, + PERF_REG_ARM_IP, + PERF_REG_ARM_SP, + PERF_REG_ARM_LR, + PERF_REG_ARM_PC, + PERF_REG_ARM_MAX, +}; +#endif /* _ASM_ARM_PERF_REGS_H */ diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 5140df5f..9b818ca 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -78,6 +78,7 @@ obj-$(CONFIG_CPU_XSC3) += xscale-cp0.o obj-$(CONFIG_CPU_MOHAWK) += xscale-cp0.o obj-$(CONFIG_CPU_PJ4) += pj4-cp0.o obj-$(CONFIG_IWMMXT) += iwmmxt.o +obj-$(CONFIG_PERF_EVENTS) += perf_regs.o obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o perf_event_cpu.o AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt obj-$(CONFIG_ARM_CPU_TOPOLOGY) += topology.o diff --git a/arch/arm/kernel/perf_regs.c b/arch/arm/kernel/perf_regs.c new file mode 100644 index 0000000..6e4379c --- /dev/null +++ b/arch/arm/kernel/perf_regs.c @@ -0,0 +1,30 @@ + +#include <linux/errno.h> +#include <linux/kernel.h> +#include <linux/perf_event.h> +#include <linux/bug.h> +#include <asm/perf_regs.h> +#include <asm/ptrace.h> + +u64 perf_reg_value(struct pt_regs *regs, int idx) +{ + if (WARN_ON_ONCE((u32)idx >= PERF_REG_ARM_MAX)) + return 0; + + return regs->uregs[idx]; +} + +#define REG_RESERVED (~((1ULL << PERF_REG_ARM_MAX) - 1)) + +int perf_reg_validate(u64 mask) +{ + if (!mask || mask & REG_RESERVED) + return -EINVAL; + + return 0; +} + +u64 perf_reg_abi(struct task_struct *task) +{ + return PERF_SAMPLE_REGS_ABI_32; +} -- 1.7.11.7 ^ permalink raw reply related [flat|nested] 14+ messages in thread
end of thread, other threads:[~2013-10-08 14:31 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-09-26 11:36 [PATCH v3 0/4] perf: parse the dwarf backtrace info from .debug_frame section Jean Pihet 2013-09-26 11:36 ` [PATCH 1/4] ARM: perf: add support for perf registers API Jean Pihet 2013-09-26 11:36 ` [PATCH 2/4] ARM: perf: wire up perf_regs and unwind support for ARM Jean Pihet 2013-09-26 11:36 ` [PATCH 3/4] perf tools: Check libunwind for availability of dwarf parsing feature Jean Pihet 2013-09-26 12:48 ` Jiri Olsa 2013-10-08 10:44 ` Jean Pihet 2013-10-08 10:47 ` Peter Zijlstra 2013-10-08 14:15 ` Jean Pihet 2013-10-08 14:28 ` Arnaldo Carvalho de Melo 2013-10-08 14:31 ` Will Deacon 2013-09-26 11:36 ` [PATCH 4/4] perf: parse the .debug_frame section in case .eh_frame is not present Jean Pihet 2013-09-26 12:49 ` Jiri Olsa 2013-10-08 10:44 ` Jean Pihet -- strict thread matches above, loose matches on Subject: below -- 2013-09-16 9:17 [PATCH v2 0/4] perf: parse the dwarf backtrace info from .debug_frame section Jean Pihet 2013-09-16 9:17 ` [PATCH 1/4] ARM: perf: add support for perf registers API Jean Pihet
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).