Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753319AbcCGRin (ORCPT ); Mon, 7 Mar 2016 12:38:43 -0500 Received: from mail-db3on0091.outbound.protection.outlook.com ([157.55.234.91]:43744 "EHLO emea01-db3-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752427AbcCGRif (ORCPT ); Mon, 7 Mar 2016 12:38:35 -0500 Authentication-Results: linaro.org; dkim=none (message not signed) header.d=none;linaro.org; dmarc=none action=none header.from=mellanox.com; Subject: Re: [PATCH 2/4] nmi_backtrace: generate one-line reports for idle cpus To: Peter Zijlstra , Daniel Thompson References: <1456782024-7122-1-git-send-email-cmetcalf@ezchip.com> <1456782024-7122-3-git-send-email-cmetcalf@ezchip.com> <56D5A5E6.9050206@linaro.org> <56D5BCE6.3010300@mellanox.com> <20160307094852.GA6356@twins.programming.kicks-ass.net> CC: Russell King , Thomas Gleixner , Ingo Molnar , Andrew Morton , , Aaron Tomlin , "Rafael J. Wysocki" , Daniel Lezcano From: Chris Metcalf Message-ID: <56DDBC88.9060308@mellanox.com> Date: Mon, 7 Mar 2016 12:38:16 -0500 User-Agent: Mozilla/5.0 (X11; Linux i686 on x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.6.0 MIME-Version: 1.0 In-Reply-To: <20160307094852.GA6356@twins.programming.kicks-ass.net> Content-Type: text/plain; charset="windows-1252"; format=flowed Content-Transfer-Encoding: 7bit X-Originating-IP: [12.216.194.146] X-ClientProxiedBy: BN3PR16CA0046.namprd16.prod.outlook.com (25.165.72.142) To HE1PR05MB1689.eurprd05.prod.outlook.com (25.169.119.155) X-MS-Office365-Filtering-Correlation-Id: d2fc63c0-3034-49be-7fc9-08d346af4be6 X-Microsoft-Exchange-Diagnostics: 1;HE1PR05MB1689;2:ERlY00uxG4Jt0j4hZK12YbGx5Z+7Z9rz9Ijy2mHpQN62aSkmlaGICmF5pRDl3BgQl1WffEbnuI1GmqNict2K3WLZAIeL5gyJJd367vJiAn12DrUUEuHczljPu9JmSy0KVeSLhV9VK+A/SSldJtp1VUHwxJ/NANr31a6+MqvtqNr0rjbS2PntCQicYQG9r2ge;3:NbrlhGIYNCgFOxqziJHUeNqMjLQotMruKv//X7mPsE5UV9EQDokvBYNbd7neTwxiW1kVSRTlkHSNRNJ7+m+PqJgYR8nOppjvSo7dVA42RrnQYnBOjMrupFAWq+jdJchj;25:o89n1pTHEIgOwIRhn9FpfB9m9k0JB0yR+xFWi3+L7e9U0pqYW2K/J4/rQ2eMfGwCWNpsd2L80w+GITbbtu+apcjfT55Y1BDXkRhAwABeFHP3ssgG9BigovyxkyzpxtnsVMiOppdLuMQnaw4TwFaxoxsTS0B+kh6CnQ47VnRu2uIjT2lczhWGdjifQ7djRwK+XaklVDd7Nk+Psm6p+jHssetdP6z9GQsBs3uATsC0fMkaYJo7OglgyeW/Nrf+4R69eLtk7xy6dp6motAOxm3xJVBkuqbBI/X5ic+uV3rRRrUZC8JGEemfIbYfoxzRrcD4Dag8x1iFKNkNVYcsZB5oWA== X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:HE1PR05MB1689; X-MLNXRule-EZCH-Linux: Rule triggered X-Microsoft-Exchange-Diagnostics: 1;HE1PR05MB1689;20:4UlZskM6P9Flcov1YKUkxOdQiYfhPzWlUfBw4u3NGckHdtWSRiCWe8vANRDyvSK7hdE+w96TIqATRZjgTRyenSiG3kEVqjMugaZeIkPqLQjvwJc7i79uHELVe7PM48rP2x1z7Wfgt3+uute9WZA4xTlUsP8P9682y3c9H8MVbWmJ8gvr14enoD3QHuoNkuz/EUhlkQleft8gZx0oxaBS7eX973Jm4gXfT97/4pcvZw3x84rhr+EpmvfBj49b1fSLNDoANCI5qFouDKwa32VtQp1sSA1lXEca+82IeGcUKvTKNAgMh+I1OvHWW1p+54dCM6nL2KevGXQX9Ayr6Lr6DU6xoUIVZ/NWjKfRPYGi566CberefPFgIuT8IVU32V4HTnUjHu1tsscy3PJ+0m3dVm6mZUgXlqfCD4sLH4Vu08XCZJTjkQcNhJkGeWdPYT8/ovyWCC+O5B6tZ5GyEjG+OGxOqJo4zVyWlQl+wLxn4n97yGGxm4nK2DRwOofZanjH;4:ebtVYwIJG0pFmL4mSDwldlz85thmQ72bzwE4xlXcJRIP2/+zD6S1cM6RVxh8x5j5eKrVq6OlCmNtGB+AZKfWxMCaKyE37EHIdvWwFUDD88CzD24iBaEVQ2BfknPalxm09Yj4Iiuqp2pUhXOLVQGCK0wb5M0w/Fwv2e4sfIHbhPEbUcmTESi2laFXqurXiQ25aXPpRY7b61xQgbNWyKhwPPYWMsN6wxS+Iy9x20U0ak+M5CcahLof8Ozt68bYICaxSAhp+sSYJlIo1V0jHOHTOwi1t6QokA1rFrH9d30g9gln90hiCzxwXBnf02xjyvVjxbNlc7YQ+LNYs9FDYThnDk2KsKiPyaS9AaQd4p1RBocogIkHZgURkv15U53fXFuT X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(2401047)(5005006)(8121501046)(10201501046)(3002001);SRVR:HE1PR05MB1689;BCL:0;PCL:0;RULEID:;SRVR:HE1PR05MB1689; X-Forefront-PRVS: 087474FBFA X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(4630300001)(6049001)(6009001)(479174004)(76104003)(377454003)(24454002)(42186005)(6116002)(4326007)(1096002)(3846002)(59896002)(2906002)(230700001)(2950100001)(15975445007)(122386002)(36756003)(189998001)(586003)(77096005)(40100003)(5004730100002)(92566002)(23746002)(80316001)(4001350100001)(65806001)(76176999)(87266999)(65816999)(50986999)(54356999)(5001770100001)(50466002)(66066001)(65956001)(19580395003)(33656002)(93886004)(47776003)(87976001)(86362001)(5008740100001)(83506001)(81166005)(18886065003);DIR:OUT;SFP:1101;SCL:1;SRVR:HE1PR05MB1689;H:[10.15.7.41];FPR:;SPF:None;MLV:sfv;LANG:en; X-Microsoft-Exchange-Diagnostics: =?Windows-1252?Q?1;HE1PR05MB1689;23:l+nTalcke8IUwqIXvuJK5TmVl8+ordxx4E/FJ?= =?Windows-1252?Q?dHGzWnudzCFGDiwaKlQleYZNpOgOptTh1EyDgDSAwLYzqUB5G8i8KM8P?= =?Windows-1252?Q?xfuSVCCllW0FpQupvkT9VfJdubQGVXHZWTPN0L/VRafq+Qbhp9D6N0mF?= =?Windows-1252?Q?lANFb9XArfAP7dO0DTRIFsejjmh7G9Eky6hHO8Ccclql8ggl5wskye5R?= =?Windows-1252?Q?CROuJLSyJB4q5uk38i49lDXDeUuhO5fg56llQGwnrC3GEzzIglQsdXCu?= =?Windows-1252?Q?t2NgFwvwulTyWtDDHefU4XY1v3Tp2Qxu4yUHJV9BOqfWAi+oQljawnSJ?= =?Windows-1252?Q?s8uNv0gCNquDq3Fwc9mLeJ1w4JSPE9FboKStrIbU8WaS9BJAazNcs2IY?= =?Windows-1252?Q?ht4Fy9iF5afIy4h6yle6g2sa4xNSk7w8WvcTrip7SKekS/rtsqbFLueC?= =?Windows-1252?Q?mF8SKBsdm3M4LKcQPJ9htSvctWMmUSsgwDEu5EUWnvDrxFx69AA8NNv9?= =?Windows-1252?Q?MEqs+y2tQFefay+MvDJyA8OIMUlqI7hRtLPxuKOoeVVDPoav2fF7Jhu6?= =?Windows-1252?Q?wPqM0KmbVU6x5FbzgfbMdKZfMyPFWNkvsJmam4AptktddoBLbeBCnQr9?= =?Windows-1252?Q?IyecKCmmsarAZy13oMLbj6NyK2DPCuL7VQaJ5EgAZYLYeMYAR7O+oV5/?= =?Windows-1252?Q?vg7OcPfEyTmFWBWDh3iQDjlvfguBUy00UXlegkReEbHKaISWIy5Hszoc?= =?Windows-1252?Q?9cRa+SntFz2fqOH/pLoMGqCZuG4eLP/HCTV7U9jCkehUiyDXUYNGG1P2?= =?Windows-1252?Q?ift1zktQWPpoecH+wQaZhtbsZIFC20b9z4Bi4SgOSycjZ2/33hHezzUs?= =?Windows-1252?Q?DJXpXgBPhKY9B4BonW03FVZdQtI+wyRnNjnadzt2YqQk9ZrEE4Ro5tiT?= =?Windows-1252?Q?5PAXHD7rotHRkLERWI9Jj5t5xYqha1GaQHdltjncCCvPTyBUa0rgojaX?= =?Windows-1252?Q?ZkAwvr9Q9yxLqdUGPRkg4Fwzd5BqMw/o5NLKoq28I27inNTZsQH8TBtI?= =?Windows-1252?Q?dkSvjUmbAUeFPSTIoWVCffY2iWd3QOg2rF7nv7SjU15/lraBGqTJkRr+?= =?Windows-1252?Q?pCvBh3OGjBCVHIzA/NfDymmAKB8QBAdROdTpX/x5Zhr6Es2WMJUUIIwR?= =?Windows-1252?Q?m5t2D2vv+vprS1vZalP+c3ggPCHKBT7qF4c9cX2kwmaIuViU1gEuWpGy?= =?Windows-1252?Q?eISZ9o+FHXkvojE/waRjwyBS0E/7ErMAxyICOi1imOUXHS9clJlhPgki?= =?Windows-1252?Q?5c599vdy197E6QMQWYpwvmO1p/T5D02bBFKx5Q4OfplQh4=3D?= X-Microsoft-Exchange-Diagnostics: 1;HE1PR05MB1689;5:a0F+jRC1W7TGVxf8NiDMRkvtAMuIr/LM+nqYKb/6zzn2qeM+O0ZkLVYMpRtMGoPZc0Ek+dYvJ33kuxSs8l3oRYhs+x1NSXVAF0NDGydh9Hs9DMGn3xwYGAiQksgrvk5UnJhyzN+wmbjtM72cAhxiIA==;24:j0N9KgRz72R0GaZNO7EdfEMMnBl6gptBKnjJrY7FEq8OE9/i0C2dzPjLZArxOe3Ut3n/E4aOt1qivVO5WG6PKyb4Zfj2DXfRje9hwTL+qY4= SpamDiagnosticOutput: 1:23 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Mar 2016 17:38:27.9114 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: HE1PR05MB1689 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 6238 Lines: 174 On 03/07/2016 04:48 AM, Peter Zijlstra wrote: > On Tue, Mar 01, 2016 at 11:01:42AM -0500, Chris Metcalf wrote: >> +++ b/kernel/sched/idle.c >> @@ -52,15 +52,25 @@ static int __init cpu_idle_nopoll_setup(char *__unused) >> __setup("hlt", cpu_idle_nopoll_setup); >> #endif >> +static DEFINE_PER_CPU(bool, cpu_idling); >> + >> +/* Was the cpu was in the low-level idle code when interrupted? */ >> +bool in_cpu_idle(void) >> +{ >> + return this_cpu_read(cpu_idling); >> +} >> + >> static inline int cpu_idle_poll(void) >> { >> rcu_idle_enter(); >> trace_cpu_idle_rcuidle(0, smp_processor_id()); >> local_irq_enable(); >> stop_critical_timings(); >> + this_cpu_write(cpu_idling, true); >> while (!tif_need_resched() && >> (cpu_idle_force_poll || tick_check_broadcast_expired())) >> cpu_relax(); >> + this_cpu_write(cpu_idling, false); >> start_critical_timings(); >> trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id()); >> rcu_idle_exit(); >> @@ -89,7 +99,9 @@ void default_idle_call(void) >> local_irq_enable(); >> } else { >> stop_critical_timings(); >> + this_cpu_write(cpu_idling, true); >> arch_cpu_idle(); >> + this_cpu_write(cpu_idling, false); >> start_critical_timings(); >> } >> } > No, we're not going to add random crap here. This is actually considered > a fast path for some workloads. > > There's already far too much fat in the whole going to idle and coming > out of idle. We should be trimming this, not adding to it. I'm a little skeptical that a single percpu write is going to add much measurable overhead to this path. However, we can certainly adapt alternate approaches that stay away from the actual idle code. One approach (diff appended) is to just test to see if the PC is actually in the architecture-specific halt code. There are two downsides: 1. It requires a small amount of per-architecture support. I've provided the tile support as an example, since that's what I tested. I expect x86 is a little more complicated since there are more idle paths and they don't currently run the idle instruction(s) at a fixed address, but it's unlikely to be too complicated on any platform. Still, adding anything per-architecture is certainly a downside. 2. As proposed, my new alternate solution only handles the non-polling case, so if you are in the polling loop, we won't benefit from having the NMI backtrace code skip over you. However my guess is that 99% of the time folks do choose to run the default non-polling mode, so this probably still achieves a pretty reasonable outcome. A different approach that would handle downside #2 and probably make it easier to implement the architecture-specific code for more complicated platforms like x86 would be to use the SCHED_TEXT model and tag all the low-level idling functions as CPUIDLE_TEXT. Then the "are we idling" test is just a range compare on the PC against __cpuidle_text_{start,end}. We'd have to decide whether to make cpu_idle_poll() non-inline and just test for being in that function, or whether we could tag all of cpu_idle_loop() as being CPUIDLE_TEXT and just omit any backtrace whenever the PC is anywhere in that function. Obviously if we have called out to more complicated code (e.g. Daniel's concern about calling out to power management code) the PC would no longer be in the CPUIDLE_TEXT at that point, so that might be OK too. Let me know what you think is the right direction here. Thanks! diff --git a/arch/tile/include/asm/thread_info.h b/arch/tile/include/asm/thread_info.h index 4b7cef9e94e0..93ec51a4853b 100644 --- a/arch/tile/include/asm/thread_info.h +++ b/arch/tile/include/asm/thread_info.h @@ -92,6 +92,9 @@ extern void smp_nap(void); /* Enable interrupts racelessly and nap forever: helper for arch_cpu_idle(). */ extern void _cpu_idle(void); +/* The address of the actual nap instruction. */ +extern long _cpu_idle_nap[]; + #else /* __ASSEMBLY__ */ /* diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c index b5f30d376ce1..a83a426f1755 100644 --- a/arch/tile/kernel/process.c +++ b/arch/tile/kernel/process.c @@ -70,6 +70,11 @@ void arch_cpu_idle(void) _cpu_idle(); } +bool arch_cpu_in_idle(struct pt_regs *regs) +{ + return regs->pc == (unsigned long)_cpu_idle_nap; +} + /* * Release a thread_info structure */ diff --git a/include/linux/cpu.h b/include/linux/cpu.h index d2ca8c38f9c4..24462927fa49 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -279,6 +279,7 @@ void arch_cpu_idle_prepare(void); void arch_cpu_idle_enter(void); void arch_cpu_idle_exit(void); void arch_cpu_idle_dead(void); +bool arch_cpu_in_idle(struct pt_regs *); DECLARE_PER_CPU(bool, cpu_dead_idle); diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c index 544a7133cbd1..d9dbab6526a9 100644 --- a/kernel/sched/idle.c +++ b/kernel/sched/idle.c @@ -77,6 +77,7 @@ void __weak arch_cpu_idle(void) cpu_idle_force_poll = 1; local_irq_enable(); } +bool __weak arch_cpu_in_idle(struct pt_regs *regs) { return false; } /** * default_idle_call - Default CPU idle routine. diff --git a/lib/nmi_backtrace.c b/lib/nmi_backtrace.c index db63ac75eba0..bcc4ecc828f2 100644 --- a/lib/nmi_backtrace.c +++ b/lib/nmi_backtrace.c @@ -17,6 +17,7 @@ #include #include #include +#include #ifdef arch_trigger_cpumask_backtrace /* For reliability, we're prepared to waste bits here. */ @@ -151,11 +152,16 @@ bool nmi_cpu_backtrace(struct pt_regs *regs) /* Replace printk to write into the NMI seq */ this_cpu_write(printk_func, nmi_vprintk); - pr_warn("NMI backtrace for cpu %d\n", cpu); - if (regs) - show_regs(regs); - else - dump_stack(); + if (regs != NULL && arch_cpu_in_idle(regs)) { + pr_warn("NMI backtrace for cpu %d skipped: idle\n", + cpu); + } else { + pr_warn("NMI backtrace for cpu %d\n", cpu); + if (regs) + show_regs(regs); + else + dump_stack(); + } this_cpu_write(printk_func, printk_func_save); cpumask_clear_cpu(cpu, to_cpumask(backtrace_mask)); -- Chris Metcalf, Mellanox Technologies http://www.mellanox.com