Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933335AbcDER1K (ORCPT ); Tue, 5 Apr 2016 13:27:10 -0400 Received: from mail-db3on0056.outbound.protection.outlook.com ([157.55.234.56]:20608 "EHLO emea01-db3-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753274AbcDER1G (ORCPT ); Tue, 5 Apr 2016 13:27:06 -0400 Authentication-Results: spf=fail (sender IP is 12.216.194.146) smtp.mailfrom=ezchip.com; mellanox.com; dkim=none (message not signed) header.d=none;mellanox.com; dmarc=fail action=none header.from=mellanox.com; From: Chris Metcalf To: Peter Zijlstra , "Rafael J. Wysocki" , Petr Mladek , Russell King , Thomas Gleixner , Aaron Tomlin , Ingo Molnar , Andrew Morton , Daniel Thompson , , , CC: Chris Metcalf Subject: [PATCH v5 1/4] nmi_backtrace: add more trigger_*_cpu_backtrace() methods Date: Tue, 5 Apr 2016 13:26:45 -0400 Message-ID: <1459877208-15119-2-git-send-email-cmetcalf@mellanox.com> X-Mailer: git-send-email 2.7.2 In-Reply-To: <1459877208-15119-1-git-send-email-cmetcalf@mellanox.com> References: <1459877208-15119-1-git-send-email-cmetcalf@mellanox.com> X-EOPAttributedMessage: 0 X-Forefront-Antispam-Report: CIP:12.216.194.146;IPV:NLI;CTRY:US;EFV:NLI;SFV:NSPM;SFS:(10009020)(6009001)(2980300002)(1109001)(1110001)(339900001)(189002)(199003)(36756003)(50986999)(86362001)(1220700001)(2950100001)(48376002)(92566002)(4001430100002)(189998001)(50226001)(5001970100001)(76176999)(106466001)(6806005)(104016004)(1096002)(960300001)(105606002)(50466002)(107886002)(5008740100001)(19580405001)(33646002)(19580395003)(229853001)(42186005)(85426001)(87936001)(2201001)(4326007)(2906002)(11100500001)(5003940100001)(586003)(47776003)(575784001)(5001770100001)(921003)(2101003)(83996005)(1121003);DIR:OUT;SFP:1101;SCL:1;SRVR:DB5PR05MB1687;H:ld-1.internal.tilera.com;FPR:;SPF:Fail;MLV:sfv;MX:1;A:1;LANG:en; X-Microsoft-Exchange-Diagnostics: 1;DB3FFO11FD054;1:ACW1ImDOHBYDfTnVbVUV1w4Y9drVleExt0HbbXB4kFxtiWK0d2Lwt6Yl7Dr6FTlRD+tV0/RMq0K5EFZbTpETcOTVj+hHb1HHsH8whALBYLfvfNCoolTw/Tg+w95cVrVAFeVutK7HULNW/Blr8Ku7Ew+hjG6gCjEXeyKGCDkcdl5qQetPDBv+zInPACMesoB5KlBxe/SZ80zFgI8yaX7BPV8MB6ccbzXFxYSEYSpNkxuPIt/AGzVZHRh9wLfE96bbyhz8O8oOdQTDMlY5nrAiC1w5ERHVZr/suJAm3VZ+uy7JwFQ7QJL46QYxEyew7fvaHcilCe7OdSIkT4DS9ShTmsP5qoXLrDNOo+iuMopH1lzC3BcGq1NT0v8Hy6YqB+1PDnntZjh1mGfjlu0smBvqm23cQy98B+px0JU6kNmG4YKKBc6Qd6khf8juyefC3BfWTw1NIlnXBAhTNY1wOPByCsUtc0nzDSYNQi70sI0MLX7AfcU5Vg1jo1gY5dotPRJg88H2/mO+55xON1qL1V+N07I9vBu0k8/xBAe/ZYm0cv54ODCF+gt1G0HZj0rW1cJdgGKEq+j0BjllQ8i+fMYuOqCOc/YJuczPssVwaXduHPQvPrGJH35Dc90tuvxfojJO MIME-Version: 1.0 Content-Type: text/plain X-MS-Office365-Filtering-Correlation-Id: cf654f5b-21ca-4f07-dfed-08d35d777ef7 X-Microsoft-Exchange-Diagnostics: 1;DB5PR05MB1687;2:P1k//woK7+ib/KvqGqATGHqmreFPPEDo6017UyTiVPWXerPyKQe8Qzeiz0wtLpJlf/pdayYoncpDSmyQyhQ2xEsIhuq6E1AnYMdoh1SvDXTHlHrI6MkUnImdpz6pgjKywrXHZf+/O/I+0/yRQ3fR7J4kniNHtufV2vycK1sd5vCLqSQBbbyd3/2cAbLeIT8K;3:oVq3N+vMxPT15yZK9BkQJnRykQ7bAB65jVdupLQanPXb4Mqljflfa8eBVuo6swPYCx9u2sv5AvtJQeWLf00oOKcSQ+4nA7iU+a5OC+30fQeJ7ehis3DfxXCY79lcT/p3+v7oMCwC9ZuEjWrISRGtbMGZ9urQt03dP0QfcfZIwQIE7TCiUuL3l7Mlt4yk66oBaEi6dCPF5P2YGYF3s7phVJ06JzEGO0sCdyg2c/PLuFo=;25:8kKHKPoYxURXMNpA0NAt2ySKjfjR1DE4BSRmEJplgORdd7SWrw4HO4vn4dHEmBh/DTubkOBmSHu1aNu4tEnodysH+Vl+/YHf+pFOJXWgx2Sbcp89dBAPF1Cqrbpwwrx+B/7WM/UQoZ30a03O8CggoF8pOyKr52OP6HHoHGCEJM8hvWf8k6THeKa4I7AGHo757b1aAFHw9hspm133zi1x0jw/UwLejsrPP+Hh4+YQH5KckiqMpDigCNB52/3bmLRu3ocOnPaiAfAv8k2vciAUiQG62FQO9qn+KUNEYzGMDKsN/lC3c6ybF1ZCf8kvF1m+vfZ0LONiqbIUwNTK2NG6JNakoFBgkkTjfGgOqcqf4p4= X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:DB5PR05MB1687; X-Microsoft-Exchange-Diagnostics: 1;DB5PR05MB1687;20:qpaHUjckKvD7LCPehFMW9VHM7uw59KdCChHT8qpzevm5qnKGz2JrykrtAKfu26HBTg1CpgGyBi2zUlyuFqg0DLv2GAR0O2TYnpX0rdj1rjIMyqUM+34rgDOCj4INxQgC+XlhOU7a557TygRxpCTtWyBGCw8czWrk5FCpD8TIiuA1CkEWExTklwl5rRFuhygi8mOtqhSbsSrw+oepcMjiYEhpUqbB7jZXofAAxh168TwjUC8g6KV9UiEn//EDKe0ePxKmvm522ow2NEL+SutkjFpLaY82L6H/IL0IdkSVmyv0uKyH9h+9gxQHnTobVWMk5ggFr7DA1zK5Bs1/win8VCnzYdwzXVubq8wv33kjPK38WCNZPycK4rlu13dYumjcEFBL8MAeNp2o9B7pwbhXPhJePaAARkEV101yt00E1l99EcZPzLNevAbfJsM9gI6EKX9Q0kZiFDsC4fKqUGyUPDpytsV2FeNT2vXddpkkcy8P8ws3an+6wxZSBpSMBWSd X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(2401047)(13023025)(13018025)(13017025)(13015025)(13024025)(5005006)(8121501046)(3002001)(10201501046);SRVR:DB5PR05MB1687;BCL:0;PCL:0;RULEID:;SRVR:DB5PR05MB1687; X-Microsoft-Exchange-Diagnostics: 1;DB5PR05MB1687;4:FEzbGCje30VsZyw2UTbifxTz9YSj3w5APIvFBp5XY6gOYfAtxYcpVVXY7mtG1Itc1DSa0SFZioyNjExfCMpOtGRujElErB8DInWu+oMV38hwmtmHiEdLz93ZHsLjLJwJYNU2/ObQLG9yCAr1lojIKYy6PZrQccG5eILvOHewzc/3EED7tkNA4Wqwx0/MPY86vCJeqYSWXQL/P6gC0l6dshUtb7ds49z6fj/0zBpHV9PBhJsYme79yj0IDtvo96mmjKz90bDvzRu71ZtalL0CBlFtlov+OR9oNCCzo3KOE1BX1Xa3FGo9kSMGQycHx3/4yOajepubFDiovOOQMWm7o/oG1FEweAfPkKY9TOIko0vM7AdLlnfGHdKPHGeoVTMGQisOgOXiaoGUkLypRzPqBRYYd8z0pq01prakUPy1mLgEfmZUGEawvwsGKOvOQRf2Wgs19kQm3TSzXZADzdDd3w== X-Forefront-PRVS: 0903DD1D85 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;DB5PR05MB1687;23:gLnt1/s9SpnE79LYQRJP9f/7CcsmIKGcFbwQwb74W?= =?us-ascii?Q?4oIy4Rwm9DNiVrzyfa0S2GEdaj2rbrtFmhtApv7xPFFiovGOgO/u7+aFnl85?= =?us-ascii?Q?ljxh28gvV4hU0AjOP3cSN73yPpW8gsN52Ab9RhSaK9yp/z9BcdbuX5O5qt8f?= =?us-ascii?Q?7PTCLjvJJJo/sN6EVqDFw0tOYxVlXlcoRRV7Us9TSbCTZ18Ff9ECqkxCrsdu?= =?us-ascii?Q?EMp4eUOTL6LA6meCyce1LMxkzF3ykROxSXQ5UxRnI+RHnYHSPNsDGemBmYCj?= =?us-ascii?Q?x/wHDqQQxkFlRJZnEI/FVgsek302OV3UW5ojouSGCcZ5ONi+iwi9qPpCkvFK?= =?us-ascii?Q?zjrHrYThnQ+HxgDaDwSrrlPretx1F9qoKdlejPIEf3bXqM6vBGd+xivt67v9?= =?us-ascii?Q?o3m+ZNl5ccep8BKSWxx4j2jW3nmKBmTgO5zcm8hCxA6pT5s1V/NtZHSoIZp0?= =?us-ascii?Q?Z18aGBdGrxxeVgx3DjdnBGYm/krqN//FLRWRAFbtwndF/S81/WYjiYTE0pmg?= =?us-ascii?Q?k/6BXljJE85goVRwci4RVvLVK+EqQ8UeHJc+bac4YCiPQIZMR/TOBKw6ru6w?= =?us-ascii?Q?ndvgto08Vaz3lFGlcfMC4AHvFy4RZmYuVOLsSCJVj3NxroZ1GEEVyP9G0q2x?= =?us-ascii?Q?uw8WGAQZF5VP1TNqR1NeQk5vDu21PiBzA11p2d05yZ2W9wYCg/0SZd7xmcYK?= =?us-ascii?Q?7tQg6pDxnsJrJvVV8O5eLVlvp53ak+v/ues1ePsvwesVVszxGfAYSp4C294d?= =?us-ascii?Q?PxMSH6m5RZS5V7+fHbOaew5qzhjdPyOiX+L3u/JWeoOXMhXNF+6xn0EkGyV4?= =?us-ascii?Q?hGCzik0PvHxFjFK0tZ5R/Sq26E/xFL7emAGsNnAdiKKucO2tAw97JJ7Wxe01?= =?us-ascii?Q?P0/TWEug0E/4siH7b0vwL8KIXDsVpf6rOfckv4MyhEmZIhtVnMzZFW0+LTih?= =?us-ascii?Q?VcjHOH9zOfi1Q4xtXC/ieV2MUJAp1449iYk1040lShjCzNpaRRZSyuu0lsQU?= =?us-ascii?Q?18AIpf06UcDM7u1NDVrjmsGC1nJqp6UQSK/TZwBUnii8TSyxRfuGBKQrb//S?= =?us-ascii?Q?kX5rSQWatteZu3H+UsB7GjMWSL02LuDJGiiAvV8U5TpdKJrYVZ16vAKTzcNv?= =?us-ascii?Q?6kaqpBkhFu7w4Zt83iVfKf2IZN23VbmoUfBbIz6PJ90pLTfnT/BB9s9V51D+?= =?us-ascii?Q?fq5ksFQpkiCcLn6i2dEMZVtUMJYBoZecKM3wQlQjWriSjtCjMG/7pjpPGNJP?= =?us-ascii?Q?sNBq18kxsC9FpILt/U=3D?= X-Microsoft-Exchange-Diagnostics: 1;DB5PR05MB1687;5:ZdzlnbNmu+d/hGO7IcaybpqA8ZqW8tJf37MUzTXJGpVjOb/apV4Zvst+plOX9ODpBTMGAJ5kZSQsYslRMAQlfoHHqcEqF9xI7zz/Je42QRj89dXiduvvUIl6NGL+gYtfNmJgQwvMSBNcwXJBoW2tLg==;24:h+ebWp3UsNC5UbsyAneA4Qe169ot0wXwzI/6WjymyZsdLjLcLYoUWokW2OIEd0by0RgzgN1d2KYKYMbtkCW9pG8CkjrfNGvBR106K/iYvQg= X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Apr 2016 17:26:59.7825 (UTC) X-MS-Exchange-CrossTenant-Id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=a652971c-7d2e-4d9b-a6a4-d149256f461b;Ip=[12.216.194.146];Helo=[ld-1.internal.tilera.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB5PR05MB1687 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 7786 Lines: 236 Currently you can only request a backtrace of either all cpus, or all cpus but yourself. It can also be helpful to request a remote backtrace of a single cpu, and since we want that, the logical extension is to support a cpumask as the underlying primitive. This change modifies the existing lib/nmi_backtrace.c code to take a cpumask as its basic primitive, and modifies the linux/nmi.h code to use either the old "all/all_but_self" arch methods, or the new "cpumask" method, depending on which is available. The existing clients of nmi_backtrace (arm and x86) are converted to using the new cpumask approach in this change. Signed-off-by: Chris Metcalf --- arch/arm/include/asm/irq.h | 4 +-- arch/arm/kernel/smp.c | 4 +-- arch/x86/include/asm/irq.h | 4 +-- arch/x86/kernel/apic/hw_nmi.c | 6 ++--- include/linux/nmi.h | 63 ++++++++++++++++++++++++++++++++++--------- lib/nmi_backtrace.c | 15 +++++------ 6 files changed, 65 insertions(+), 31 deletions(-) diff --git a/arch/arm/include/asm/irq.h b/arch/arm/include/asm/irq.h index 1bd9510de1b9..13f9a9a17eca 100644 --- a/arch/arm/include/asm/irq.h +++ b/arch/arm/include/asm/irq.h @@ -36,8 +36,8 @@ extern void set_handle_irq(void (*handle_irq)(struct pt_regs *)); #endif #ifdef CONFIG_SMP -extern void arch_trigger_all_cpu_backtrace(bool); -#define arch_trigger_all_cpu_backtrace(x) arch_trigger_all_cpu_backtrace(x) +extern void arch_trigger_cpumask_backtrace(const cpumask_t *mask); +#define arch_trigger_cpumask_backtrace(x) arch_trigger_cpumask_backtrace(x) #endif static inline int nr_legacy_irqs(void) diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index baee70267f29..72ad8485993a 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -758,7 +758,7 @@ static void raise_nmi(cpumask_t *mask) smp_cross_call(mask, IPI_CPU_BACKTRACE); } -void arch_trigger_all_cpu_backtrace(bool include_self) +void arch_trigger_cpumask_backtrace(const cpumask_t *mask) { - nmi_trigger_all_cpu_backtrace(include_self, raise_nmi); + nmi_trigger_cpumask_backtrace(mask, raise_nmi); } diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h index e7de5c9a4fbd..18bdc8cc5c63 100644 --- a/arch/x86/include/asm/irq.h +++ b/arch/x86/include/asm/irq.h @@ -50,8 +50,8 @@ extern int vector_used_by_percpu_irq(unsigned int vector); extern void init_ISA_irqs(void); #ifdef CONFIG_X86_LOCAL_APIC -void arch_trigger_all_cpu_backtrace(bool); -#define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace +void arch_trigger_cpumask_backtrace(const struct cpumask *mask); +#define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace #endif #endif /* _ASM_X86_IRQ_H */ diff --git a/arch/x86/kernel/apic/hw_nmi.c b/arch/x86/kernel/apic/hw_nmi.c index 045e424fb368..63f0b69ad6a6 100644 --- a/arch/x86/kernel/apic/hw_nmi.c +++ b/arch/x86/kernel/apic/hw_nmi.c @@ -27,15 +27,15 @@ u64 hw_nmi_get_sample_period(int watchdog_thresh) } #endif -#ifdef arch_trigger_all_cpu_backtrace +#ifdef arch_trigger_cpumask_backtrace static void nmi_raise_cpu_backtrace(cpumask_t *mask) { apic->send_IPI_mask(mask, NMI_VECTOR); } -void arch_trigger_all_cpu_backtrace(bool include_self) +void arch_trigger_cpumask_backtrace(const cpumask_t *mask) { - nmi_trigger_all_cpu_backtrace(include_self, nmi_raise_cpu_backtrace); + nmi_trigger_cpumask_backtrace(mask, nmi_raise_cpu_backtrace); } static int diff --git a/include/linux/nmi.h b/include/linux/nmi.h index 4630eeae18e0..434208af10fc 100644 --- a/include/linux/nmi.h +++ b/include/linux/nmi.h @@ -31,38 +31,75 @@ static inline void hardlockup_detector_disable(void) {} #endif /* - * Create trigger_all_cpu_backtrace() out of the arch-provided - * base function. Return whether such support was available, + * Create trigger_all_cpu_backtrace() etc out of the arch-provided + * base function(s). Return whether such support was available, * to allow calling code to fall back to some other mechanism: */ -#ifdef arch_trigger_all_cpu_backtrace static inline bool trigger_all_cpu_backtrace(void) { +#if defined(arch_trigger_all_cpu_backtrace) arch_trigger_all_cpu_backtrace(true); - return true; +#elif defined(arch_trigger_cpumask_backtrace) + arch_trigger_cpumask_backtrace(cpu_online_mask); + return true; +#else + return false; +#endif } + static inline bool trigger_allbutself_cpu_backtrace(void) { +#if defined(arch_trigger_all_cpu_backtrace) arch_trigger_all_cpu_backtrace(false); return true; -} - -/* generic implementation */ -void nmi_trigger_all_cpu_backtrace(bool include_self, - void (*raise)(cpumask_t *mask)); -bool nmi_cpu_backtrace(struct pt_regs *regs); +#elif defined(arch_trigger_cpumask_backtrace) + cpumask_var_t mask; + int cpu = get_cpu(); + if (!alloc_cpumask_var(&mask, GFP_KERNEL)) + return false; + cpumask_copy(mask, cpu_online_mask); + cpumask_clear_cpu(cpu, mask); + arch_trigger_cpumask_backtrace(mask); + put_cpu(); + free_cpumask_var(mask); + return true; #else -static inline bool trigger_all_cpu_backtrace(void) -{ return false; +#endif } -static inline bool trigger_allbutself_cpu_backtrace(void) + +static inline bool trigger_cpumask_backtrace(struct cpumask *mask) { +#if defined(arch_trigger_cpumask_backtrace) + arch_trigger_cpumask_backtrace(mask); + return true; +#else return false; +#endif } + +static inline bool trigger_single_cpu_backtrace(int cpu) +{ +#if defined(arch_trigger_cpumask_backtrace) + cpumask_var_t mask; + + if (!zalloc_cpumask_var(&mask, GFP_KERNEL)) + return false; + cpumask_set_cpu(cpu, mask); + arch_trigger_cpumask_backtrace(mask); + free_cpumask_var(mask); + return true; +#else + return false; #endif +} + +/* generic implementation */ +void nmi_trigger_cpumask_backtrace(const cpumask_t *mask, + void (*raise)(cpumask_t *mask)); +bool nmi_cpu_backtrace(struct pt_regs *regs); #ifdef CONFIG_LOCKUP_DETECTOR u64 hw_nmi_get_sample_period(int watchdog_thresh); diff --git a/lib/nmi_backtrace.c b/lib/nmi_backtrace.c index 6019c53c669e..db63ac75eba0 100644 --- a/lib/nmi_backtrace.c +++ b/lib/nmi_backtrace.c @@ -18,7 +18,7 @@ #include #include -#ifdef arch_trigger_all_cpu_backtrace +#ifdef arch_trigger_cpumask_backtrace /* For reliability, we're prepared to waste bits here. */ static DECLARE_BITMAP(backtrace_mask, NR_CPUS) __read_mostly; static cpumask_t printtrace_mask; @@ -44,12 +44,12 @@ static void print_seq_line(struct nmi_seq_buf *s, int start, int end) } /* - * When raise() is called it will be is passed a pointer to the + * When raise() is called it will be passed a pointer to the * backtrace_mask. Architectures that call nmi_cpu_backtrace() * directly from their raise() functions may rely on the mask * they are passed being updated as a side effect of this call. */ -void nmi_trigger_all_cpu_backtrace(bool include_self, +void nmi_trigger_cpumask_backtrace(const cpumask_t *mask, void (*raise)(cpumask_t *mask)) { struct nmi_seq_buf *s; @@ -64,10 +64,7 @@ void nmi_trigger_all_cpu_backtrace(bool include_self, return; } - cpumask_copy(to_cpumask(backtrace_mask), cpu_online_mask); - if (!include_self) - cpumask_clear_cpu(this_cpu, to_cpumask(backtrace_mask)); - + cpumask_copy(to_cpumask(backtrace_mask), mask); cpumask_copy(&printtrace_mask, to_cpumask(backtrace_mask)); /* @@ -80,8 +77,8 @@ void nmi_trigger_all_cpu_backtrace(bool include_self, } if (!cpumask_empty(to_cpumask(backtrace_mask))) { - pr_info("Sending NMI to %s CPUs:\n", - (include_self ? "all" : "other")); + pr_info("Sending NMI from CPU %d to CPUs %*pbl:\n", + this_cpu, nr_cpumask_bits, to_cpumask(backtrace_mask)); raise(to_cpumask(backtrace_mask)); } -- 2.7.2