Skip to content

Commit eacb04f

Browse files
jognesspmladek
authored andcommitted
printk: Do not take console lock for console_flush_on_panic()
Currently console_flush_on_panic() will attempt to acquire the console lock when flushing the buffer on panic. If it fails to acquire the lock, it continues anyway because this is the last chance to get any pending records printed. The reason why the console lock was attempted at all was to prevent any other CPUs from acquiring the console lock for printing while the panic CPU was printing. But as of the previous commit, non-panic CPUs will no longer attempt to acquire the console lock in a panic situation. Therefore it is no longer strictly necessary for a panic CPU to acquire the console lock. Avoiding taking the console lock when flushing in panic has the additional benefit of avoiding possible deadlocks due to semaphore usage in NMI context (semaphores are not NMI-safe) and avoiding possible deadlocks if another CPU accesses the semaphore and is stopped while holding one of the semaphore's internal spinlocks. 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 51a1d25 commit eacb04f

File tree

1 file changed

+19
-9
lines changed

1 file changed

+19
-9
lines changed

kernel/printk/printk.c

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3118,14 +3118,24 @@ void console_unblank(void)
31183118
*/
31193119
void console_flush_on_panic(enum con_flush_mode mode)
31203120
{
3121+
bool handover;
3122+
u64 next_seq;
3123+
31213124
/*
3122-
* If someone else is holding the console lock, trylock will fail
3123-
* and may_schedule may be set. Ignore and proceed to unlock so
3124-
* that messages are flushed out. As this can be called from any
3125-
* context and we don't want to get preempted while flushing,
3126-
* ensure may_schedule is cleared.
3125+
* Ignore the console lock and flush out the messages. Attempting a
3126+
* trylock would not be useful because:
3127+
*
3128+
* - if it is contended, it must be ignored anyway
3129+
* - console_lock() and console_trylock() block and fail
3130+
* respectively in panic for non-panic CPUs
3131+
* - semaphores are not NMI-safe
3132+
*/
3133+
3134+
/*
3135+
* If another context is holding the console lock,
3136+
* @console_may_schedule might be set. Clear it so that
3137+
* this context does not call cond_resched() while flushing.
31273138
*/
3128-
console_trylock();
31293139
console_may_schedule = 0;
31303140

31313141
if (mode == CONSOLE_REPLAY_ALL) {
@@ -3138,15 +3148,15 @@ void console_flush_on_panic(enum con_flush_mode mode)
31383148
cookie = console_srcu_read_lock();
31393149
for_each_console_srcu(c) {
31403150
/*
3141-
* If the above console_trylock() failed, this is an
3142-
* unsynchronized assignment. But in that case, the
3151+
* This is an unsynchronized assignment, but the
31433152
* kernel is in "hope and pray" mode anyway.
31443153
*/
31453154
c->seq = seq;
31463155
}
31473156
console_srcu_read_unlock(cookie);
31483157
}
3149-
console_unlock();
3158+
3159+
console_flush_all(false, &next_seq, &handover);
31503160
}
31513161

31523162
/*

0 commit comments

Comments
 (0)