Commit dc219d8d authored by John Ogness's avatar John Ogness Committed by Petr Mladek

console: Improve console_srcu_read_flags() comments

It was not clear when exactly console_srcu_read_flags() must be
used vs. directly reading @console->flags.

Refactor and clarify that console_srcu_read_flags() is only
needed if the console is registered or the caller is in a
context where the registration status of the console may change
(due to another context).

The function requires the caller holds @console_srcu, which will
ensure that the caller sees an appropriate @flags value for the
registered console and that exit/cleanup routines will not run
if the console is in the process of unregistration.
Signed-off-by: default avatarJohn Ogness <john.ogness@linutronix.de>
Reviewed-by: default avatarPetr Mladek <pmladek@suse.com>
Link: https://lore.kernel.org/r/20240820063001.36405-13-john.ogness@linutronix.deSigned-off-by: default avatarPetr Mladek <pmladek@suse.com>
parent eabd4600
...@@ -446,28 +446,34 @@ extern void console_list_unlock(void) __releases(console_mutex); ...@@ -446,28 +446,34 @@ extern void console_list_unlock(void) __releases(console_mutex);
extern struct hlist_head console_list; extern struct hlist_head console_list;
/** /**
* console_srcu_read_flags - Locklessly read the console flags * console_srcu_read_flags - Locklessly read flags of a possibly registered
* console
* @con: struct console pointer of console to read flags from * @con: struct console pointer of console to read flags from
* *
* This function provides the necessary READ_ONCE() and data_race() * Locklessly reading @con->flags provides a consistent read value because
* notation for locklessly reading the console flags. The READ_ONCE() * there is at most one CPU modifying @con->flags and that CPU is using only
* in this function matches the WRITE_ONCE() when @flags are modified * read-modify-write operations to do so.
* for registered consoles with console_srcu_write_flags().
* *
* Only use this function to read console flags when locklessly * Requires console_srcu_read_lock to be held, which implies that @con might
* iterating the console list via srcu. * 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->flags directly instead.
* *
* Context: Any context. * Context: Any context.
* Return: The current value of the @con->flags field.
*/ */
static inline short console_srcu_read_flags(const struct console *con) static inline short console_srcu_read_flags(const struct console *con)
{ {
WARN_ON_ONCE(!console_srcu_read_lock_is_held()); WARN_ON_ONCE(!console_srcu_read_lock_is_held());
/* /*
* Locklessly reading console->flags provides a consistent * The READ_ONCE() matches the WRITE_ONCE() when @flags are modified
* read value because there is at most one CPU modifying * for registered consoles with console_srcu_write_flags().
* console->flags and that CPU is using only read-modify-write
* operations to do so.
*/ */
return data_race(READ_ONCE(con->flags)); return data_race(READ_ONCE(con->flags));
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment