Skip to content

Commit 779dbc2

Browse files
jognesspmladek
authored andcommitted
printk: Avoid non-panic CPUs writing to ringbuffer
Commit 13fb0f7 ("printk: Avoid livelock with heavy printk during panic") introduced a mechanism to silence non-panic CPUs if too many messages are being dropped. Aside from trying to workaround the livelock bugs of legacy consoles, it was also intended to avoid losing panic messages. However, if non-panic CPUs are writing to the ringbuffer, then reacting to dropped messages is too late. Another motivation is that non-finalized messages already might be skipped in panic(). In other words, random messages from non-panic CPUs might already get lost. It is better to ignore all to avoid confusion. To avoid losing panic CPU messages, silence non-panic CPUs immediately on panic. 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 d04d588 commit 779dbc2

File tree

1 file changed

+6
-20
lines changed

1 file changed

+6
-20
lines changed

kernel/printk/printk.c

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -462,12 +462,6 @@ static int console_msg_format = MSG_FORMAT_DEFAULT;
462462
static DEFINE_MUTEX(syslog_lock);
463463

464464
#ifdef CONFIG_PRINTK
465-
/*
466-
* During panic, heavy printk by other CPUs can delay the
467-
* panic and risk deadlock on console resources.
468-
*/
469-
static int __read_mostly suppress_panic_printk;
470-
471465
DECLARE_WAIT_QUEUE_HEAD(log_wait);
472466
/* All 3 protected by @syslog_lock. */
473467
/* the next printk record to read by syslog(READ) or /proc/kmsg */
@@ -2322,7 +2316,12 @@ asmlinkage int vprintk_emit(int facility, int level,
23222316
if (unlikely(suppress_printk))
23232317
return 0;
23242318

2325-
if (unlikely(suppress_panic_printk) && other_cpu_in_panic())
2319+
/*
2320+
* The messages on the panic CPU are the most important. If
2321+
* non-panic CPUs are generating any messages, they will be
2322+
* silently dropped.
2323+
*/
2324+
if (other_cpu_in_panic())
23262325
return 0;
23272326

23282327
if (level == LOGLEVEL_SCHED) {
@@ -2799,8 +2798,6 @@ void console_prepend_dropped(struct printk_message *pmsg, unsigned long dropped)
27992798
bool printk_get_next_message(struct printk_message *pmsg, u64 seq,
28002799
bool is_extended, bool may_suppress)
28012800
{
2802-
static int panic_console_dropped;
2803-
28042801
struct printk_buffers *pbufs = pmsg->pbufs;
28052802
const size_t scratchbuf_sz = sizeof(pbufs->scratchbuf);
28062803
const size_t outbuf_sz = sizeof(pbufs->outbuf);
@@ -2828,17 +2825,6 @@ bool printk_get_next_message(struct printk_message *pmsg, u64 seq,
28282825
pmsg->seq = r.info->seq;
28292826
pmsg->dropped = r.info->seq - seq;
28302827

2831-
/*
2832-
* Check for dropped messages in panic here so that printk
2833-
* suppression can occur as early as possible if necessary.
2834-
*/
2835-
if (pmsg->dropped &&
2836-
panic_in_progress() &&
2837-
panic_console_dropped++ > 10) {
2838-
suppress_panic_printk = 1;
2839-
pr_warn_once("Too many dropped messages. Suppress messages on non-panic CPUs to prevent livelock.\n");
2840-
}
2841-
28422828
/* Skip record that has level above the console loglevel. */
28432829
if (may_suppress && suppress_message_printing(r.info->level))
28442830
goto out;

0 commit comments

Comments
 (0)