linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: John Ogness <john.ogness@linutronix.de>
To: Petr Mladek <pmladek@suse.com>
Cc: Sergey Senozhatsky <senozhatsky@chromium.org>,
	Steven Rostedt <rostedt@goodmis.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	linux-kernel@vger.kernel.org, Miguel Ojeda <ojeda@kernel.org>,
	"Paul E. McKenney" <paulmck@kernel.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Subject: [PATCH printk v2 03/38] printk: Prepare for SRCU console list protection
Date: Wed, 19 Oct 2022 17:01:25 +0206	[thread overview]
Message-ID: <20221019145600.1282823-4-john.ogness@linutronix.de> (raw)
In-Reply-To: <20221019145600.1282823-1-john.ogness@linutronix.de>

Provide an NMI-safe SRCU protected variant to walk the console list.

Note that all console fields are now set before adding the console
to the list to avoid the console becoming visible by SCRU readers
before being fully initialized.

This is a preparatory change for a new console infrastructure which
operates independent of the console BKL.

Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 .clang-format           |  1 +
 include/linux/console.h | 28 +++++++++++++++-
 kernel/printk/printk.c  | 72 ++++++++++++++++++++++++++++++++---------
 3 files changed, 85 insertions(+), 16 deletions(-)

diff --git a/.clang-format b/.clang-format
index 1247d54f9e49..04a675b56b57 100644
--- a/.clang-format
+++ b/.clang-format
@@ -222,6 +222,7 @@ ForEachMacros:
   - 'for_each_component_dais'
   - 'for_each_component_dais_safe'
   - 'for_each_console'
+  - 'for_each_console_srcu'
   - 'for_each_cpu'
   - 'for_each_cpu_and'
   - 'for_each_cpu_not'
diff --git a/include/linux/console.h b/include/linux/console.h
index 7b5f21f9e469..cff86cc615f8 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -15,7 +15,7 @@
 #define _LINUX_CONSOLE_H_ 1
 
 #include <linux/atomic.h>
-#include <linux/list.h>
+#include <linux/rculist.h>
 #include <linux/types.h>
 
 struct vc_data;
@@ -158,8 +158,34 @@ struct console {
 	struct hlist_node node;
 };
 
+#ifdef CONFIG_LOCKDEP
+extern bool console_srcu_read_lock_is_held(void);
+#else
+static inline bool console_srcu_read_lock_is_held(void)
+{
+	return 1;
+}
+#endif
+
+extern int console_srcu_read_lock(void);
+extern void console_srcu_read_unlock(int cookie);
+
 extern struct hlist_head console_list;
 
+/**
+ * for_each_console_srcu() - Iterator over registered consoles
+ * @con:	struct console pointer used as loop cursor
+ *
+ * Although SRCU guarantees the console list will be consistent, the
+ * struct console fields may be updated by other CPUs while iterating.
+ *
+ * Requires console_srcu_read_lock to be held. Can be invoked from
+ * any context.
+ */
+#define for_each_console_srcu(con)					\
+	hlist_for_each_entry_srcu(con, &console_list, node,		\
+				  console_srcu_read_lock_is_held())
+
 /*
  * for_each_console() allows you to iterate on each console
  */
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 867becc40021..e8a56056cd50 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -85,6 +85,7 @@ EXPORT_SYMBOL(oops_in_progress);
 static DEFINE_SEMAPHORE(console_sem);
 HLIST_HEAD(console_list);
 EXPORT_SYMBOL_GPL(console_list);
+DEFINE_STATIC_SRCU(console_srcu);
 
 /*
  * System may need to suppress printk message under certain
@@ -102,6 +103,11 @@ static int __read_mostly suppress_panic_printk;
 static struct lockdep_map console_lock_dep_map = {
 	.name = "console_lock"
 };
+
+bool console_srcu_read_lock_is_held(void)
+{
+	return srcu_read_lock_held(&console_srcu);
+}
 #endif
 
 enum devkmsg_log_bits {
@@ -219,6 +225,32 @@ int devkmsg_sysctl_set_loglvl(struct ctl_table *table, int write,
 }
 #endif /* CONFIG_PRINTK && CONFIG_SYSCTL */
 
