Skip to content

Commit

Permalink
dump_stack: Do not get cpu_sync for panic CPU
Browse files Browse the repository at this point in the history
[ Upstream commit 7412dc6 ]

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 <john.ogness@linutronix.de>
Reviewed-by: Petr Mladek <pmladek@suse.com>
Link: https://lore.kernel.org/r/20240207134103.1357162-15-john.ogness@linutronix.de
Signed-off-by: Petr Mladek <pmladek@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
jogness authored and gregkh committed Apr 13, 2024
1 parent 365224c commit a63a05d
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 4 deletions.
2 changes: 2 additions & 0 deletions include/linux/printk.h
Expand Up @@ -273,6 +273,8 @@ static inline void printk_trigger_flush(void)
}
#endif

bool this_cpu_in_panic(void);

#ifdef CONFIG_SMP
extern int __printk_cpu_sync_try_get(void);
extern void __printk_cpu_sync_wait(void);
Expand Down
1 change: 0 additions & 1 deletion kernel/printk/internal.h
Expand Up @@ -130,7 +130,6 @@ struct printk_message {
};

bool other_cpu_in_panic(void);
bool this_cpu_in_panic(void);
bool printk_get_next_message(struct printk_message *pmsg, u64 seq,
bool is_extended, bool may_supress);

Expand Down
16 changes: 13 additions & 3 deletions lib/dump_stack.c
Expand Up @@ -96,15 +96,25 @@ static void __dump_stack(const char *log_lvl)
*/
asmlinkage __visible void dump_stack_lvl(const char *log_lvl)
{
bool in_panic = this_cpu_in_panic();
unsigned long flags;

/*
* Permit this cpu to perform nested stack dumps while serialising
* against other CPUs
* against other CPUs, unless this CPU is in panic.
*
* When in panic, non-panic CPUs are not permitted to store new
* printk messages so there is no need to synchronize the output.
* This avoids potential deadlock in panic() if another CPU is
* holding and unable to release the printk_cpu_sync.
*/
printk_cpu_sync_get_irqsave(flags);
if (!in_panic)
printk_cpu_sync_get_irqsave(flags);

__dump_stack(log_lvl);
printk_cpu_sync_put_irqrestore(flags);

if (!in_panic)
printk_cpu_sync_put_irqrestore(flags);
}
EXPORT_SYMBOL(dump_stack_lvl);

Expand Down

0 comments on commit a63a05d

Please sign in to comment.