mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
console: introduce wrappers to read/write console flags
After switching to SRCU for console list iteration, some readers will begin readings console->flags as a data race. Locklessly reading console->flags provides a consistent value because there is at most one CPU modifying console->flags and that CPU is using only read-modify-write operations. Introduce a wrapper for SRCU iterators to read console flags. Introduce a matching wrapper to write to flags of registered consoles. Writing to flags of registered consoles is synchronized by the console_list_lock. Signed-off-by: John Ogness <john.ogness@linutronix.de> Reviewed-by: Petr Mladek <pmladek@suse.com> Signed-off-by: Petr Mladek <pmladek@suse.com> Link: https://lore.kernel.org/r/20221116162152.193147-13-john.ogness@linutronix.de
This commit is contained in:
parent
4dc64682ad
commit
100bdef2c1
2 changed files with 50 additions and 5 deletions
|
@ -183,6 +183,51 @@ extern void console_list_unlock(void) __releases(console_mutex);
|
|||
|
||||
extern struct hlist_head console_list;
|
||||
|
||||
/**
|
||||
* console_srcu_read_flags - Locklessly read the console flags
|
||||
* @con: struct console pointer of console to read flags from
|
||||
*
|
||||
* This function provides the necessary READ_ONCE() and data_race()
|
||||
* notation for locklessly reading the console flags. The READ_ONCE()
|
||||
* in this function matches the WRITE_ONCE() when @flags are modified
|
||||
* for registered consoles with console_srcu_write_flags().
|
||||
*
|
||||
* Only use this function to read console flags when locklessly
|
||||
* iterating the console list via srcu.
|
||||
*
|
||||
* Context: Any context.
|
||||
*/
|
||||
static inline short console_srcu_read_flags(const struct console *con)
|
||||
{
|
||||
WARN_ON_ONCE(!console_srcu_read_lock_is_held());
|
||||
|
||||
/*
|
||||
* Locklessly reading console->flags provides a consistent
|
||||
* read value because there is at most one CPU modifying
|
||||
* console->flags and that CPU is using only read-modify-write
|
||||
* operations to do so.
|
||||
*/
|
||||
return data_race(READ_ONCE(con->flags));
|
||||
}
|
||||
|
||||
/**
|
||||
* console_srcu_write_flags - Write flags for a registered console
|
||||
* @con: struct console pointer of console to write flags to
|
||||
* @flags: new flags value to write
|
||||
*
|
||||
* Only use this function to write flags for registered consoles. It
|
||||
* requires holding the console_list_lock.
|
||||
*
|
||||
* Context: Any context.
|
||||
*/
|
||||
static inline void console_srcu_write_flags(struct console *con, short flags)
|
||||
{
|
||||
lockdep_assert_console_list_lock_held();
|
||||
|
||||
/* This matches the READ_ONCE() in console_srcu_read_flags(). */
|
||||
WRITE_ONCE(con->flags, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* for_each_console_srcu() - Iterator over registered consoles
|
||||
* @con: struct console pointer used as loop cursor
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue