[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <a226b9dced07bba6d9486dea18507be6290fdd38.1764272407.git.chris@chrisdown.name>
Date: Fri, 28 Nov 2025 03:43:29 +0800
From: Chris Down <chris@...isdown.name>
To: Petr Mladek <pmladek@...e.com>
Cc: linux-kernel@...r.kernel.org,
Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
Sergey Senozhatsky <senozhatsky@...omium.org>,
Steven Rostedt <rostedt@...dmis.org>,
John Ogness <john.ogness@...utronix.de>,
Geert Uytterhoeven <geert@...ux-m68k.org>,
Tony Lindgren <tony.lindgren@...ux.intel.com>, kernel-team@...com
Subject: [PATCH v8 05/21] printk: console: Add per-console loglevel support
to struct console
The printk subsystem currently uses a single global console_loglevel
to control which messages are emitted to all consoles. This works well
when all consoles have similar characteristics, but consoles can have
vastly different latencies and throughputs.
For example, writing a message to the serial console can take on the
order of tens of milliseconds to get the UART to successfully write a
message. While this is fine for a single, one-off message, this can
cause significant application-level stalls when the kernel writes large
amounts of information to the console.
In preparation for allowing each console to filter messages at its own
loglevel, this commit adds the basic infrastructure to support that.
Each struct console now has a level field, and a new
console_srcu_read_loglevel() helper is added to safely read it under
SRCU.
Reviewed-by: Petr Mladek <pmladek@...e.com>
Signed-off-by: Chris Down <chris@...isdown.name>
---
include/linux/console.h | 36 ++++++++++++++++++++++++++++++++++++
kernel/printk/printk.c | 3 +++
2 files changed, 39 insertions(+)
diff --git a/include/linux/console.h b/include/linux/console.h
index 8f10d0a85bb4..a670c40623ad 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -314,6 +314,8 @@ struct nbcon_write_context {
* @match: Callback for matching a console (Optional)
* @flags: Console flags. See enum cons_flags
* @index: Console index, e.g. port number
+ * @level: Per-console loglevel. -1 means use global console_loglevel,
+ * values > 0 specify console-specific filtering level
* @cflag: TTY control mode flags
* @ispeed: TTY input speed
* @ospeed: TTY output speed
@@ -342,6 +344,7 @@ struct console {
int (*match)(struct console *co, char *name, int idx, char *options);
short flags;
short index;
+ int level;
int cflag;
uint ispeed;
uint ospeed;
@@ -544,6 +547,39 @@ static inline void console_srcu_write_flags(struct console *con, short flags)
WRITE_ONCE(con->flags, flags);
}
+/**
+ * console_srcu_read_loglevel - Locklessly read the console specific loglevel
+ * of a possibly registered console
+ * @con: struct console pointer of console to read loglevel from
+ *
+ * Locklessly reading @con->level provides a consistent read value because
+ * there is at most one CPU modifying @con->level and that CPU is using only
+ * read-modify-write operations to do so.
+ *
+ * Requires console_srcu_read_lock to be held, which implies that @con might
+ * be a registered console. The purpose of holding console_srcu_read_lock is
+ * to guarantee that the console state is valid (CON_SUSPENDED/CON_ENABLED)
+ * and that no exit/cleanup routines will run if the console is currently
+ * undergoing unregistration.
+ *
+ * If the caller is holding the console_list_lock or it is _certain_ that
+ * @con is not and will not become registered, the caller may read
+ * @con->level directly instead.
+ *
+ * Context: Any context.
+ * Return: The current value of the @con->level field.
+ */
+static inline int console_srcu_read_loglevel(const struct console *con)
+{
+ WARN_ON_ONCE(!console_srcu_read_lock_is_held());
+
+ /*
+ * The READ_ONCE() matches the WRITE_ONCE() when @level is modified
+ * for registered consoles.
+ */
+ return data_race(READ_ONCE(con->level));
+}
+
/* Variant of console_is_registered() when the console_list_lock is held. */
static inline bool console_is_registered_locked(const struct console *con)
{
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 9f40ebfac0c1..c6b56f4d8072 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -3848,6 +3848,9 @@ static int try_enable_preferred_console(struct console *newcon,
if (newcon->index < 0)
newcon->index = c->index;
+ /* TODO: will be configurable in a later patch */
+ newcon->level = LOGLEVEL_DEFAULT;
+
if (_braille_register_console(newcon, c))
return 0;
--
2.51.2
Powered by blists - more mailing lists