Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755217AbcCBByJ (ORCPT ); Tue, 1 Mar 2016 20:54:09 -0500 Received: from mail333.us4.mandrillapp.com ([205.201.137.77]:44579 "EHLO mail333.us4.mandrillapp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754802AbcCAXx3 (ORCPT ); Tue, 1 Mar 2016 18:53:29 -0500 DomainKey-Signature: a=rsa-sha1; c=nofws; q=dns; s=mandrill; d=linuxfoundation.org; b=PdeM1kphtQ3byujW7fPHldq/x954kDzsgDSDvgmgd2KRb1A1PmjR6EWScWrJiHa1Qh5cPnsa3QdB 7diZnxfZXeGDzkmhXnqgnIEatwcnFmNDtz2aZbILDmDz7ghjfdeZFN1Y4Nd0lKuuNAUeZ4S/lhoW y4wY9BeQlMJNVk2c4QQ=; From: Greg Kroah-Hartman Subject: [PATCH 3.14 064/130] ARC: dw2 unwind: Remove falllback linear search thru FDE entries X-Mailer: git-send-email 2.7.2 To: Cc: Greg Kroah-Hartman , , Vineet Gupta Message-Id: <20160301234502.075947405@linuxfoundation.org> In-Reply-To: <20160301234459.768886030@linuxfoundation.org> References: <20160301234459.768886030@linuxfoundation.org> X-Report-Abuse: Please forward a copy of this message, including all headers, to abuse@mandrill.com X-Report-Abuse: You can also report abuse here: http://mandrillapp.com/contact/abuse?id=30481620.e9dba21b137b4d1fa5a46ff70e3e5a28 X-Mandrill-User: md_30481620 Date: Tue, 01 Mar 2016 23:53:27 +0000 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3141 Lines: 93 3.14-stable review patch. If anyone has any objections, please let me know. ------------------ From: Vineet Gupta commit 2e22502c080f27afeab5e6f11e618fb7bc7aea53 upstream. Fixes STAR 9000953410: "perf callgraph profiling causing RCU stalls" | perf record -g -c 15000 -e cycles /sbin/hackbench | | INFO: rcu_preempt self-detected stall on CPU | 1: (1 GPs behind) idle=609/140000000000002/0 softirq=2914/2915 fqs=603 | Task dump for CPU 1: in-kernel dwarf unwinder has a fast binary lookup and a fallback linear search (which iterates thru each of ~11K entries) thus takes 2 orders of magnitude longer (~3 million cycles vs. 2000). Routines written in hand assembler lack dwarf info (as we don't support assembler CFI pseudo-ops yet) fail the unwinder binary lookup, hit linear search, failing nevertheless in the end. However the linear search is pointless as binary lookup tables are created from it in first place. It is impossible to have binary lookup fail while succeed the linear search. It is pure waste of cycles thus removed by this patch. This manifested as RCU stalls / NMI watchdog splat when running hackbench under perf with callgraph profiling. The triggering condition was perf counter overflowing in routine lacking dwarf info (like memset) leading to patheic 3 million cycle unwinder slow path and by the time it returned new interrupts were already pending (Timer, IPI) and taken rightaway. The original memset didn't make forward progress, system kept accruing more interrupts and more unwinder delayes in a vicious feedback loop, ultimately triggering the NMI diagnostic. Signed-off-by: Vineet Gupta Signed-off-by: Greg Kroah-Hartman --- arch/arc/kernel/unwind.c | 37 ++++--------------------------------- 1 file changed, 4 insertions(+), 33 deletions(-) --- a/arch/arc/kernel/unwind.c +++ b/arch/arc/kernel/unwind.c @@ -986,42 +986,13 @@ int arc_unwind(struct unwind_frame_info (const u8 *)(fde + 1) + *fde, ptrType); - if (pc >= endLoc) + if (pc >= endLoc) { fde = NULL; - } else - fde = NULL; - } - if (fde == NULL) { - for (fde = table->address, tableSize = table->size; - cie = NULL, tableSize > sizeof(*fde) - && tableSize - sizeof(*fde) >= *fde; - tableSize -= sizeof(*fde) + *fde, - fde += 1 + *fde / sizeof(*fde)) { - cie = cie_for_fde(fde, table); - if (cie == &bad_cie) { cie = NULL; - break; } - if (cie == NULL - || cie == ¬_fde - || (ptrType = fde_pointer_type(cie)) < 0) - continue; - ptr = (const u8 *)(fde + 2); - startLoc = read_pointer(&ptr, - (const u8 *)(fde + 1) + - *fde, ptrType); - if (!startLoc) - continue; - if (!(ptrType & DW_EH_PE_indirect)) - ptrType &= - DW_EH_PE_FORM | DW_EH_PE_signed; - endLoc = - startLoc + read_pointer(&ptr, - (const u8 *)(fde + - 1) + - *fde, ptrType); - if (pc >= startLoc && pc < endLoc) - break; + } else { + fde = NULL; + cie = NULL; } } }