summaryrefslogtreecommitdiffstats
path: root/kernel/printk
diff options
context:
space:
mode:
authorJohn Ogness <john.ogness@linutronix.de>2022-11-16 17:21:31 +0100
committerPetr Mladek <pmladek@suse.com>2022-12-02 11:25:01 +0100
commit87f2e4b7d9e5c50756184b4f8d0b92680de61496 (patch)
tree11258aabf266bf5614213aa675fe6252088e16ba /kernel/printk
parentprintk: console_unblank: use srcu console list iterator (diff)
downloadlinux-87f2e4b7d9e5c50756184b4f8d0b92680de61496.tar.xz
linux-87f2e4b7d9e5c50756184b4f8d0b92680de61496.zip
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
Diffstat (limited to 'kernel/printk')
-rw-r--r--kernel/printk/printk.c21
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();
}