Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753479AbcCVRfE (ORCPT ); Tue, 22 Mar 2016 13:35:04 -0400 Received: from mail-am1on0098.outbound.protection.outlook.com ([157.56.112.98]:62537 "EHLO emea01-am1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751365AbcCVRe5 (ORCPT ); Tue, 22 Mar 2016 13:34:57 -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" , Russell King , Thomas Gleixner , Aaron Tomlin , Ingo Molnar , Andrew Morton , Daniel Thompson , , , CC: Chris Metcalf Subject: [PATCH v3 1/4] nmi_backtrace: add more trigger_*_cpu_backtrace() methods Date: Tue, 22 Mar 2016 13:19:36 -0400 Message-ID: <1458667179-19630-2-git-send-email-cmetcalf@mellanox.com> X-Mailer: git-send-email 2.7.2 In-Reply-To: <1458667179-19630-1-git-send-email-cmetcalf@mellanox.com> References: <1458667179-19630-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)(199003)(189002)(105606002)(19580405001)(189998001)(107886002)(5001970100001)(19580395003)(85426001)(229853001)(92566002)(50226001)(106466001)(87936001)(50986999)(86362001)(2201001)(50466002)(76176999)(575784001)(48376002)(42186005)(36756003)(47776003)(5001770100001)(104016004)(6806005)(586003)(11100500001)(2950100001)(4326007)(2906002)(1096002)(5008740100001)(33646002)(1220700001)(4001430100002)(921003)(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;AM1FFO11OLC003;1:mEC09UNjxV8UOc8hD8cPHKFDn2PE5pvFDmwdm70kFTSVWktSq2NqurzB/yHB5UYNZmM36vq9DCvSd0kz5H1SgT9LiGq5VYs9hCJJGL88o2C8tRT2ZBtbaE9yy3+RzvXxft5FcVEFAOzLPfOmKo8+uKbYlAHvZWfFBkazYwn79G4mmb3GP/3i27mTF6mduBh1znSBUWnH/bT9Oll2FjyuZWkn+r5fpmT/YobSj4W0Ncs1B42/CCM958idxCJADIm0hPjPlJNo+je33AISzxQh0fn3weJZpG4Ky0VN1R3DRsVl32yBtM8mxtnq+Pe4lVC7Dr6RhBdHljTyKODzI/GMNzZWdnHaB7QRH9yuXKPnQppLDBrSbjaTtpTVPVBOl46pfZQKobvo82V6s+W7ySC6Nb60eXm5sKj3dpNjEBYk8JQCGkt0CI793jIvyLjLJ8Ykv6uV5JyNR4/cxhqXoQB2lasZ6JNNeECmvi0ax0A0VDvG8u3DqdcqxlbrUFzoj8AXu+kwbXGpoXZtpVk3BYBQMvvRy5IpcIlshAWw8wUJoXEihP8p5xlMqyZd7udYb/fZ MIME-Version: 1.0 Content-Type: text/plain X-MS-Office365-Filtering-Correlation-Id: 9dd77c9a-c1d4-45c9-b6cc-08d352762d7d X-Microsoft-Exchange-Diagnostics: 1;AM4PR05MB1682;2:HD8i7DB6wSoqEol1WPOWjcv1mfT/9JQv8jgOpezgV8X9SIQIfkkAUe48q/1wWazX0AB4OdE3/kon+rWgsH8EGkpdball6M3+ZD+I8ipMG5lP6CpwUvoC7IC2F6bMWmE2hRnIvzNyRmJh4cpHm0CkdrtiHGW0zxaJ7zdLjjA8BgJ+c64YXxEMq7UrvWKU6s24;3:eygntpp/5MqhJXurKjolgLfTzEbGIoZWNprXhlb4/TvQD0bzTff+XolZP0vprvmM5oR59cni4elgaXN5uNd/D8R/9wz8tCGhXYgnCi3hMBrCv2jYDs1/Ms8ExFmAAof0gfImO4WMpVPHZRad2ck3Axs+jjznl58U7NJxzpq6X00qaovM/CIBB4VkzCGDFwYofyHZSVB5W08kQNuP3ZDVoghojvLVT0dFaJrDp9FMayw= X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:AM4PR05MB1682; X-Microsoft-Exchange-Diagnostics: 1;AM4PR05MB1682;25:r3KwHHKkzA5EbtBd+LBfN/eJK7l7eybGA2ZiOv8QjHg6HmJmM008D82xWqlJzPOrPO0tK2Lue9Xh91HL2bp5bddRKs/rFDfmh5kbxhye1p1d3AUZ91mwnm5uYjdn+7GhZYWFRUh3vUq7dLNSZ+1GZA2OSJC/G6oAxMnBtAVxn/qv5sFN1Cij4E+nXFIQb6co+W8oyORloT9yn8/Zgl9J0ZFuZJdVU/n7P4gYbnJFcI1Gv99IYXS8k8LanjlqCEKBlwfgmyWzZ70rnkFVVsZAT/gUynqJQnM3cKaymh2vXZc/xrqZ0C9cHIC5/rgEfve7pSTEEjPmowqg2CVQIgbfGymPvCw1PxkrAyam4pTJiLweelBCT8RooBJzkqWDe2p3kDFSyYRElpvLaJVz8gUDY7OILsOXXuPL6PnyJNR1/emBG/t1rwh2TvbcRZvpfGqggO/sVFpTd6koK5sqZrAnVCinwBzoHHsCbu3qBaiyDNmbWADljChKON+Yzt1Par2f+pnrGTYTJ0ih1Xtlx6XKmgiQjvMson8tDFVtmbLIj3Twxqb+0GK3LZBCvxCbFkpi X-Microsoft-Exchange-Diagnostics: 1;AM4PR05MB1682;20:RD1NoCgXO9ho1eDVXKXV/y/YkyKoqbHv7yd6svSSamlHaJ5sKA6voCtioqxeFKMFhbY4nTkxnjd081NJzyVUAMZi2TPzSZ1zyHCvfRoQWN/iVLMdLYgscp15k5k6SSXhD8vg3u1lpny7DfAHNVdhWDG/F4gxP/K+Q7fu29r4xWODN9S6CQeB9qa1bdcW2vG38krjl9nvmv1eq4blMxONylkYjgKPQ/oSMtE6Du4u8J+oE8zNHeQH8ZSZdAX5aVtlKaryG8k60BqNPeZP2s6oltqTHufgETzGuHKUK1KlRzAyIareVx6dpG+niFk0ymrLaK/6rhYb1esFgtrlD4O7HokxsOixsHkVTYAzIEIxAclkVRKo10XX9tLFyBa3Qsw0v2KKbDQgAW8wGjmojS5zzBSZfakmUaLI1Sn2ok2ZAesIRsk4Zg6/b0JCE3x46QfKbJn87af1DRbIJbB6Mfa8vuAO3Q3r5TqV0Sg+S0aniMahXn9xVi+zLo3BFi0Xabkp X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(2401047)(13023025)(13017025)(5005006)(13018025)(13015025)(8121501046)(13024025)(3002001)(10201501046);SRVR:AM4PR05MB1682;BCL:0;PCL:0;RULEID:;SRVR:AM4PR05MB1682; X-Microsoft-Exchange-Diagnostics: 1;AM4PR05MB1682;4:F/RLb9NAcn9c1/EV9C9uQsMLwUbykq+4B2PMqJjC0f0JwEamc7X2paLj63sZJK6Ul7qrIADmny5tsGDgwjTzW3n3w4+p3O0CKQkPhdOJQwqMflRxB2K9a/QyIaTBncI/77OWMXvIKrIcK0HT0QYvdIggroB/EvnIcu1c3TD5pNz+DR6C3iSfuf/zChbopOzjqnkJnGeZZcRsYjpP3dj0Of+Nlj07beiMAMLmE58Y3b4h5y/B3S3E8SPQ986AuaZayUPaeqXjyBQ1Xg6pAnUFFrix4ILMr6Y3DmLgG46I7+tF6CyyaAWHCxZt7KxDRlnIkyxk6W85X2TyndRq5blJHt8OxoFrUyBBI3Z1wOzaZ8lQpggfUclhMP4KqWkx/U9wCKLRtzUXtsMMbUuVqBU9Wn9DpD4ym0leCRnSl4nKrq1Fkq5dcrfEynQJpwtr4LmqqEzyhG5O3siWMMeP9naKLw== X-Forefront-PRVS: 08897B549D X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;AM4PR05MB1682;23:u2G+VW/M55ViyTqEiAAO59X2+XK7zk6jC/UKKTCMb?= =?us-ascii?Q?Sc3rProxFFFmDvQfdljUSRksAQlhansQyJ3V2+HhsedbUG4RWVQvJ6j8gcwx?= =?us-ascii?Q?VTQDqzAZ0GYmf+L5tcEQcL51ZKIyoF8pM5NJ+ekqJ/6Nah+HB0HNkDg8J8I6?= =?us-ascii?Q?Ox0QTZqhFHP/us2/LIiJEo57RL+BjLXb3OqIWaT8evfpOc8c5OuWQQ3uyL/d?= =?us-ascii?Q?r+VDb8Po1EYrLWEgMxHLOOdIjIxNLxRnFNZg/mavYBfAZ7gEFkaeqz3WY2OE?= =?us-ascii?Q?YVnd8PSYc6C1w3GUV4un/iEZxWdFpiNjoHXhELmN1yJQkPvOHeC5xZEmDmfl?= =?us-ascii?Q?w6axW3N1xS5MHLh2mEw28jpUuWX+9EceGfv73oGmcwwmyQFBqDLNcG0M2M2r?= =?us-ascii?Q?iUJZuXPmJgVUV7hsS4ODhJ1kfhYf6exEBRtQqF/N8W0JhXo3vOlbZaAvAILG?= =?us-ascii?Q?tkhACwWJRr7K7UOQcJZ3ej5xoRqa/3RK5w1ONHd4+TEZu78pVLiztBbpdHiT?= =?us-ascii?Q?epyMWtGu0GWchqVO7j/T3aj6ej9WUpT8R3wFyVMooGqoHWP1XqGRxHNuAQW5?= =?us-ascii?Q?CPifSp7YlVjWfipHHtub+jq0E63F0ORFYWOtyWBoXE1WjjXVOqR2RgY79g5L?= =?us-ascii?Q?aBJF/Re5GBZNoXlh2qKvf2dcIb0aGuOxBNwL+DYVDRP3VPopmDEV+jQ9mw1o?= =?us-ascii?Q?IBw0j9y1GqfIs0daxJBVdV3t6tdg1lr2eQiH60xLfmzniI75piG5sBB2fp3X?= =?us-ascii?Q?iX5o3b/rxl5og8WQi79sfW9EA8yOBwwDTgpFzqZxdSu+xiXgYCGHJtsJzDmh?= =?us-ascii?Q?Nz76nt4hcZdm2RVCpKEd5fW7irK1a63XGgs7KsbMdmU/r2KVl5L0ugb5d1Fu?= =?us-ascii?Q?Hn78c7xArkhnbEEmU+ww9Zlo8li6cdqSta4RcADPAxiY7BH1qyJEKXlMW50A?= =?us-ascii?Q?DBx8LIg17Mm5mK7JemmKVE0KAgU9t1jjwFQfxKmhDtMMfjD6TEnsADDcD1Cx?= =?us-ascii?Q?u1Jk4O2+7jyYKaoic13vanP9InHzV7rZ0ZC6RmQfa+YdzqVnw/6zHOFAEMdj?= =?us-ascii?Q?vlpPAInq3B98gwiqZ2jR0PNnXD8bl1gsx5ygpTAWSpdKYQAVvyWVqjB6yqOK?= =?us-ascii?Q?2QUT8HT5WWIsm1kJvvgEknQJYwP1g5XNOGCdhOUW9V/OtcLJC5KQw=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1;AM4PR05MB1682;5:MKdd2BKNvThPcCRoUnY3e4M4cNoa3vMdaDwmf70WPGrph9KBHPoDCKjGeCQoVK/XS9lALIFaqbSoaNukZJaoW0Eex27vCNMlkRtADb7pBPUAFvy1VXOADWaH75Xqx3LnPTlRO1y9OYdQyoAnmDgyJw==;24:RCT1aeSQGcdxKPJFUoEM/Nzo96BZURS7TGQNheGe6MNKJRbDYMfKrrnloUukXHXXX8MNgimKDp9Vi/KgoYuelODQAlWSwrPrWVkNmTbVM58= X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 22 Mar 2016 17:19:50.7836 (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: 7778 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 37312f6749f3..208125658e56 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 7ec5b86735f3..951875f4f072 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 int hw_nmi_is_cpu_stuck(struct pt_regs *); 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