+/**
+ * console_srcu_read_lock - Register a new reader for the
+ *	SRCU-protected console list
+ *
+ * Use for_each_console_srcu() to iterate the console list
+ *
+ * Context: Any context.
+ */
+int console_srcu_read_lock(void)
+{
+	return srcu_read_lock_nmisafe(&console_srcu);
+}
+EXPORT_SYMBOL(console_srcu_read_lock);
+
+/**
+ * console_srcu_read_unlock - Unregister an old reader from
+ *	the SRCU-protected console list
+ *
+ * Counterpart to console_srcu_read_lock()
+ */
+void console_srcu_read_unlock(int cookie)
+{
+	srcu_read_unlock_nmisafe(&console_srcu, cookie);
+}
+EXPORT_SYMBOL(console_srcu_read_unlock);
+
 /*
  * Helper macros to handle lockdep when locking/unlocking console_sem. We use
  * macros instead of functions so that _RET_IP_ contains useful information.
@@ -2989,6 +3021,9 @@ void console_stop(struct console *console)
 	console_lock();
 	console->flags &= ~CON_ENABLED;
 	console_unlock();
+
+	/* Ensure that all SRCU list walks have completed */
+	synchronize_srcu(&console_srcu);
 }
 EXPORT_SYMBOL(console_stop);
 
@@ -3179,6 +3214,17 @@ void register_console(struct console *newcon)
 		newcon->flags &= ~CON_PRINTBUFFER;
 	}
 
+	newcon->dropped = 0;
+	if (newcon->flags & CON_PRINTBUFFER) {
+		/* Get a consistent copy of @syslog_seq. */
+		mutex_lock(&syslog_lock);
+		newcon->seq = syslog_seq;
+		mutex_unlock(&syslog_lock);
+	} else {
+		/* Begin with next message. */
+		newcon->seq = prb_next_seq(prb);
+	}
+
 	/*
 	 * Put this console in the list - keep the
 	 * preferred driver at the head of the list.
@@ -3187,28 +3233,20 @@ void register_console(struct console *newcon)
 	if (hlist_empty(&console_list)) {
 		/* Ensure CON_CONSDEV is always set for the head. */
 		newcon->flags |= CON_CONSDEV;
-		hlist_add_head(&newcon->node, &console_list);
+		hlist_add_head_rcu(&newcon->node, &console_list);
 
 	} else if (newcon->flags & CON_CONSDEV) {
 		/* Only the new head can have CON_CONSDEV set. */
 		console_first()->flags &= ~CON_CONSDEV;
-		hlist_add_head(&newcon->node, &console_list);
+		hlist_add_head_rcu(&newcon->node, &console_list);
 
 	} else {
-		hlist_add_behind(&newcon->node, console_list.first);
-	}
-
-	newcon->dropped = 0;
-	if (newcon->flags & CON_PRINTBUFFER) {
-		/* Get a consistent copy of @syslog_seq. */
-		mutex_lock(&syslog_lock);
-		newcon->seq = syslog_seq;
-		mutex_unlock(&syslog_lock);
-	} else {
-		/* Begin with next message. */
-		newcon->seq = prb_next_seq(prb);
+		hlist_add_behind_rcu(&newcon->node, console_list.first);
 	}
 	console_unlock();
+
+	/* No need to synchronize SRCU here! */
+
 	console_sysfs_notify();
 
 	/*
@@ -3254,7 +3292,7 @@ int unregister_console(struct console *console)
 		goto out_unlock;
 	}
 
-	hlist_del_init(&console->node);
+	hlist_del_init_rcu(&console->node);
 
 	/*
 	 * <HISTORICAL>
@@ -3269,6 +3307,10 @@ int unregister_console(struct console *console)
 		console_first()->flags |= CON_CONSDEV;
 
 	console_unlock();
+
+	/* Ensure that all SRCU list walks have completed */
+	synchronize_srcu(&console_srcu);
+
 	console_sysfs_notify();
 
 	if (console->exit)
