Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932925AbcC3RRd (ORCPT ); Wed, 30 Mar 2016 13:17:33 -0400 Received: from mail-db3on0091.outbound.protection.outlook.com ([157.55.234.91]:6752 "EHLO emea01-db3-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753977AbcC3RQi (ORCPT ); Wed, 30 Mar 2016 13:16:38 -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 v4 1/4] nmi_backtrace: add more trigger_*_cpu_backtrace() methods Date: Wed, 30 Mar 2016 13:16:07 -0400 Message-ID: <1459358170-27745-2-git-send-email-cmetcalf@mellanox.com> X-Mailer: git-send-email 2.7.2 In-Reply-To: <1459358170-27745-1-git-send-email-cmetcalf@mellanox.com> References: <1459358170-27745-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)(339900001)(199003)(189002)(6806005)(50226001)(19580395003)(4001430100002)(19580405001)(104016004)(33646002)(5001970100001)(107886002)(50466002)(87936001)(189998001)(4326007)(5008740100001)(5001770100001)(575784001)(1220700001)(5003940100001)(1096002)(2201001)(92566002)(2950100001)(86362001)(586003)(48376002)(47776003)(50986999)(36756003)(85426001)(229853001)(2906002)(105606002)(42186005)(106466001)(11100500001)(76176999)(921003)(2101003)(83996005)(1121003);DIR:OUT;SFP:1101;SCL:1;SRVR:AM4PR05MB1682;H:ld-1.internal.tilera.com;FPR:;SPF:Fail;MLV:sfv;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: 1;AM1FFO11OLC008;1:j0t6lrQepVWUWRfBuKEKw719RZfGaWkTbu1WHedzFdeJmS4dWoAbScGBQs8X2eKGuZw4dDTOzmixa2261x8Z9xS5QxR1zq5YSDX/ILRaa19YLHNsyJ4rhRBAXLCuju8X7pX42wVc9l5hGeGmKoa8kW80NR6C4M2Uk/dtM7j0zu6tmkd0C2/RVwn50N8BrE1lpvGYC/6KVx3IQ2pkWLQ2AOh//fG90Pb8cRqPCBfkTf2RCB1DiGBxDqUp889lisyayNzRlypThvPV9UAylOLxjwo+Z7mgRTqVupgK93o97iOqZhZOJUuy59udFK1nUQL0nB8C9SOe9Iol1vdRBHB9NPtSxEzSSDP98/eA9W6txSVx8sS/eS3I8nljg4utr/NH3VRs26tNNkP/jeulWC4rDkz5MKk8YEdTuQqS72hWBcXsJ6Os14GJU9lI8IcZOgaIAP4ze+cEQPjz6YIg7lrGJB9E6/EHJAS0gxPdHkDlbL2dssyiyqQw9ZGiKuxJvTDmh2nxenkqwlxj4CUlPDIj019C96q9sgMgNWZys1VAGAXKPSA89LPREGcvBHvIWw1o MIME-Version: 1.0 Content-Type: text/plain X-MS-Office365-Filtering-Correlation-Id: 4e3e8693-2d25-48eb-0a4b-08d358bf0837 X-Microsoft-Exchange-Diagnostics: 1;AM4PR05MB1682;2:yPdzknM8uwsjT1ludFjKcpyFkVtFqWY+73tguE7L5zdXSuaDgno+RxoYlUgY9Wu9bIqqnzrY6Yj3XuZujh25n83yq079dkGzEVwGZwtAnd7Apowc8k6IlmfeCJZnDBMhKZwOYPstJ/9gaAR5kDYT65JcwSh+LWpA6ssLWIJqy1FZp40pzuDXO3xG1IjkYWjf;3:ZBKUge2XtgKEnu/9mNSMVi9YLEI9p31Th6LTc9E2BJu9YFTSsOPodN6+ICR2tXmkMMTUesMHcpK5GKJsJr8JQU9PavHl9GOVwgUsLs+mCJZsL2g0dK6lB1Bi/ykf5/1PYQ3/DIgxAFb/RQRKNp7Dnijc3KOpwcCaGQvheZUAj4chmcaqebGGRW7TpdplH5pGEcs52lOO1qhR6c9Vp/APN1kMSmXAHZIR9D8W6aYl248= X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:AM4PR05MB1682; X-Microsoft-Exchange-Diagnostics: 1;AM4PR05MB1682;25:j55mftX7s4Q3LskTFKgEBF/6rI/bUrv0Ytgj68bHZVznnBysl0mHRDDc/s7qMiO7yQDVAcRaE0lH9FzS+l9nrbGZqNgEiMwzyZBiSjgIZ1ibTovU3pHcyjrTnJl6uebwKLJnsCd1WPG9ivDytX/nFjLvQgPVclojjh3Bc2hw0BGUWjgt/iUVWfRIYwKMoxp9AAxCEzLc8r9xneBCyIt3kMJPCPGKi1u4//osWQyhW4m4EGeuF5O7lKvOi3DzvUe/PIqle8KYoXjUsV49nc9s1mr8f5yqah8c1GVMhLWF6o53+E3/ajaU+yKvkhYtELpKPqrmcskXrCskpHyM8i6QLSXSbA8bf/2mOtK71VwnfDtcAtPxVkf1YOfQY1DeTHyRQUtJDNZvc/u3lB42f55kMBDEHt3xBLxLetncxGzUEgPIOiqy6aeb6dkoxbom+jz0+TURwOMHn7KdgMplCS8ilQybF32fMdKVfPb3e2U7IBL8zHwQzLr7tmzgBK8fNGnqiysOZcF46ZIJEyDkQk/Kx45Cs70sh7FEWjJyFSHXlB34jjaQeLEbNdEhAY4kQkh3OFruUkOuZ9+vpJ8WTngcu+725m49XxGW3/rD9hyLIXU= X-Microsoft-Exchange-Diagnostics: 1;AM4PR05MB1682;20:cV5h5PkBID2PUGdEd8pe3N9Ok0OHvtq3ZeqHkBfg6DGb2NsP6mROkEl03fKK4qMiLPhONLV67rulUeQbQV94O/YSqbMFUOUjGoeESufR7dT10KdAaAB+0JbBmFJgmaJBhdgQRtAe5fj4JhzD8PD6WQFBpgcOMU+q6pPFlA5YWIPgdmFC2+BEaoF0KqzLiyviAlqRqMZw13FFb9TidyJa91QKi1n8NHd44up1kF4VwIntAbv++QvS4WYvTuuoBTrV2mhCZiuW6WNU0LtyUm1ZhCo78kAEB4UqYQL3Tj9RJ7MOinkWdKOkPQ6IO5qbITj/4Pw8jnETv16I8qoIhfvGXds7L2heOThNU+OVY5eATLq4JRwdlZHbGjgwT+TqhA8Pmg/ssG/1NfvTOPF/0HOQY76Ni0rsEO36Y9wbUpabXWBpeRTBNQxNbferIDTTYBKUi6mWG7XNQw8GrAEuj6J8jc52noRE47J4fTIpFpYOcbnJI/5flQ7eBZpPN5Q1TDTx 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)(13024025)(8121501046)(13015025)(13017025)(5005006)(10201501046)(3002001);SRVR:AM4PR05MB1682;BCL:0;PCL:0;RULEID:;SRVR:AM4PR05MB1682; X-Microsoft-Exchange-Diagnostics: 1;AM4PR05MB1682;4:dknO/+9UV0izGPXvZThR6MrV5ooYh7lrU+ThS3EgswnB/UsqS6hVhMUunvUGI8sX9sD8CVZlZa6bgD7N4HZEvMY16qVXdrI9I15B8nnk3udJ3/8VSWwJ43NTtvmhh7Q+3dbxiIyTzd7Lx0kONqElI651aHG6yyK6Hwc/Z3gJDx8vqfoLwbRTzFRGqHndIshVRBBHjyGTuJtIE1fhmqvtzGymJaCajzHWzegg6AbuYQk41SXR423Puhmego4TtMLJAnmIhrs8JIyD8MZwg2L9GccyE+SNcgoVDCK1JCJBZTeimqcXQPHQwMu7n5LmMuN+nE+L7hlC5Teacd0yYLiSxEkkaPXzxAsLAYPIfQr4XbqUlmc67Lg4i7OTdJI6vhxuaIxGAvqw1FuTLfP6q2bSSb/t7tigsl5tIBtzZ2LEMJZQfC7+WHUp7472FX1jzh4rs5/ha5VLwNVm3cuuP/rwlQ== X-Forefront-PRVS: 08978A8F5C X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;AM4PR05MB1682;23:uBcv58/3zC8i6PAyiYo9KRx9MXC3OHVLBWFikug06?= =?us-ascii?Q?lz9eeUHuDlG8+fzUWgMS36d0cz/3P+hqXC0hm4qrRw9LslFOxPBIiW2mzTuR?= =?us-ascii?Q?nZHYHjQ8nphls+WWOed7K69sJdx/yLlBsXjvsNhSFum06ilYiOIoIMul/xwA?= =?us-ascii?Q?nKKJzVtUy4B6x4Y1njY6rw2by8g4rGeE4S7SL5eV49osl/t0P8EHI/aMilt+?= =?us-ascii?Q?TTI6AP1OFY2HskFcqBP114OYLN+myyx7aBEh9pc5PuG/FlnY/IgLYJPtn543?= =?us-ascii?Q?shCrFYnAzz38/eGNGcsilUq7/nHa+LedJRfUgBmF+3oEM99KudMk0Lt65RLC?= =?us-ascii?Q?ybwsXZM/KyP/YwSUPtJng4aVV/emJ5oCcYlx8vuGAzMzizvjJm9+Ir5rkjxN?= =?us-ascii?Q?CFd1c77ixD+SjGiv1HyuItsfu5K4MAjSjdehti7dNCsqIzaZshF4QYP99EjM?= =?us-ascii?Q?lpHwkZReBryAgN1mXqLlyfvNdOC6Ktr0MreS317CJul9w+XnSt+3E//Dv+kj?= =?us-ascii?Q?gqxDxehuB3eGhuk5y0h/HFcccYzOCT5LqSpeSMRV5unfxitk5GdrGCgKnLSb?= =?us-ascii?Q?SyVPG21TPPWmzmS7eihmDtmO6lxyMYelTfxFV/KehUo2wJZvydqY/zvQa0eE?= =?us-ascii?Q?KxhkbGtUBWEGo/4OXTzesk6ZdEY3tNsYBQ7TMwRORfhmqYTQrtxWqyqmPLSV?= =?us-ascii?Q?+SUDfy2BjaNfBodS5J/g2VZCqGOWcESLA0jS2zZMRpWD9XF5dJ1Vi66+OKQJ?= =?us-ascii?Q?Lm5+qZd60gjJ+gdLmGYMUJ78pAaLdB0NIGqdymoyiSqJNqosFUy1ZgSAioFp?= =?us-ascii?Q?jes7CGVJY/uFa4BfzFBX2doCNCgsJutF7BrjmP+lmYC2PNpaZ1ob7MpIxF95?= =?us-ascii?Q?nbWonqqPbqQyvMy3o6FGQAZzMRRe3SI5JJ3U27R76g85ulMycTubWLcvR+J8?= =?us-ascii?Q?y9rV2onayj3bATw28HhCp37gtVzMAGRnbqSvvO1/VpeIGbzfvLBAtx2kfJ6p?= =?us-ascii?Q?I864D9gnL6LBioNcXSbm0SAbt1HWDm658gQN/K3gIgbcsWOsobQoPm7ZwsKF?= =?us-ascii?Q?Q0BA39iwuWnti4kdbcsQrWSPb/xnWBwcpEYBuotgve9WK8GN01J2gbiO9Bzc?= =?us-ascii?Q?TjbSJnC1fjEQbBbEz+UkGXJlIQM+44xL62BVfr7zbKQXP+Q17F8+DG/hxm+K?= =?us-ascii?Q?NRbDTWgq86dgU68HxG1W82SkDoexuo/u0JG?= X-Microsoft-Exchange-Diagnostics: 1;AM4PR05MB1682;5:o6CtllFbxqwSGO3yO9FGfmofMHbKu5K3phzuOSO/jsBDY8CpnXbThza3xDE+mBmtH8I40Q9MVCBgQh9QYwcSgi2YgUdK5hKqjEFOinnxuBAB1CzyotQMEKFWVTH6w/QqETKmCaQTcHXzZK6Y9tLC2w==;24:bYzPLJuzzR4gEIiszwV8NPeUbissqxNXWPd61GBGcglTWXVT4fqYvayxU7+DQSrWL5dUT+mZr8uc89N0zoGevoyCl6bS0D2Fb8YO0Y9sG4A= X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 30 Mar 2016 17:16:28.4202 (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: AM4PR05MB1682 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