[PATCH v1] printk: Add CON_NO_SUPPRESS console flag and use it for ramoops
From: Pasha Tatashin
Date: Fri Jun 12 2026 - 13:26:45 EST
The ramoops console is designed to capture and preserve logs across warm
reboots and liveupdates. It is registered during boot and captures logs
from that point forward. However, if a 'quiet' loglevel is specified on
the kernel command line, ramoops console logs (including important
shutdown/kexec handover logs) can be filtered out and suppressed by
printk.
Specifying 'quiet' on the kernel command line is highly desirable to
avoid severe warm-reboot slowdowns, since physical serial consoles are
typically bottlenecked by slow baud rates. However, we still need to
fully capture all logs in memory via ramoops without suppression.
Introduce a generic console flag CON_NO_SUPPRESS to allow specific
consoles (like the ramoops/pstore console) to opt-out of loglevel
suppression. Check this flag safely in console_emit_next_record() and
nbcon_emit_next_record(). Finally, set this flag on registration of the
pstore console in pstore_register_console().
Signed-off-by: Pasha Tatashin <pasha.tatashin@xxxxxxxxxx>
---
fs/pstore/platform.c | 2 +-
include/linux/console.h | 3 +++
kernel/printk/nbcon.c | 5 ++++-
kernel/printk/printk.c | 4 +++-
4 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 1d76c9d92056..9efbaa9895da 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -420,7 +420,7 @@ static void pstore_register_console(void)
* Always initialize flags here since prior unregister_console()
* calls may have changed settings (specifically CON_ENABLED).
*/
- pstore_console.flags = CON_PRINTBUFFER | CON_ENABLED | CON_ANYTIME;
+ pstore_console.flags = CON_PRINTBUFFER | CON_ENABLED | CON_ANYTIME | CON_NO_SUPPRESS;
register_console(&pstore_console);
}
diff --git a/include/linux/console.h b/include/linux/console.h
index 5520e4477ad7..9bd06d3fece3 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -180,6 +180,8 @@ static inline void con_debug_leave(void) { }
* constraints.
* @CON_NBCON_ATOMIC_UNSAFE: The write_atomic() callback is not safe and is
* therefore only used by nbcon_atomic_flush_unsafe().
+ * @CON_NO_SUPPRESS: Indicates that the console is exempt from loglevel-based
+ * message suppression (e.g. from the 'quiet' boot argument).
*/
enum cons_flags {
CON_PRINTBUFFER = BIT(0),
@@ -192,6 +194,7 @@ enum cons_flags {
CON_SUSPENDED = BIT(7),
CON_NBCON = BIT(8),
CON_NBCON_ATOMIC_UNSAFE = BIT(9),
+ CON_NO_SUPPRESS = BIT(10),
};
/**
diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c
index d7044a7a214b..cd0fc5f42360 100644
--- a/kernel/printk/nbcon.c
+++ b/kernel/printk/nbcon.c
@@ -989,6 +989,7 @@ static bool nbcon_emit_next_record(struct nbcon_write_context *wctxt, bool use_a
struct nbcon_state cur;
unsigned long dropped;
unsigned long ulseq;
+ bool may_suppress;
/*
* This function should never be called for consoles that have not
@@ -1014,7 +1015,9 @@ static bool nbcon_emit_next_record(struct nbcon_write_context *wctxt, bool use_a
if (!nbcon_context_enter_unsafe(ctxt))
return false;
- ctxt->backlog = printk_get_next_message(&pmsg, ctxt->seq, is_extended, true);
+ may_suppress = !(console_srcu_read_flags(con) & CON_NO_SUPPRESS);
+ ctxt->backlog = printk_get_next_message(&pmsg, ctxt->seq, is_extended,
+ may_suppress);
if (!ctxt->backlog)
return nbcon_context_exit_unsafe(ctxt);
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 0323149548f6..f6502cb84160 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -3131,10 +3131,12 @@ static bool console_emit_next_record(struct console *con, bool *handover, int co
.pbufs = &printk_shared_pbufs,
};
unsigned long flags;
+ bool may_suppress;
*handover = false;
- if (!printk_get_next_message(&pmsg, con->seq, is_extended, true))
+ may_suppress = !(console_srcu_read_flags(con) & CON_NO_SUPPRESS);
+ if (!printk_get_next_message(&pmsg, con->seq, is_extended, may_suppress))
return false;
con->dropped += pmsg.dropped;
--
2.53.0