-- 
2.30.2


  parent reply	other threads:[~2022-10-19 15:03 UTC|newest]

Thread overview: 129+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-19 14:55 [PATCH printk v2 00/38] reduce console_lock scope John Ogness
2022-10-19 14:55 ` [PATCH printk v2 01/38] serial: kgdboc: Lock console list in probe function John Ogness
2022-10-19 15:41   ` Greg Kroah-Hartman
2022-10-24  5:22   ` Sergey Senozhatsky
2022-10-25  0:34   ` Doug Anderson
2022-10-19 14:55 ` [PATCH printk v2 02/38] printk: Convert console_drivers list to hlist John Ogness
2022-10-19 15:44   ` Greg Kroah-Hartman
2022-10-19 21:46     ` John Ogness
2022-10-20  7:43       ` Greg Kroah-Hartman
2022-10-20 12:36   ` Petr Mladek
2022-10-24  5:23   ` Sergey Senozhatsky
2022-10-19 14:55 ` John Ogness [this message]
2022-10-19 15:16   ` [PATCH printk v2 03/38] printk: Prepare for SRCU console list protection Miguel Ojeda
2022-10-19 17:12   ` Paul E. McKenney
2022-10-21  8:34   ` Petr Mladek
2022-10-31 13:06     ` John Ogness
2022-10-31 14:09       ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 04/38] printk: introduce console_is_enabled() wrapper John Ogness
2022-10-19 16:01   ` Greg Kroah-Hartman
2022-10-21  8:57   ` Petr Mladek
2022-10-21  9:37     ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 05/38] printk: use console_is_enabled() John Ogness
2022-10-21  9:25   ` Petr Mladek
2022-10-31 15:39     ` John Ogness
2022-10-19 14:55 ` [PATCH printk v2 06/38] tty: nfcon: " John Ogness
2022-10-21  9:55   ` Petr Mladek
2022-10-31 15:59     ` John Ogness
2022-11-01  8:57       ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 07/38] um: kmsg_dump: " John Ogness
2022-10-21 12:46   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 08/38] efi: earlycon: " John Ogness
2022-10-19 15:32   ` Ard Biesheuvel
2022-10-21 12:53   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 09/38] netconsole: " John Ogness
2022-10-21 13:14   ` Petr Mladek
2022-11-04 15:12     ` John Ogness
2022-10-19 14:55 ` [PATCH printk v2 10/38] tty: hvc: " John Ogness
2022-10-19 16:01   ` Greg Kroah-Hartman
2022-10-21 13:22   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 11/38] tty: serial: earlycon: " John Ogness
2022-10-19 16:01   ` Greg Kroah-Hartman
2022-10-21 13:51   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 12/38] tty: serial: kgdboc: " John Ogness
2022-10-19 16:00   ` Greg Kroah-Hartman
2022-10-21 14:10   ` Petr Mladek
2022-10-24 22:46   ` Doug Anderson
2022-10-25  0:49     ` Doug Anderson
2022-10-25 11:28       ` John Ogness
2022-11-04 16:23         ` John Ogness
2022-11-07  8:47           ` Petr Mladek
2022-11-07  9:45             ` John Ogness
2022-10-19 14:55 ` [PATCH printk v2 13/38] tty: serial: pic32_uart: " John Ogness
2022-10-19 16:01   ` Greg Kroah-Hartman
2022-10-21 14:11   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 14/38] tty: serial: samsung_tty: " John Ogness
2022-10-19 16:00   ` Greg Kroah-Hartman
2022-10-21 14:14   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 15/38] tty: serial: serial_core: " John Ogness
2022-10-19 16:00   ` Greg Kroah-Hartman
2022-10-21 14:14   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 16/38] tty: serial: xilinx_uartps: " John Ogness
2022-10-19 16:01   ` Greg Kroah-Hartman
2022-10-21 14:23   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 17/38] tty: tty_io: " John Ogness
2022-10-19 16:00   ` Greg Kroah-Hartman
2022-10-21 14:24   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 18/38] usb: early: xhci-dbc: " John Ogness
2022-10-19 16:01   ` Greg Kroah-Hartman
2022-10-21 14:27   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 19/38] kdb: kdb_io: " John Ogness
2022-10-21 14:28   ` Petr Mladek
2022-10-25  0:34   ` Doug Anderson
2022-10-19 14:55 ` [PATCH printk v2 20/38] um: kmsg_dumper: use srcu console list iterator John Ogness
2022-10-21 14:56   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 21/38] serial: kgdboc: " John Ogness
2022-10-19 16:02   ` Greg Kroah-Hartman
2022-10-21 15:09   ` Petr Mladek
2022-10-25  0:33     ` Doug Anderson
2022-10-19 14:55 ` [PATCH printk v2 22/38] serial: kgdboc: document console_lock usage John Ogness
2022-10-20  7:42   ` Greg Kroah-Hartman
2022-10-25  0:36   ` Doug Anderson
2022-10-25 10:09   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 23/38] tty: tty_io: " John Ogness
2022-10-20  7:43   ` Greg Kroah-Hartman
2022-10-25 13:31   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 24/38] xen: fbfront: use srcu console list iterator John Ogness
2022-10-25 13:39   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 25/38] proc: consoles: document console_lock usage John Ogness
2022-10-25 14:40   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 26/38] kdb: use srcu console list iterator John Ogness
2022-10-25  0:47   ` Doug Anderson
2022-10-25 14:59     ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 27/38] printk: console_flush_all: " John Ogness
2022-10-25 15:17   ` Petr Mladek
2022-11-07  0:00     ` John Ogness
2022-11-07 13:03       ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 28/38] printk: console_unblank: " John Ogness
2022-10-25 15:28   ` Petr Mladek
2022-10-25 15:31   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 29/38] printk: console_flush_on_panic: " John Ogness
2022-10-25 15:32   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 30/38] printk: console_device: " John Ogness
2022-10-25 15:35   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 31/38] printk: register_console: " John Ogness
2022-10-26  8:20   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 32/38] printk: __pr_flush: " John Ogness
2022-10-26  8:33   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 33/38] printk: introduce console_list_lock John Ogness
2022-10-20  7:53   ` Greg Kroah-Hartman
2022-10-27 10:09   ` Petr Mladek
2022-10-27 18:50     ` Paul E. McKenney
2022-10-28 18:09       ` Boqun Feng
2022-10-28 18:42         ` Paul E. McKenney
2022-11-07 10:10       ` John Ogness
2022-11-07 16:16         ` Paul E. McKenney
2022-10-19 14:55 ` [PATCH printk v2 34/38] serial: kgdboc: use console_list_lock instead of console_lock John Ogness
2022-10-20  7:52   ` Greg Kroah-Hartman
2022-10-27 10:13   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 35/38] tty: tty_io: use console_list_lock for list synchronization John Ogness
2022-10-20  7:43   ` Greg Kroah-Hartman
2022-10-27 10:17   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 36/38] proc: consoles: use console_list_lock for list iteration John Ogness
2022-10-27 12:02   ` Petr Mladek
2022-10-19 14:55 ` [PATCH printk v2 37/38] printk: relieve console_lock of list synchronization duties John Ogness
2022-10-27 12:40   ` Petr Mladek
2022-10-19 14:56 ` [PATCH printk v2 38/38] printk, xen: fbfront: create/use safe function for forcing preferred John Ogness
2022-10-27 13:18   ` Petr Mladek
2022-10-27 13:35     ` John Ogness
2022-10-27 14:27       ` Petr Mladek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20221019145600.1282823-4-john.ogness@linutronix.de \
    --to=john.ogness@linutronix.de \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ojeda@kernel.org \
    --cc=paulmck@kernel.org \
    --cc=pmladek@suse.com \
    --cc=rostedt@goodmis.org \
    --cc=senozhatsky@chromium.org \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).