From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932354AbdERSUs convert rfc822-to-8bit (ORCPT ); Thu, 18 May 2017 14:20:48 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:59698 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1757211AbdERSUp (ORCPT ); Thu, 18 May 2017 14:20:45 -0400 Date: Thu, 18 May 2017 18:19:45 +0000 From: "Naveen N. Rao" Subject: Re: [PATCH] perf: libdw support for powerpc To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Paolo Bonzini Cc: acme@kernel.org, Ravi Bangoria , linuxppc-dev@lists.ozlabs.org References: <20170518170018.10507-1-pbonzini@redhat.com> In-Reply-To: <20170518170018.10507-1-pbonzini@redhat.com> User-Agent: astroid/0.9.1 (https://github.com/astroidmail/astroid) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8BIT X-TM-AS-MML: disable x-cbid: 17051818-0048-0000-0000-0000022EE73F X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17051818-0049-0000-0000-000047DD7918 Message-Id: <1495131092.c1jiws8vlt.astroid@naverao1-tp.none> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2017-05-18_04:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=0 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1703280000 definitions=main-1705180122 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Paolo Bonzini wrote: > The ARM and x86 architectures already use libdw, and it is useful to > have as much common code for the unwinder as possible. Porting PPC > to libdw only needs an architecture-specific hook to move the register > state from perf to libdw. Thanks. Ravi has had a similar patch locally, but from what I understand, there are issues with libdw based unwinding on powerpc64. I gave this a quick test and I don't see the user-space call trace being unwinded properly with libdw. With the same perf.data, with libunwind: bswap 19286 134866.199717: 321955 cycles: c0000000000b5e60 [unknown] ([unknown]) b31bc pSeries_lpar_hpte_invalidate (/boot/vmlinux) 76f10 flush_hash_page (/boot/vmlinux) 7ddec hpte_need_flush (/boot/vmlinux) 2d9f64 ptep_clear_flush (/boot/vmlinux) 2c24dc wp_page_copy (/boot/vmlinux) 2c5c44 do_wp_page (/boot/vmlinux) 2cabcc __handle_mm_fault (/boot/vmlinux) 2cbbe8 handle_mm_fault (/boot/vmlinux) 71074 do_page_fault (/boot/vmlinux) 1b078 handle_page_fault (/boot/vmlinux) 9958 _dl_map_object_from_fd (/lib/powerpc64le-linux-gnu/ld-2.24.so) e70c _dl_map_object (/lib/powerpc64le-linux-gnu/ld-2.24.so) 18da4 openaux (/lib/powerpc64le-linux-gnu/ld-2.24.so) 1c068 _dl_catch_error (/lib/powerpc64le-linux-gnu/ld-2.24.so) 19430 _dl_map_object_deps (/lib/powerpc64le-linux-gnu/ld-2.24.so) 41dc dl_main (/lib/powerpc64le-linux-gnu/ld-2.24.so) 29954 _dl_sysdep_start (/lib/powerpc64le-linux-gnu/ld-2.24.so) 1be0 _dl_start_final (/lib/powerpc64le-linux-gnu/ld-2.24.so) 6080 _dl_start (/lib/powerpc64le-linux-gnu/ld-2.24.so) 1398 _start (/lib/powerpc64le-linux-gnu/ld-2.24.so) ... and with libdw: bswap 19286 134866.199717: 321955 cycles: c0000000000b5e60 [unknown] ([unknown]) b31bc pSeries_lpar_hpte_invalidate (/boot/vmlinux) 76f10 flush_hash_page (/boot/vmlinux) 7ddec hpte_need_flush (/boot/vmlinux) 2d9f64 ptep_clear_flush (/boot/vmlinux) 2c24dc wp_page_copy (/boot/vmlinux) 2c5c44 do_wp_page (/boot/vmlinux) 2cabcc __handle_mm_fault (/boot/vmlinux) 2cbbe8 handle_mm_fault (/boot/vmlinux) 71074 do_page_fault (/boot/vmlinux) 1b078 handle_page_fault (/boot/vmlinux) Ravi is OOO currently can will have more to say on this once he is back next week. > > Signed-off-by: Paolo Bonzini > --- > tools/perf/Makefile.config | 2 +- > tools/perf/arch/powerpc/util/Build | 2 + > tools/perf/arch/powerpc/util/unwind-libdw.c | 73 +++++++++++++++++++++++++++++ > 3 files changed, 76 insertions(+), 1 deletion(-) > create mode 100644 tools/perf/arch/powerpc/util/unwind-libdw.c > > diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config > index f67ae83..342c57c 100644 > --- a/tools/perf/Makefile.config > +++ b/tools/perf/Makefile.config > @@ -61,7 +61,7 @@ endif > # Disable it on all other architectures in case libdw unwind > # support is detected in system. Add supported architectures > # to the check. > -ifneq ($(ARCH),$(filter $(ARCH),x86 arm)) > +ifneq ($(ARCH),$(filter $(ARCH),x86 arm powerpc)) > NO_LIBDW_DWARF_UNWIND := 1 > endif > > diff --git a/tools/perf/arch/powerpc/util/Build b/tools/perf/arch/powerpc/util/Build > index 90ad64b..2e65953 100644 > --- a/tools/perf/arch/powerpc/util/Build > +++ b/tools/perf/arch/powerpc/util/Build > @@ -5,4 +5,6 @@ libperf-y += perf_regs.o > > libperf-$(CONFIG_DWARF) += dwarf-regs.o > libperf-$(CONFIG_DWARF) += skip-callchain-idx.o > + > libperf-$(CONFIG_LIBUNWIND) += unwind-libunwind.o > +libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o > diff --git a/tools/perf/arch/powerpc/util/unwind-libdw.c b/tools/perf/arch/powerpc/util/unwind-libdw.c > new file mode 100644 > index 0000000..c61e1d8 > --- /dev/null > +++ b/tools/perf/arch/powerpc/util/unwind-libdw.c > @@ -0,0 +1,73 @@ > +#include > +#include "../../util/util.h" > +#include "../../util/unwind-libdw.h" > +#include "../../util/perf_regs.h" As an aside, we also need to include "event.h", without which there are a few compile errors. - Naveen > + > +/* See backends/ppc_initreg.c and backends/ppc_regs.c in elfutils. */ > +static const int special_regs[3][2] = { > + { 65, PERF_REG_POWERPC_LINK }, > + { 101, PERF_REG_POWERPC_XER }, > + { 109, PERF_REG_POWERPC_CTR }, > +}; > + > +bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg) > +{ > + struct unwind_info *ui = arg; > + struct regs_dump *user_regs = &ui->sample->user_regs; > + Dwarf_Word dwarf_regs[32], dwarf_nip; > + size_t i; > + > +#define REG(r) ({ \ > + Dwarf_Word val = 0; \ > + perf_reg_value(&val, user_regs, PERF_REG_POWERPC_##r); \ > + val; \ > +}) > + > + dwarf_regs[0] = REG(R0); > + dwarf_regs[1] = REG(R1); > + dwarf_regs[2] = REG(R2); > + dwarf_regs[3] = REG(R3); > + dwarf_regs[4] = REG(R4); > + dwarf_regs[5] = REG(R5); > + dwarf_regs[6] = REG(R6); > + dwarf_regs[7] = REG(R7); > + dwarf_regs[8] = REG(R8); > + dwarf_regs[9] = REG(R9); > + dwarf_regs[10] = REG(R10); > + dwarf_regs[11] = REG(R11); > + dwarf_regs[12] = REG(R12); > + dwarf_regs[13] = REG(R13); > + dwarf_regs[14] = REG(R14); > + dwarf_regs[15] = REG(R15); > + dwarf_regs[16] = REG(R16); > + dwarf_regs[17] = REG(R17); > + dwarf_regs[18] = REG(R18); > + dwarf_regs[19] = REG(R19); > + dwarf_regs[20] = REG(R20); > + dwarf_regs[21] = REG(R21); > + dwarf_regs[22] = REG(R22); > + dwarf_regs[23] = REG(R23); > + dwarf_regs[24] = REG(R24); > + dwarf_regs[25] = REG(R25); > + dwarf_regs[26] = REG(R26); > + dwarf_regs[27] = REG(R27); > + dwarf_regs[28] = REG(R28); > + dwarf_regs[29] = REG(R29); > + dwarf_regs[30] = REG(R30); > + dwarf_regs[31] = REG(R31); > + if (!dwfl_thread_state_registers(thread, 0, 32, dwarf_regs)) > + return false; > + > + dwarf_nip = REG(NIP); > + dwfl_thread_state_register_pc(thread, dwarf_nip); > + for (i = 0; i < ARRAY_SIZE(special_regs); i++) { > + Dwarf_Word val = 0; > + perf_reg_value(&val, user_regs, special_regs[i][1]); > + if (!dwfl_thread_state_registers(thread, > + special_regs[i][0], 1, > + &val)) > + return false; > + } > + > + return true; > +} > -- > 1.8.3.1 > > >