Skip to content

Commit 51a1d25

Browse files
jognesspmladek
authored andcommitted
printk: Keep non-panic-CPUs out of console lock
When in a panic situation, non-panic CPUs should avoid holding the console lock so as not to contend with the panic CPU. This is already implemented with abandon_console_lock_in_panic(), which is checked after each printed line. However, non-panic CPUs should also avoid trying to acquire the console lock during a panic. Modify console_trylock() to fail and console_lock() to block() when called from a non-panic CPU during a panic. Signed-off-by: John Ogness <[email protected]> Reviewed-by: Sergey Senozhatsky <[email protected]> Reviewed-by: Petr Mladek <[email protected]> Signed-off-by: Petr Mladek <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 7b23a66 commit 51a1d25

File tree

1 file changed

+26
-19
lines changed

1 file changed

+26
-19
lines changed

kernel/printk/printk.c

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2583,6 +2583,25 @@ static int console_cpu_notify(unsigned int cpu)
25832583
return 0;
25842584
}
25852585

2586+
/*
2587+
* Return true when this CPU should unlock console_sem without pushing all
2588+
* messages to the console. This reduces the chance that the console is
2589+
* locked when the panic CPU tries to use it.
2590+
*/
2591+
static bool abandon_console_lock_in_panic(void)
2592+
{
2593+
if (!panic_in_progress())
2594+
return false;
2595+
2596+
/*
2597+
* We can use raw_smp_processor_id() here because it is impossible for
2598+
* the task to be migrated to the panic_cpu, or away from it. If
2599+
* panic_cpu has already been set, and we're not currently executing on
2600+
* that CPU, then we never will be.
2601+
*/
2602+
return atomic_read(&panic_cpu) != raw_smp_processor_id();
2603+
}
2604+
25862605
/**
25872606
* console_lock - block the console subsystem from printing
25882607
*
@@ -2595,6 +2614,10 @@ void console_lock(void)
25952614
{
25962615
might_sleep();
25972616

2617+
/* On panic, the console_lock must be left to the panic cpu. */
2618+
while (abandon_console_lock_in_panic())
2619+
msleep(1000);
2620+
25982621
down_console_sem();
25992622
if (console_suspended)
26002623
return;
@@ -2613,6 +2636,9 @@ EXPORT_SYMBOL(console_lock);
26132636
*/
26142637
int console_trylock(void)
26152638
{
2639+
/* On panic, the console_lock must be left to the panic cpu. */
2640+
if (abandon_console_lock_in_panic())
2641+
return 0;
26162642
if (down_trylock_console_sem())
26172643
return 0;
26182644
if (console_suspended) {
@@ -2631,25 +2657,6 @@ int is_console_locked(void)
26312657
}
26322658
EXPORT_SYMBOL(is_console_locked);
26332659

2634-
/*
2635-
* Return true when this CPU should unlock console_sem without pushing all
2636-
* messages to the console. This reduces the chance that the console is
2637-
* locked when the panic CPU tries to use it.
2638-
*/
2639-
static bool abandon_console_lock_in_panic(void)
2640-
{
2641-
if (!panic_in_progress())
2642-
return false;
2643-
2644-
/*
2645-
* We can use raw_smp_processor_id() here because it is impossible for
2646-
* the task to be migrated to the panic_cpu, or away from it. If
2647-
* panic_cpu has already been set, and we're not currently executing on
2648-
* that CPU, then we never will be.
2649-
*/
2650-
return atomic_read(&panic_cpu) != raw_smp_processor_id();
2651-
}
2652-
26532660
/*
26542661
* Check if the given console is currently capable and allowed to print
26552662
* records.

0 commit comments

Comments
 (0)