Skip to content

Commit 8ebc476

Browse files
brenns10pmladek
authored andcommitted
printk: Drop console_sem during panic
If another CPU is in panic, we are about to be halted. Try to gracefully abandon the console_sem, leaving it free for the panic CPU to grab. Suggested-by: Petr Mladek <pmladek@suse.com> Signed-off-by: Stephen Brennan <stephen.s.brennan@oracle.com> Reviewed-by: Petr Mladek <pmladek@suse.com> Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org> Signed-off-by: Petr Mladek <pmladek@suse.com> Link: https://lore.kernel.org/r/20220202171821.179394-5-stephen.s.brennan@oracle.com
1 parent 13fb0f7 commit 8ebc476

File tree

1 file changed

+24
-1
lines changed

1 file changed

+24
-1
lines changed

kernel/printk/printk.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2597,6 +2597,25 @@ static int have_callable_console(void)
25972597
return 0;
25982598
}
25992599

2600+
/*
2601+
* Return true when this CPU should unlock console_sem without pushing all
2602+
* messages to the console. This reduces the chance that the console is
2603+
* locked when the panic CPU tries to use it.
2604+
*/
2605+
static bool abandon_console_lock_in_panic(void)
2606+
{
2607+
if (!panic_in_progress())
2608+
return false;
2609+
2610+
/*
2611+
* We can use raw_smp_processor_id() here because it is impossible for
2612+
* the task to be migrated to the panic_cpu, or away from it. If
2613+
* panic_cpu has already been set, and we're not currently executing on
2614+
* that CPU, then we never will be.
2615+
*/
2616+
return atomic_read(&panic_cpu) != raw_smp_processor_id();
2617+
}
2618+
26002619
/*
26012620
* Can we actually use the console at this time on this cpu?
26022621
*
@@ -2745,6 +2764,10 @@ void console_unlock(void)
27452764
if (handover)
27462765
return;
27472766

2767+
/* Allow panic_cpu to take over the consoles safely */
2768+
if (abandon_console_lock_in_panic())
2769+
break;
2770+
27482771
if (do_cond_resched)
27492772
cond_resched();
27502773
}
@@ -2762,7 +2785,7 @@ void console_unlock(void)
27622785
* flush, no worries.
27632786
*/
27642787
retry = prb_read_valid(prb, next_seq, NULL);
2765-
if (retry && console_trylock())
2788+
if (retry && !abandon_console_lock_in_panic() && console_trylock())
27662789
goto again;
27672790
}
27682791
EXPORT_SYMBOL(console_unlock);

0 commit comments

Comments
 (0)