Skip to content

Commit 7412dc6

Browse files
jognesspmladek
authored andcommitted
dump_stack: Do not get cpu_sync for panic CPU
dump_stack() is called in panic(). If for some reason another CPU is holding the printk_cpu_sync and is unable to release it, the panic CPU will be unable to continue and print the stacktrace. Since non-panic CPUs are not allowed to store new printk messages anyway, there is no need to synchronize the stacktrace output in a panic situation. For the panic CPU, do not get the printk_cpu_sync because it is not needed and avoids a potential deadlock scenario in panic(). Link: https://lore.kernel.org/lkml/ZcIGKU8sxti38Kok@alley Signed-off-by: John Ogness <[email protected]> Reviewed-by: Petr Mladek <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Petr Mladek <[email protected]>
1 parent d988d9a commit 7412dc6

File tree

3 files changed

+15
-4
lines changed

3 files changed

+15
-4
lines changed

include/linux/printk.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,8 @@ static inline void printk_trigger_flush(void)
273273
}
274274
#endif
275275

276+
bool this_cpu_in_panic(void);
277+
276278
#ifdef CONFIG_SMP
277279
extern int __printk_cpu_sync_try_get(void);
278280
extern void __printk_cpu_sync_wait(void);

kernel/printk/internal.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,6 @@ struct printk_message {
130130
};
131131

132132
bool other_cpu_in_panic(void);
133-
bool this_cpu_in_panic(void);
134133
bool printk_get_next_message(struct printk_message *pmsg, u64 seq,
135134
bool is_extended, bool may_supress);
136135

lib/dump_stack.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,15 +96,25 @@ static void __dump_stack(const char *log_lvl)
9696
*/
9797
asmlinkage __visible void dump_stack_lvl(const char *log_lvl)
9898
{
99+
bool in_panic = this_cpu_in_panic();
99100
unsigned long flags;
100101

101102
/*
102103
* Permit this cpu to perform nested stack dumps while serialising
103-
* against other CPUs
104+
* against other CPUs, unless this CPU is in panic.
105+
*
106+
* When in panic, non-panic CPUs are not permitted to store new
107+
* printk messages so there is no need to synchronize the output.
108+
* This avoids potential deadlock in panic() if another CPU is
109+
* holding and unable to release the printk_cpu_sync.
104110
*/
105-
printk_cpu_sync_get_irqsave(flags);
111+
if (!in_panic)
112+
printk_cpu_sync_get_irqsave(flags);
113+
106114
__dump_stack(log_lvl);
107-
printk_cpu_sync_put_irqrestore(flags);
115+
116+
if (!in_panic)
117+
printk_cpu_sync_put_irqrestore(flags);
108118
}
109119
EXPORT_SYMBOL(dump_stack_lvl);
110120

0 commit comments

Comments
 (0)