]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-6.8/dump_stack-do-not-get-cpu_sync-for-panic-cpu.patch
Fixes for 6.8
[thirdparty/kernel/stable-queue.git] / queue-6.8 / dump_stack-do-not-get-cpu_sync-for-panic-cpu.patch
1 From ffdb28902359d97bbf24eaa25d7b1585a0f91142 Mon Sep 17 00:00:00 2001
2 From: Sasha Levin <sashal@kernel.org>
3 Date: Wed, 7 Feb 2024 14:47:03 +0106
4 Subject: dump_stack: Do not get cpu_sync for panic CPU
5
6 From: John Ogness <john.ogness@linutronix.de>
7
8 [ Upstream commit 7412dc6d55eed6b76180e40ac3601412ebde29bd ]
9
10 dump_stack() is called in panic(). If for some reason another CPU
11 is holding the printk_cpu_sync and is unable to release it, the
12 panic CPU will be unable to continue and print the stacktrace.
13
14 Since non-panic CPUs are not allowed to store new printk messages
15 anyway, there is no need to synchronize the stacktrace output in
16 a panic situation.
17
18 For the panic CPU, do not get the printk_cpu_sync because it is
19 not needed and avoids a potential deadlock scenario in panic().
20
21 Link: https://lore.kernel.org/lkml/ZcIGKU8sxti38Kok@alley
22 Signed-off-by: John Ogness <john.ogness@linutronix.de>
23 Reviewed-by: Petr Mladek <pmladek@suse.com>
24 Link: https://lore.kernel.org/r/20240207134103.1357162-15-john.ogness@linutronix.de
25 Signed-off-by: Petr Mladek <pmladek@suse.com>
26 Signed-off-by: Sasha Levin <sashal@kernel.org>
27 ---
28 include/linux/printk.h | 2 ++
29 kernel/printk/internal.h | 1 -
30 lib/dump_stack.c | 16 +++++++++++++---
31 3 files changed, 15 insertions(+), 4 deletions(-)
32
33 diff --git a/include/linux/printk.h b/include/linux/printk.h
34 index 8ef499ab3c1ed..955e31860095e 100644
35 --- a/include/linux/printk.h
36 +++ b/include/linux/printk.h
37 @@ -273,6 +273,8 @@ static inline void printk_trigger_flush(void)
38 }
39 #endif
40
41 +bool this_cpu_in_panic(void);
42 +
43 #ifdef CONFIG_SMP
44 extern int __printk_cpu_sync_try_get(void);
45 extern void __printk_cpu_sync_wait(void);
46 diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h
47 index ac2d9750e5f81..6c2afee5ef620 100644
48 --- a/kernel/printk/internal.h
49 +++ b/kernel/printk/internal.h
50 @@ -130,7 +130,6 @@ struct printk_message {
51 };
52
53 bool other_cpu_in_panic(void);
54 -bool this_cpu_in_panic(void);
55 bool printk_get_next_message(struct printk_message *pmsg, u64 seq,
56 bool is_extended, bool may_supress);
57
58 diff --git a/lib/dump_stack.c b/lib/dump_stack.c
59 index 83471e81501a7..222c6d6c8281a 100644
60 --- a/lib/dump_stack.c
61 +++ b/lib/dump_stack.c
62 @@ -96,15 +96,25 @@ static void __dump_stack(const char *log_lvl)
63 */
64 asmlinkage __visible void dump_stack_lvl(const char *log_lvl)
65 {
66 + bool in_panic = this_cpu_in_panic();
67 unsigned long flags;
68
69 /*
70 * Permit this cpu to perform nested stack dumps while serialising
71 - * against other CPUs
72 + * against other CPUs, unless this CPU is in panic.
73 + *
74 + * When in panic, non-panic CPUs are not permitted to store new
75 + * printk messages so there is no need to synchronize the output.
76 + * This avoids potential deadlock in panic() if another CPU is
77 + * holding and unable to release the printk_cpu_sync.
78 */
79 - printk_cpu_sync_get_irqsave(flags);
80 + if (!in_panic)
81 + printk_cpu_sync_get_irqsave(flags);
82 +
83 __dump_stack(log_lvl);
84 - printk_cpu_sync_put_irqrestore(flags);
85 +
86 + if (!in_panic)
87 + printk_cpu_sync_put_irqrestore(flags);
88 }
89 EXPORT_SYMBOL(dump_stack_lvl);
90
91 --
92 2.43.0
93