diff options
author | John Ogness <john.ogness@linutronix.de> | 2022-11-16 17:27:31 +0106 |
---|---|---|
committer | Petr Mladek <pmladek@suse.com> | 2022-12-02 11:25:01 +0100 |
commit | 87f2e4b7d9e5c50756184b4f8d0b92680de61496 (patch) | |
tree | 11258aabf266bf5614213aa675fe6252088e16ba | |
parent | d792db6f6b902dad6b751dc2ef226fb4463efe62 (diff) |
printk: console_flush_on_panic: use srcu console list iterator
With SRCU it is now safe to traverse the console list, even if
the console_trylock() failed. However, overwriting console->seq
when console_trylock() failed is still an issue.
Switch to SRCU iteration and document remaining issue with
console->seq.
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-20-john.ogness@linutronix.de
-rw-r--r-- | kernel/printk/printk.c | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 8e37a35764f2..b78947077659 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -3050,21 +3050,22 @@ void console_flush_on_panic(enum con_flush_mode mode) console_may_schedule = 0; if (mode == CONSOLE_REPLAY_ALL) { - struct hlist_node *tmp; struct console *c; + int cookie; u64 seq; seq = prb_first_valid_seq(prb); - /* - * This cannot use for_each_console() because it's not established - * that the current context has console locked and neither there is - * a guarantee that there is no concurrency in that case. - * - * Open code it for documentation purposes and pretend that - * it works. - */ - hlist_for_each_entry_safe(c, tmp, &console_list, node) + + cookie = console_srcu_read_lock(); + for_each_console_srcu(c) { + /* + * If the above console_trylock() failed, this is an + * unsynchronized assignment. But in that case, the + * kernel is in "hope and pray" mode anyway. + */ c->seq = seq; + } + console_srcu_read_unlock(cookie); } console_unlock(); } |