linux-parisc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH printk 00/18] preparation for threaded/atomic printing
@ 2022-09-24  0:04 John Ogness
  2022-09-24  0:04 ` [PATCH printk 08/18] parisc: Put console abuse into one place John Ogness
                   ` (4 more replies)
  0 siblings, 5 replies; 17+ messages in thread
From: John Ogness @ 2022-09-24  0:04 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, linux-fsdevel, Greg Kroah-Hartman, Jiri Slaby,
	James E.J. Bottomley, Helge Deller, Sven Schnelle,
	John David Anglin, Eric W. Biederman, Julia Lawall, linux-parisc,
	Jason Wessel, Daniel Thompson, Douglas Anderson, kgdb-bugreport,
	linux-serial, Aaron Tomlin, Luis Chamberlain

Hi,

This series is essentially the first 18 patches of tglx's RFC series
[0] with only minor changes in comments and commit messages. It's
purpose is to lay the groundwork for the upcoming threaded/atomic
console printing posted as the RFC series and demonstrated at
LPC2022 [1].

This series is interesting for mainline because it cleans up various
code and documentation quirks discovered while working on the new
console printing implementation.

Aside from cleanups, the main features introduced here are:

- Converts the console's DIY linked list implementation to hlist.

- Introduces a console list lock (mutex) so that readers (such as
  /proc/consoles) can safely iterate the consoles without blocking
  console printing.

- Adds SRCU support to the console list to prepare for safe console
  list iterating from any context.

- Refactors buffer handling to prepare for per-console, per-cpu,
  per-context atomic printing.

The series has the following parts:

   Patches  1 - 5:   Cleanups

   Patches  6 - 12:  Locking and list conversion

   Patches 13 - 18:  Improved output buffer handling to prepare for
                     code sharing

John Ogness

[0] https://lore.kernel.org/lkml/20220910221947.171557773@linutronix.de
[1] https://lore.kernel.org/lkml/875yheqh6v.fsf@jogness.linutronix.de

Thomas Gleixner (18):
  printk: Make pr_flush() static
  printk: Declare log_wait properly
  printk: Remove write only variable nr_ext_console_drivers
  printk: Remove bogus comment vs. boot consoles
  printk: Mark __printk percpu data ready __ro_after_init
  printk: Protect [un]register_console() with a mutex
  printk: Convert console list walks for readers to list lock
  parisc: Put console abuse into one place
  serial: kgdboc: Lock console list in probe function
  kgbd: Pretend that console list walk is safe
  printk: Convert console_drivers list to hlist
  printk: Prepare for SCRU console list protection
  printk: Move buffer size defines
  printk: Document struct console
  printk: Add struct cons_text_buf
  printk: Use struct cons_text_buf
  printk: Use an output descriptor struct for emit
  printk: Handle dropped message smarter

 arch/parisc/include/asm/pdc.h |   2 +-
 arch/parisc/kernel/pdc_cons.c |  55 +++--
 arch/parisc/kernel/traps.c    |  17 +-
 drivers/tty/serial/kgdboc.c   |   9 +-
 drivers/tty/tty_io.c          |   6 +-
 fs/proc/consoles.c            |  11 +-
 fs/proc/kmsg.c                |   2 -
 include/linux/console.h       | 197 +++++++++++++---
 include/linux/printk.h        |   9 -
 include/linux/syslog.h        |   3 +
 kernel/debug/kdb/kdb_io.c     |   7 +-
 kernel/printk/printk.c        | 414 ++++++++++++++++++++++------------
 12 files changed, 499 insertions(+), 233 deletions(-)


base-commit: dc453dd89daacdc0da6d66234aa27e417df7edcd
-- 
2.30.2


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH printk 08/18] parisc: Put console abuse into one place
  2022-09-24  0:04 [PATCH printk 00/18] preparation for threaded/atomic printing John Ogness
@ 2022-09-24  0:04 ` John Ogness
  2022-09-24  0:20   ` Steven Rostedt
  2022-09-30  7:54   ` Petr Mladek
  2022-09-24  0:04 ` [PATCH printk 11/18] printk: Convert console_drivers list to hlist John Ogness
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 17+ messages in thread
From: John Ogness @ 2022-09-24  0:04 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, James E.J. Bottomley, Helge Deller, Sven Schnelle,
	John David Anglin, Eric W. Biederman, Julia Lawall, linux-parisc

From: Thomas Gleixner <tglx@linutronix.de>

PARISC has a hope based mechanism to restore consoles in case of a HPMC
(machine check exception) which is scattered over several places.

Move it into one place to make further changes simpler and add comments.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: John Ogness <john.ogness@linutronix.de>
Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org>
---
 arch/parisc/include/asm/pdc.h |  2 +-
 arch/parisc/kernel/pdc_cons.c | 38 ++++++++++++++++++++++++++++-------
 arch/parisc/kernel/traps.c    | 17 +++++-----------
 3 files changed, 37 insertions(+), 20 deletions(-)

diff --git a/arch/parisc/include/asm/pdc.h b/arch/parisc/include/asm/pdc.h
index b643092d4b98..12bffd8a5d05 100644
--- a/arch/parisc/include/asm/pdc.h
+++ b/arch/parisc/include/asm/pdc.h
@@ -20,7 +20,7 @@ extern unsigned long parisc_pat_pdc_cap; /* PDC capabilities (PAT) */
 #define PDC_TYPE_SNAKE		 2 /* Doesn't support SYSTEM_MAP */
 
 void pdc_console_init(void);	/* in pdc_console.c */
-void pdc_console_restart(void);
+void pdc_console_restart(bool hpmc);
 
 void setup_pdc(void);		/* in inventory.c */
 
diff --git a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c
index 2661cdd256ae..9a0c0932d2f9 100644
--- a/arch/parisc/kernel/pdc_cons.c
+++ b/arch/parisc/kernel/pdc_cons.c
@@ -237,20 +237,44 @@ void __init pdc_console_init(void)
 
 
 /*
- * Used for emergencies. Currently only used if an HPMC occurs. If an
- * HPMC occurs, it is possible that the current console may not be
- * properly initialised after the PDC IO reset. This routine unregisters
- * all of the current consoles, reinitializes the pdc console and
- * registers it.
+ * <Historical comments>
+ *
+ * Used for emergencies.
+ *
+ *  - If an HPMC occurs, it is possible that the current console may not be
+ *    properly initialised after the PDC IO reset. This routine unregisters
+ *    all of the current consoles, reinitializes the pdc console and registers
+ *    it.
+ *
+ *  - Maybe the kernel hasn't booted very far yet and hasn't been able
+ *    to initialize the serial or STI console. In that case we should
+ *    re-enable the pdc console, so that the user will be able to
+ *    identify the problem.
+ *
+ * </Historical comments>
+ *
+ * The above is all wishful thinking:
+ *
+ *  - Invoking [un]register_console() from exception contexts is obviously
+ *    unsafe.
+ *
+ *  - If the HPMC left the machine in unpleasant state and the pdc console
+ *    was already initialized, but later removed due to CON_BOOT then this
+ *    will do nothing.
+ *
+ * Pretend that any of the below works in the same way as we pretend that
+ * any of PARISC works.
  */
-
-void pdc_console_restart(void)
+void pdc_console_restart(bool hpmc)
 {
 	struct console *console;
 
 	if (pdc_console_initialized)
 		return;
 
+	if (!hpmc && console_drivers)
+		return;
+
 	/* If we've already seen the output, don't bother to print it again */
 	if (console_drivers != NULL)
 		pdc_cons.flags &= ~CON_PRINTBUFFER;
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
index b78f1b9d45c1..81e23f589d3d 100644
--- a/arch/parisc/kernel/traps.c
+++ b/arch/parisc/kernel/traps.c
@@ -235,17 +235,12 @@ void die_if_kernel(char *str, struct pt_regs *regs, long err)
 			"                 (__)\\       )\\/\\\n"
 			"                  U  ||----w |\n"
 			"                     ||     ||\n");
-	
+
 	/* unlock the pdc lock if necessary */
 	pdc_emergency_unlock();
 
-	/* maybe the kernel hasn't booted very far yet and hasn't been able 
-	 * to initialize the serial or STI console. In that case we should 
-	 * re-enable the pdc console, so that the user will be able to 
-	 * identify the problem. */
-	if (!console_drivers)
-		pdc_console_restart();
-	
+	pdc_console_restart(false);
+
 	if (err)
 		printk(KERN_CRIT "%s (pid %d): %s (code %ld)\n",
 			current->comm, task_pid_nr(current), str, err);
@@ -429,9 +424,7 @@ void parisc_terminate(char *msg, struct pt_regs *regs, int code, unsigned long o
 	/* unlock the pdc lock if necessary */
 	pdc_emergency_unlock();
 
-	/* restart pdc console if necessary */
-	if (!console_drivers)
-		pdc_console_restart();
+	pdc_console_restart(false);
 
 	/* Not all paths will gutter the processor... */
 	switch(code){
@@ -483,7 +476,7 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
 	int si_code;
 
 	if (code == 1)
-	    pdc_console_restart();  /* switch back to pdc if HPMC */
+	    pdc_console_restart(true);  /* switch back to pdc if HPMC */
 	else if (!irqs_disabled_flags(regs->gr[0]))
 	    local_irq_enable();
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH printk 11/18] printk: Convert console_drivers list to hlist
  2022-09-24  0:04 [PATCH printk 00/18] preparation for threaded/atomic printing John Ogness
  2022-09-24  0:04 ` [PATCH printk 08/18] parisc: Put console abuse into one place John Ogness
@ 2022-09-24  0:04 ` John Ogness
  2022-09-24 10:53   ` Sergey Senozhatsky
                     ` (3 more replies)
  2022-09-24  6:44 ` [PATCH printk 00/18] preparation for threaded/atomic printing Greg Kroah-Hartman
                   ` (2 subsequent siblings)
  4 siblings, 4 replies; 17+ messages in thread
From: John Ogness @ 2022-09-24  0:04 UTC (permalink / raw)
  To: Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, James E.J. Bottomley, Helge Deller,
	Greg Kroah-Hartman, linux-parisc, linux-fsdevel

From: Thomas Gleixner <tglx@linutronix.de>

Replace the open coded single linked list with a hlist so a conversion to
SRCU protected list walks can reuse the existing primitives.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: John Ogness <john.ogness@linutronix.de>
---
 arch/parisc/kernel/pdc_cons.c | 19 +++----
 fs/proc/consoles.c            |  5 +-
 include/linux/console.h       | 15 ++++--
 kernel/printk/printk.c        | 99 +++++++++++++++++++----------------
 4 files changed, 75 insertions(+), 63 deletions(-)

diff --git a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c
index 9a0c0932d2f9..3f9abf0263ee 100644
--- a/arch/parisc/kernel/pdc_cons.c
+++ b/arch/parisc/kernel/pdc_cons.c
@@ -147,13 +147,8 @@ static int __init pdc_console_tty_driver_init(void)
 
 	struct console *tmp;
 
-	console_lock();
-	for_each_console(tmp)
-		if (tmp == &pdc_cons)
-			break;
-	console_unlock();
-
-	if (!tmp) {
+	/* Pretend that this works as much as it pretended to work historically */
+	if (hlist_unhashed_lockless(&pdc_cons.node)) {
 		printk(KERN_INFO "PDC console driver not registered anymore, not creating %s\n", pdc_cons.name);
 		return -ENODEV;
 	}
@@ -272,15 +267,17 @@ void pdc_console_restart(bool hpmc)
 	if (pdc_console_initialized)
 		return;
 
-	if (!hpmc && console_drivers)
+	if (!hpmc && !hlist_empty(&console_list))
 		return;
 
 	/* If we've already seen the output, don't bother to print it again */
-	if (console_drivers != NULL)
+	if (!hlist_empty(&console_list))
 		pdc_cons.flags &= ~CON_PRINTBUFFER;
 
-	while ((console = console_drivers) != NULL)
-		unregister_console(console_drivers);
+	while (!hlist_empty(&console_list)) {
+		unregister_console(READ_ONCE(hlist_entry(console_list.first,
+							 struct console, node)));
+	}
 
 	/* force registering the pdc console */
 	pdc_console_init_force();
diff --git a/fs/proc/consoles.c b/fs/proc/consoles.c
index 6775056eecd5..70994d1e52f6 100644
--- a/fs/proc/consoles.c
+++ b/fs/proc/consoles.c
@@ -74,8 +74,11 @@ static void *c_start(struct seq_file *m, loff_t *pos)
 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
 {
 	struct console *con = v;
+
 	++*pos;
-	return con->next;
+	hlist_for_each_entry_continue(con, node)
+		break;
+	return con;
 }
 
 static void c_stop(struct seq_file *m, void *v)
diff --git a/include/linux/console.h b/include/linux/console.h
index 86a6125512b9..1e3d0a50cef1 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -15,6 +15,7 @@
 #define _LINUX_CONSOLE_H_ 1
 
 #include <linux/atomic.h>
+#include <linux/list.h>
 #include <linux/types.h>
 
 struct vc_data;
@@ -154,15 +155,19 @@ struct console {
 	u64	seq;
 	unsigned long dropped;
 	void	*data;
-	struct	 console *next;
+	struct hlist_node node;
 };
 
 #ifdef CONFIG_LOCKDEP
+extern void lockdep_assert_console_lock_held(void);
 extern void lockdep_assert_console_list_lock_held(void);
 #else
+static inline void lockdep_assert_console_lock_held(void) { }
 static inline void lockdep_assert_console_list_lock_held(void) { }
 #endif
 
+extern struct hlist_head console_list;
+
 extern void console_list_lock(void) __acquires(console_mutex);
 extern void console_list_unlock(void) __releases(console_mutex);
 
@@ -175,7 +180,7 @@ extern void console_list_unlock(void) __releases(console_mutex);
  */
 #define for_each_registered_console(con)				\
 	lockdep_assert_console_list_lock_held();			\
-	for (con = console_drivers; con != NULL; con = con->next)
+	hlist_for_each_entry(con, &console_list, node)
 
 /**
  * for_each_console() - Iterator over registered consoles
@@ -185,7 +190,8 @@ extern void console_list_unlock(void) __releases(console_mutex);
  * list is immutable.
  */
 #define for_each_console(con)						\
-	for (con = console_drivers; con != NULL; con = con->next)
+	lockdep_assert_console_lock_held();				\
+	hlist_for_each_entry(con, &console_list, node)
 
 /**
  * for_each_console_kgdb() - Iterator over registered consoles for KGDB
@@ -195,7 +201,7 @@ extern void console_list_unlock(void) __releases(console_mutex);
  * Don't use outside of the KGDB fairy tale land!
  */
 #define for_each_console_kgdb(con)					\
-	for (con = console_drivers; con != NULL; con = con->next)
+	hlist_for_each_entry(con, &console_list, node)
 
 extern int console_set_on_cmdline;
 extern struct console *early_console;
@@ -208,7 +214,6 @@ enum con_flush_mode {
 extern int add_preferred_console(char *name, int idx, char *options);
 extern void register_console(struct console *);
 extern int unregister_console(struct console *);
-extern struct console *console_drivers;
 extern void console_lock(void);
 extern int console_trylock(void);
 extern void console_unlock(void);
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 80a728ef9d96..f1d31dcbd6ba 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -79,20 +79,20 @@ int oops_in_progress;
 EXPORT_SYMBOL(oops_in_progress);
 
 /*
- * console_sem protects the console_drivers list, and also provides
- * serialization for access to the entire console driver system.
+ * console_sem protects onsole_list, and also provides serialization for
+ * access to the entire console driver system.
  *
  * console_mutex serializes register/unregister.
  *
  * console_sem must be taken inside a console_mutex locked section
- * for any list manipulation in order to keep the console BKL
+ * for any console_list manipulation in order to keep the console BKL
  * machinery happy. This requirement also applies to manipulation
  * of console->flags.
  */
 static DEFINE_MUTEX(console_mutex);
 static DEFINE_SEMAPHORE(console_sem);
-struct console *console_drivers;
-EXPORT_SYMBOL_GPL(console_drivers);
+HLIST_HEAD(console_list);
+EXPORT_SYMBOL_GPL(console_list);
 
 /*
  * System may need to suppress printk message under certain
@@ -111,6 +111,11 @@ static struct lockdep_map console_lock_dep_map = {
 	.name = "console_lock"
 };
 
+void lockdep_assert_console_lock_held(void)
+{
+	lockdep_assert(lock_is_held(&console_lock_dep_map));
+}
+
 void lockdep_assert_console_list_lock_held(void)
 {
 	lockdep_assert_held(&console_mutex);
@@ -2591,7 +2596,7 @@ static int console_cpu_notify(unsigned int cpu)
  * console_lock - lock the console system for exclusive use.
  *
  * Acquires a lock which guarantees that the caller has
- * exclusive access to the console system and the console_drivers list.
+ * exclusive access to the console system and console_list.
  *
  * Can sleep, returns nothing.
  */
@@ -2611,7 +2616,7 @@ EXPORT_SYMBOL(console_lock);
  * console_trylock - try to lock the console system for exclusive use.
  *
  * Try to acquire a lock which guarantees that the caller has exclusive
- * access to the console system and the console_drivers list.
+ * access to the console system and console_list.
  *
  * returns 1 on success, and 0 on failure to acquire the lock.
  */
@@ -2979,7 +2984,15 @@ void console_flush_on_panic(enum con_flush_mode mode)
 		u64 seq;
 
 		seq = prb_first_valid_seq(prb);
-		for_each_console(c)
+		/*
+		 * 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(c, &console_list, node)
 			c->seq = seq;
 	}
 	console_unlock();
@@ -3120,6 +3133,9 @@ static void try_enable_default_console(struct console *newcon)
 	       (con->flags & CON_BOOT) ? "boot" : "",	\
 	       con->name, con->index, ##__VA_ARGS__)
 
+#define cons_first()					\
+	hlist_entry(console_list.first, struct console, node)
+
 static int console_unregister_locked(struct console *console);
 
 /*
@@ -3182,8 +3198,8 @@ void register_console(struct console *newcon)
 	 * flag set and will be first in the list.
 	 */
 	if (preferred_console < 0) {
-		if (!console_drivers || !console_drivers->device ||
-		    console_drivers->flags & CON_BOOT) {
+		if (hlist_empty(&console_list) || !cons_first()->device ||
+		    cons_first()->flags & CON_BOOT) {
 			try_enable_default_console(newcon);
 		}
 	}
@@ -3211,21 +3227,17 @@ void register_console(struct console *newcon)
 	}
 
 	/*
-	 *	Put this console in the list - keep the
-	 *	preferred driver at the head of the list.
+	 * Put this console in the list and keep the referred driver at the
+	 * head of the list.
 	 */
 	console_lock();
-	if ((newcon->flags & CON_CONSDEV) || console_drivers == NULL) {
-		newcon->next = console_drivers;
-		console_drivers = newcon;
-		if (newcon->next)
-			newcon->next->flags &= ~CON_CONSDEV;
-		/* Ensure this flag is always set for the head of the list */
-		newcon->flags |= CON_CONSDEV;
-	} else {
-		newcon->next = console_drivers->next;
-		console_drivers->next = newcon;
-	}
+	if (newcon->flags & CON_CONSDEV || hlist_empty(&console_list))
+		hlist_add_head(&newcon->node, &console_list);
+	else
+		hlist_add_behind(&newcon->node, console_list.first);
+
+	/* Ensure this flag is always set for the head of the list */
+	cons_first()->flags |= CON_CONSDEV;
 
 	newcon->dropped = 0;
 	if (newcon->flags & CON_PRINTBUFFER) {
@@ -3251,7 +3263,9 @@ void register_console(struct console *newcon)
 	if (bootcon_enabled &&
 	    ((newcon->flags & (CON_CONSDEV | CON_BOOT)) == CON_CONSDEV) &&
 	    !keep_bootcon) {
-		for_each_console(con) {
+		struct hlist_node *tmp;
+
+		hlist_for_each_entry_safe(con, tmp, &console_list, node) {
 			if (con->flags & CON_BOOT)
 				console_unregister_locked(con);
 		}
@@ -3263,7 +3277,6 @@ EXPORT_SYMBOL(register_console);
 
 static int console_unregister_locked(struct console *console)
 {
-	struct console *con;
 	int res;
 
 	con_printk(KERN_INFO, console, "disabled\n");
@@ -3274,32 +3287,28 @@ static int console_unregister_locked(struct console *console)
 	if (res > 0)
 		return 0;
 
-	res = -ENODEV;
 	console_lock();
-	if (console_drivers == console) {
-		console_drivers=console->next;
-		res = 0;
-	} else {
-		for_each_console(con) {
-			if (con->next == console) {
-				con->next = console->next;
-				res = 0;
-				break;
-			}
-		}
-	}
 
-	if (res)
-		goto out_disable_unlock;
+	/* Disable it unconditionally */
+	console->flags &= ~CON_ENABLED;
+
+	if (hlist_unhashed(&console->node))
+		goto out_unlock;
+
+	hlist_del_init(&console->node);
 
 	/*
+	 * <HISTORICAL>
 	 * If this isn't the last console and it has CON_CONSDEV set, we
 	 * need to set it on the next preferred console.
+	 * </HISTORICAL>
+	 *
+	 * The above makes no sense as there is no guarantee that the next
+	 * console has any device attached. Oh well....
 	 */
-	if (console_drivers != NULL && console->flags & CON_CONSDEV)
-		console_drivers->flags |= CON_CONSDEV;
+	if (!hlist_empty(&console_list) && console->flags & CON_CONSDEV)
+		cons_first()->flags |= CON_CONSDEV;
 
-	console->flags &= ~CON_ENABLED;
 	console_unlock();
 	console_sysfs_notify();
 
@@ -3308,10 +3317,8 @@ static int console_unregister_locked(struct console *console)
 
 	return res;
 
-out_disable_unlock:
-	console->flags &= ~CON_ENABLED;
+out_unlock:
 	console_unlock();
-
 	return res;
 }
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH printk 08/18] parisc: Put console abuse into one place
  2022-09-24  0:04 ` [PATCH printk 08/18] parisc: Put console abuse into one place John Ogness
@ 2022-09-24  0:20   ` Steven Rostedt
  2022-09-30  7:54   ` Petr Mladek
  1 sibling, 0 replies; 17+ messages in thread
From: Steven Rostedt @ 2022-09-24  0:20 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Thomas Gleixner, linux-kernel,
	James E.J. Bottomley, Helge Deller, Sven Schnelle,
	John David Anglin, Eric W. Biederman, Julia Lawall, linux-parisc

On Sat, 24 Sep 2022 02:10:44 +0206
John Ogness <john.ogness@linutronix.de> (on behalf of Thomas Gleixner) wrote:

> + * Pretend that any of the below works in the same way as we pretend that
> + * any of PARISC works.

Not approving of what PARISC did here?

  ;-)

-- Steve

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH printk 00/18] preparation for threaded/atomic printing
  2022-09-24  0:04 [PATCH printk 00/18] preparation for threaded/atomic printing John Ogness
  2022-09-24  0:04 ` [PATCH printk 08/18] parisc: Put console abuse into one place John Ogness
  2022-09-24  0:04 ` [PATCH printk 11/18] printk: Convert console_drivers list to hlist John Ogness
@ 2022-09-24  6:44 ` Greg Kroah-Hartman
  2022-09-25 15:23   ` John Ogness
  2022-09-24  9:47 ` Sergey Senozhatsky
  2022-09-29 16:33 ` Petr Mladek
  4 siblings, 1 reply; 17+ messages in thread
From: Greg Kroah-Hartman @ 2022-09-24  6:44 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, linux-fsdevel, Jiri Slaby, James E.J. Bottomley,
	Helge Deller, Sven Schnelle, John David Anglin,
	Eric W. Biederman, Julia Lawall, linux-parisc, Jason Wessel,
	Daniel Thompson, Douglas Anderson, kgdb-bugreport, linux-serial,
	Aaron Tomlin, Luis Chamberlain

On Sat, Sep 24, 2022 at 02:10:36AM +0206, John Ogness wrote:
> Hi,
> 
> This series is essentially the first 18 patches of tglx's RFC series
> [0] with only minor changes in comments and commit messages. It's
> purpose is to lay the groundwork for the upcoming threaded/atomic
> console printing posted as the RFC series and demonstrated at
> LPC2022 [1].
> 
> This series is interesting for mainline because it cleans up various
> code and documentation quirks discovered while working on the new
> console printing implementation.
> 
> Aside from cleanups, the main features introduced here are:
> 
> - Converts the console's DIY linked list implementation to hlist.
> 
> - Introduces a console list lock (mutex) so that readers (such as
>   /proc/consoles) can safely iterate the consoles without blocking
>   console printing.
> 
> - Adds SRCU support to the console list to prepare for safe console
>   list iterating from any context.
> 
> - Refactors buffer handling to prepare for per-console, per-cpu,
>   per-context atomic printing.
> 
> The series has the following parts:
> 
>    Patches  1 - 5:   Cleanups
> 
>    Patches  6 - 12:  Locking and list conversion
> 
>    Patches 13 - 18:  Improved output buffer handling to prepare for
>                      code sharing
> 

These all look great to me, thanks for resending them.

Do you want them to go through my serial/tty tree, or is there some
other tree to take them through (printk?)

If they are to go through someone else's tree, feel free to add:

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH printk 00/18] preparation for threaded/atomic printing
  2022-09-24  0:04 [PATCH printk 00/18] preparation for threaded/atomic printing John Ogness
                   ` (2 preceding siblings ...)
  2022-09-24  6:44 ` [PATCH printk 00/18] preparation for threaded/atomic printing Greg Kroah-Hartman
@ 2022-09-24  9:47 ` Sergey Senozhatsky
  2022-09-29 16:33 ` Petr Mladek
  4 siblings, 0 replies; 17+ messages in thread
From: Sergey Senozhatsky @ 2022-09-24  9:47 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, linux-fsdevel, Greg Kroah-Hartman, Jiri Slaby,
	James E.J. Bottomley, Helge Deller, Sven Schnelle,
	John David Anglin, Eric W. Biederman, Julia Lawall, linux-parisc,
	Jason Wessel, Daniel Thompson, Douglas Anderson, kgdb-bugreport,
	linux-serial, Aaron Tomlin, Luis Chamberlain

On (22/09/24 02:10), John Ogness wrote:
> 
>    Patches  6 - 12:  Locking and list conversion
> 

A quick question: I wonder why xenfb_make_preferred_console() isn't
converted to list lock and for_each_registered_console()?

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH printk 11/18] printk: Convert console_drivers list to hlist
  2022-09-24  0:04 ` [PATCH printk 11/18] printk: Convert console_drivers list to hlist John Ogness
@ 2022-09-24 10:53   ` Sergey Senozhatsky
  2022-09-24 17:20   ` Helge Deller
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 17+ messages in thread
From: Sergey Senozhatsky @ 2022-09-24 10:53 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, James E.J. Bottomley, Helge Deller,
	Greg Kroah-Hartman, linux-parisc, linux-fsdevel

On (22/09/24 02:10), John Ogness wrote:
[..]
>  static int console_unregister_locked(struct console *console)
>  {
> -	struct console *con;
>  	int res;
>  
>  	con_printk(KERN_INFO, console, "disabled\n");
> @@ -3274,32 +3287,28 @@ static int console_unregister_locked(struct console *console)
>  	if (res > 0)
>  		return 0;
>  
> -	res = -ENODEV;
>  	console_lock();
> -	if (console_drivers == console) {
> -		console_drivers=console->next;
> -		res = 0;
> -	} else {
> -		for_each_console(con) {
> -			if (con->next == console) {
> -				con->next = console->next;
> -				res = 0;
> -				break;
> -			}
> -		}
> -	}
>  
> -	if (res)
> -		goto out_disable_unlock;
> +	/* Disable it unconditionally */
> +	console->flags &= ~CON_ENABLED;
> +
> +	if (hlist_unhashed(&console->node))
> +		goto out_unlock;

Shouldn't this set `ret` to -ENODEV before goto? Otherwise it will always
return 0 (which is set by _braille_unregister_console()).

> +
> +	hlist_del_init(&console->node);
>  
>  	/*
> +	 * <HISTORICAL>
>  	 * If this isn't the last console and it has CON_CONSDEV set, we
>  	 * need to set it on the next preferred console.
> +	 * </HISTORICAL>
> +	 *
> +	 * The above makes no sense as there is no guarantee that the next
> +	 * console has any device attached. Oh well....
>  	 */

It's complicated...

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH printk 11/18] printk: Convert console_drivers list to hlist
  2022-09-24  0:04 ` [PATCH printk 11/18] printk: Convert console_drivers list to hlist John Ogness
  2022-09-24 10:53   ` Sergey Senozhatsky
@ 2022-09-24 17:20   ` Helge Deller
  2022-09-25  0:43     ` Sergey Senozhatsky
  2022-09-24 17:27   ` Helge Deller
  2022-09-30 14:20   ` Petr Mladek
  3 siblings, 1 reply; 17+ messages in thread
From: Helge Deller @ 2022-09-24 17:20 UTC (permalink / raw)
  To: John Ogness
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, James E.J. Bottomley, Helge Deller,
	Greg Kroah-Hartman, linux-parisc, linux-fsdevel

Hi John,

* John Ogness <john.ogness@linutronix.de>:
> From: Thomas Gleixner <tglx@linutronix.de>
>
> Replace the open coded single linked list with a hlist so a conversion to
> SRCU protected list walks can reuse the existing primitives.
>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  arch/parisc/kernel/pdc_cons.c | 19 +++----
>  fs/proc/consoles.c            |  5 +-
>  include/linux/console.h       | 15 ++++--
>  kernel/printk/printk.c        | 99 +++++++++++++++++++----------------
>  4 files changed, 75 insertions(+), 63 deletions(-)
>
> diff --git a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c
> index 9a0c0932d2f9..3f9abf0263ee 100644
> --- a/arch/parisc/kernel/pdc_cons.c
> +++ b/arch/parisc/kernel/pdc_cons.c
> @@ -272,15 +267,17 @@ void pdc_console_restart(bool hpmc)
>  	if (pdc_console_initialized)
>  		return;
>
> -	if (!hpmc && console_drivers)
> +	if (!hpmc && !hlist_empty(&console_list))
>  		return;
>
>  	/* If we've already seen the output, don't bother to print it again */
> -	if (console_drivers != NULL)
> +	if (!hlist_empty(&console_list))
>  		pdc_cons.flags &= ~CON_PRINTBUFFER;
>
> -	while ((console = console_drivers) != NULL)
> -		unregister_console(console_drivers);
> +	while (!hlist_empty(&console_list)) {
> +		unregister_console(READ_ONCE(hlist_entry(console_list.first,
> +							 struct console, node)));
> +	}
>
>  	/* force registering the pdc console */
>  	pdc_console_init_force();

Thanks for doing this!!

I had to add the hunks below on top of your patch to make it compile
and boot sucessfully on parisc.
Maybe you could fold those into your patch?

Thanks!
Helge


diff --git a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c
index 3f9abf0263ee..f15998aa47a8 100644
--- a/arch/parisc/kernel/pdc_cons.c
+++ b/arch/parisc/kernel/pdc_cons.c
@@ -262,8 +262,6 @@ void __init pdc_console_init(void)
  */
 void pdc_console_restart(bool hpmc)
 {
-	struct console *console;
-
 	if (pdc_console_initialized)
 		return;

@@ -275,8 +273,8 @@ void pdc_console_restart(bool hpmc)
 		pdc_cons.flags &= ~CON_PRINTBUFFER;

 	while (!hlist_empty(&console_list)) {
-		unregister_console(READ_ONCE(hlist_entry(console_list.first,
-							 struct console, node)));
+		unregister_console(hlist_entry(console_list.first,
+						 struct console, node));
 	}

 	/* force registering the pdc console */

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH printk 11/18] printk: Convert console_drivers list to hlist
  2022-09-24  0:04 ` [PATCH printk 11/18] printk: Convert console_drivers list to hlist John Ogness
  2022-09-24 10:53   ` Sergey Senozhatsky
  2022-09-24 17:20   ` Helge Deller
@ 2022-09-24 17:27   ` Helge Deller
  2022-09-30 14:20   ` Petr Mladek
  3 siblings, 0 replies; 17+ messages in thread
From: Helge Deller @ 2022-09-24 17:27 UTC (permalink / raw)
  To: John Ogness, Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, James E.J. Bottomley, Greg Kroah-Hartman,
	linux-parisc, linux-fsdevel

On 9/24/22 02:04, John Ogness wrote:
> --- a/kernel/printk/printk.c
> +++ b/kernel/printk/printk.c
> @@ -79,20 +79,20 @@ int oops_in_progress;
>   EXPORT_SYMBOL(oops_in_progress);
>
>   /*
> - * console_sem protects the console_drivers list, and also provides
> - * serialization for access to the entire console driver system.
> + * console_sem protects onsole_list, and also provides serialization for

Typo: missing the "c"
  onsole_list -> console_list

Helge

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH printk 11/18] printk: Convert console_drivers list to hlist
  2022-09-24 17:20   ` Helge Deller
@ 2022-09-25  0:43     ` Sergey Senozhatsky
  0 siblings, 0 replies; 17+ messages in thread
From: Sergey Senozhatsky @ 2022-09-25  0:43 UTC (permalink / raw)
  To: Helge Deller
  Cc: John Ogness, Petr Mladek, Sergey Senozhatsky, Steven Rostedt,
	Thomas Gleixner, linux-kernel, James E.J. Bottomley,
	Greg Kroah-Hartman, linux-parisc, linux-fsdevel

On (22/09/24 19:20), Helge Deller wrote:
> diff --git a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c
> index 3f9abf0263ee..f15998aa47a8 100644
> --- a/arch/parisc/kernel/pdc_cons.c
> +++ b/arch/parisc/kernel/pdc_cons.c
> @@ -262,8 +262,6 @@ void __init pdc_console_init(void)
>   */
>  void pdc_console_restart(bool hpmc)
>  {
> -	struct console *console;
> -
>  	if (pdc_console_initialized)
>  		return;
> 
> @@ -275,8 +273,8 @@ void pdc_console_restart(bool hpmc)
>  		pdc_cons.flags &= ~CON_PRINTBUFFER;
> 
>  	while (!hlist_empty(&console_list)) {
> -		unregister_console(READ_ONCE(hlist_entry(console_list.first,
> -							 struct console, node)));
> +		unregister_console(hlist_entry(console_list.first,
> +						 struct console, node));

In this case we maybe can use cons_first() macro here (perhaps
give it a little more clear name (first_console()?) and move to
printk.h) and also do READ_ONCE there

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH printk 00/18] preparation for threaded/atomic printing
  2022-09-24  6:44 ` [PATCH printk 00/18] preparation for threaded/atomic printing Greg Kroah-Hartman
@ 2022-09-25 15:23   ` John Ogness
  0 siblings, 0 replies; 17+ messages in thread
From: John Ogness @ 2022-09-25 15:23 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Petr Mladek, Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, linux-fsdevel, Jiri Slaby, James E.J. Bottomley,
	Helge Deller, Sven Schnelle, John David Anglin,
	Eric W. Biederman, Julia Lawall, linux-parisc, Jason Wessel,
	Daniel Thompson, Douglas Anderson, kgdb-bugreport, linux-serial,
	Aaron Tomlin, Luis Chamberlain

On 2022-09-24, Greg Kroah-Hartman <gregkh@linuxfoundation.org> wrote:
> These all look great to me, thanks for resending them.
>
> Do you want them to go through my serial/tty tree, or is there some
> other tree to take them through (printk?)

Thanks Greg. but I would prefer they go through the printk tree. In
particular, I want Petr to have the chance to review patches 15-18.

> If they are to go through someone else's tree, feel free to add:
>
> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Thanks!

John

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH printk 00/18] preparation for threaded/atomic printing
  2022-09-24  0:04 [PATCH printk 00/18] preparation for threaded/atomic printing John Ogness
                   ` (3 preceding siblings ...)
  2022-09-24  9:47 ` Sergey Senozhatsky
@ 2022-09-29 16:33 ` Petr Mladek
  4 siblings, 0 replies; 17+ messages in thread
From: Petr Mladek @ 2022-09-29 16:33 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, linux-fsdevel, Greg Kroah-Hartman, Jiri Slaby,
	James E.J. Bottomley, Helge Deller, Sven Schnelle,
	John David Anglin, Eric W. Biederman, Julia Lawall, linux-parisc,
	Jason Wessel, Daniel Thompson, Douglas Anderson, kgdb-bugreport,
	linux-serial, Aaron Tomlin, Luis Chamberlain

On Sat 2022-09-24 02:10:36, John Ogness wrote:
> Hi,
> 
> This series is essentially the first 18 patches of tglx's RFC series
> [0] with only minor changes in comments and commit messages. It's
> purpose is to lay the groundwork for the upcoming threaded/atomic
> console printing posted as the RFC series and demonstrated at
> LPC2022 [1].
> 
> This series is interesting for mainline because it cleans up various
> code and documentation quirks discovered while working on the new
> console printing implementation.
> 
> Aside from cleanups, the main features introduced here are:
> 
> - Converts the console's DIY linked list implementation to hlist.
> 
> - Introduces a console list lock (mutex) so that readers (such as
>   /proc/consoles) can safely iterate the consoles without blocking
>   console printing.
> 
> - Adds SRCU support to the console list to prepare for safe console
>   list iterating from any context.
> 
> - Refactors buffer handling to prepare for per-console, per-cpu,
>   per-context atomic printing.
> 
> The series has the following parts:
> 
>    Patches  1 - 5:   Cleanups
> 
>    Patches  6 - 12:  Locking and list conversion
> 
>    Patches 13 - 18:  Improved output buffer handling to prepare for
>                      code sharing
> 
> Thomas Gleixner (18):
>   printk: Make pr_flush() static
>   printk: Declare log_wait properly
>   printk: Remove write only variable nr_ext_console_drivers
>   printk: Remove bogus comment vs. boot consoles
>   printk: Mark __printk percpu data ready __ro_after_init

JFYI, I have pushed the first 5 cleanup patches into printk/linux.git,
branch rework/kthreads. The aim is to get them into 6.1.

The rest of the patchset is still being discussed.

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH printk 08/18] parisc: Put console abuse into one place
  2022-09-24  0:04 ` [PATCH printk 08/18] parisc: Put console abuse into one place John Ogness
  2022-09-24  0:20   ` Steven Rostedt
@ 2022-09-30  7:54   ` Petr Mladek
  1 sibling, 0 replies; 17+ messages in thread
From: Petr Mladek @ 2022-09-30  7:54 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, James E.J. Bottomley, Helge Deller, Sven Schnelle,
	John David Anglin, Eric W. Biederman, Julia Lawall, linux-parisc

On Sat 2022-09-24 02:10:44, John Ogness wrote:
> From: Thomas Gleixner <tglx@linutronix.de>
> 
> PARISC has a hope based mechanism to restore consoles in case of a HPMC
> (machine check exception) which is scattered over several places.
> 
> Move it into one place to make further changes simpler and add comments.
> 
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org>

I agree that the mechanism is weird. A bit more safe approach would be
to just disable all consoles instead of unregistering them...

Anyway, the patch does not change the existing behavior:

Reviewed-by: Petr Mladek <pmladek@suse.com>

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH printk 11/18] printk: Convert console_drivers list to hlist
  2022-09-24  0:04 ` [PATCH printk 11/18] printk: Convert console_drivers list to hlist John Ogness
                     ` (2 preceding siblings ...)
  2022-09-24 17:27   ` Helge Deller
@ 2022-09-30 14:20   ` Petr Mladek
  2022-09-30 16:53     ` Helge Deller
  3 siblings, 1 reply; 17+ messages in thread
From: Petr Mladek @ 2022-09-30 14:20 UTC (permalink / raw)
  To: John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, James E.J. Bottomley, Helge Deller,
	Greg Kroah-Hartman, linux-parisc, linux-fsdevel

On Sat 2022-09-24 02:10:47, John Ogness wrote:
> From: Thomas Gleixner <tglx@linutronix.de>
> 
> Replace the open coded single linked list with a hlist so a conversion to
> SRCU protected list walks can reuse the existing primitives.
> 
> --- a/arch/parisc/kernel/pdc_cons.c
> +++ b/arch/parisc/kernel/pdc_cons.c
> @@ -272,15 +267,17 @@ void pdc_console_restart(bool hpmc)
>  	if (pdc_console_initialized)
>  		return;
>  
> -	if (!hpmc && console_drivers)
> +	if (!hpmc && !hlist_empty(&console_list))
>  		return;
>  
>  	/* If we've already seen the output, don't bother to print it again */
> -	if (console_drivers != NULL)
> +	if (!hlist_empty(&console_list))
>  		pdc_cons.flags &= ~CON_PRINTBUFFER;
>  
> -	while ((console = console_drivers) != NULL)
> -		unregister_console(console_drivers);
> +	while (!hlist_empty(&console_list)) {
> +		unregister_console(READ_ONCE(hlist_entry(console_list.first,
> +							 struct console, node)));

The READ_ONCE() is in a wrong place. This is why it did not compile.
It should be:

		unregister_console(hlist_entry(READ_ONCE(console_list.first),
						struct console,
						node));

I know that it is all hope for good. But there is also a race between
the hlist_empty() and hlist_entry().

We might make it sligtly more safe by using hlist_entry_safe()

	struct console *con;

	while (con = hlist_entry_safe(READ_ONCE(console_list.first),
				      struct console, node)) {
		unregister_console(con);
	}

or

	while (tmp = READ_ONCE(console_list.first) {
		unregister_console(hlist_entry_safe(tmp, struct console, node));
	}

> +	}
>  
>  	/* force registering the pdc console */
>  	pdc_console_init_force();
> diff --git a/fs/proc/consoles.c b/fs/proc/consoles.c
> index 6775056eecd5..70994d1e52f6 100644
> --- a/fs/proc/consoles.c
> +++ b/fs/proc/consoles.c
> @@ -74,8 +74,11 @@ static void *c_start(struct seq_file *m, loff_t *pos)
>  static void *c_next(struct seq_file *m, void *v, loff_t *pos)
>  {
>  	struct console *con = v;
> +
>  	++*pos;
> -	return con->next;
> +	hlist_for_each_entry_continue(con, node)
> +		break;

Nit: It looks weird and hacky. It does not look like a common patter.
     I see that another code reads the next entry instead.
     I would rather do:

     return hlist_entry_safe(con->node.next, struct *console, node);

and we should later make it rcu safe, something like:

     return hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu(con, struct *console, node));

But I do not have strong opinion.


> +	return con;
>  }
>  
>  static void c_stop(struct seq_file *m, void *v)
> --- a/kernel/printk/printk.c
> +++ b/kernel/printk/printk.c
> @@ -2979,7 +2984,15 @@ void console_flush_on_panic(enum con_flush_mode mode)
>  		u64 seq;
>  
>  		seq = prb_first_valid_seq(prb);
> -		for_each_console(c)
> +		/*
> +		 * 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(c, &console_list, node)
>  			c->seq = seq;

It is not a big deal. But I would use the _safe() variant to make
it slightly more robust.

>  	}
>  	console_unlock();
> @@ -3211,21 +3227,17 @@ void register_console(struct console *newcon)
>  	}
>  
>  	/*
> -	 *	Put this console in the list - keep the
> -	 *	preferred driver at the head of the list.
> +	 * Put this console in the list and keep the referred driver at the
> +	 * head of the list.
>  	 */
>  	console_lock();
> -	if ((newcon->flags & CON_CONSDEV) || console_drivers == NULL) {
> -		newcon->next = console_drivers;
> -		console_drivers = newcon;
> -		if (newcon->next)
> -			newcon->next->flags &= ~CON_CONSDEV;
> -		/* Ensure this flag is always set for the head of the list */
> -		newcon->flags |= CON_CONSDEV;
> -	} else {
> -		newcon->next = console_drivers->next;
> -		console_drivers->next = newcon;
> -	}
> +	if (newcon->flags & CON_CONSDEV || hlist_empty(&console_list))
> +		hlist_add_head(&newcon->node, &console_list);
> +	else
> +		hlist_add_behind(&newcon->node, console_list.first);
> +
> +	/* Ensure this flag is always set for the head of the list */
> +	cons_first()->flags |= CON_CONSDEV;

The patch removed:

		if (newcon->next)
			newcon->next->flags &= ~CON_CONSDEV;

As a result, all consoles will have CON_CONSDEV flag set.
We need to remove it in the 2nd console when exists.
See below for more details.

>  	newcon->dropped = 0;
>  	if (newcon->flags & CON_PRINTBUFFER) {
> @@ -3263,7 +3277,6 @@ EXPORT_SYMBOL(register_console);
>  
>  static int console_unregister_locked(struct console *console)
>  {
> -	struct console *con;
>  	int res;
>  
>  	con_printk(KERN_INFO, console, "disabled\n");
> @@ -3274,32 +3287,28 @@ static int console_unregister_locked(struct console *console)
>  	if (res > 0)
>  		return 0;
>  
> -	res = -ENODEV;
>  	console_lock();
> -	if (console_drivers == console) {
> -		console_drivers=console->next;
> -		res = 0;
> -	} else {
> -		for_each_console(con) {
> -			if (con->next == console) {
> -				con->next = console->next;
> -				res = 0;
> -				break;
> -			}
> -		}
> -	}
>  
> -	if (res)
> -		goto out_disable_unlock;
> +	/* Disable it unconditionally */
> +	console->flags &= ~CON_ENABLED;
> +
> +	if (hlist_unhashed(&console->node))
> +		goto out_unlock;

We should return -ENODEV here. I think that Sergey found this as well.

> +	hlist_del_init(&console->node);
>  
>  	/*
> +	 * <HISTORICAL>
>  	 * If this isn't the last console and it has CON_CONSDEV set, we
>  	 * need to set it on the next preferred console.
> +	 * </HISTORICAL>
> +	 *
> +	 * The above makes no sense as there is no guarantee that the next
> +	 * console has any device attached. Oh well....

This is a sad story. CON_CONSDEV used to be an implementation detail.
It was used to associate the preferred console (last on the
command line) with /dev/console. It was achieved by putting
it at the beginning of the list. All consoled had tty binding at
that time.

The problem started when the flags became readable by user space
via /proc/consoles. There is even a tool (showconsole) that is
reading it. As a result people wanted to show correct value.

The problem is that con->device never exist during boot. The consoles
are registered before the tty subsystem is initialized.

I have a patch that sets the flag correctly in console_device()
that is called from tty_lookup_driver(). But it is part of a bigger
clean up patchset that is sitting in my drawer :-/

On the other hand, the current code kind of works. Most console
drivers have the tty binding. I can't recall what is the exception.
Maybe boot consoles?

>  	 */
> -	if (console_drivers != NULL && console->flags & CON_CONSDEV)
> -		console_drivers->flags |= CON_CONSDEV;
> +	if (!hlist_empty(&console_list) && console->flags & CON_CONSDEV)
> +		cons_first()->flags |= CON_CONSDEV;
>
>  
> -	console->flags &= ~CON_ENABLED;
>  	console_unlock();
>  	console_sysfs_notify();

Best Regards,
Petr

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH printk 11/18] printk: Convert console_drivers list to hlist
  2022-09-30 14:20   ` Petr Mladek
@ 2022-09-30 16:53     ` Helge Deller
  2022-09-30 19:46       ` John Ogness
  0 siblings, 1 reply; 17+ messages in thread
From: Helge Deller @ 2022-09-30 16:53 UTC (permalink / raw)
  To: Petr Mladek, John Ogness
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, James E.J. Bottomley, Greg Kroah-Hartman,
	linux-parisc, linux-fsdevel

On 9/30/22 16:20, Petr Mladek wrote:
> On Sat 2022-09-24 02:10:47, John Ogness wrote:
>> From: Thomas Gleixner <tglx@linutronix.de>
>>
>> Replace the open coded single linked list with a hlist so a conversion to
>> SRCU protected list walks can reuse the existing primitives.
>>
>> --- a/arch/parisc/kernel/pdc_cons.c
>> +++ b/arch/parisc/kernel/pdc_cons.c
>> @@ -272,15 +267,17 @@ void pdc_console_restart(bool hpmc)
>>   	if (pdc_console_initialized)
>>   		return;
>>
>> -	if (!hpmc && console_drivers)
>> +	if (!hpmc && !hlist_empty(&console_list))
>>   		return;
>>
>>   	/* If we've already seen the output, don't bother to print it again */
>> -	if (console_drivers != NULL)
>> +	if (!hlist_empty(&console_list))
>>   		pdc_cons.flags &= ~CON_PRINTBUFFER;
>>
>> -	while ((console = console_drivers) != NULL)
>> -		unregister_console(console_drivers);
>> +	while (!hlist_empty(&console_list)) {
>> +		unregister_console(READ_ONCE(hlist_entry(console_list.first,
>> +							 struct console, node)));
>
> The READ_ONCE() is in a wrong place. This is why it did not compile.
> It should be:
>
> 		unregister_console(hlist_entry(READ_ONCE(console_list.first),
> 						struct console,
> 						node));
>
> I know that it is all hope for good. But there is also a race between
> the hlist_empty() and hlist_entry().

I wonder if pdc_console() is still needed as it is today.
When this was written, early_console and such didn't worked for parisc
as it should. That's proably why we have this register/unregister in here.

Would it make sense, and would we gain something for this printk-series,
if I'd try to convert pdc_console to a standard earlycon or earlyprintk device?

Helge

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH printk 11/18] printk: Convert console_drivers list to hlist
  2022-09-30 16:53     ` Helge Deller
@ 2022-09-30 19:46       ` John Ogness
  2022-09-30 22:41         ` Helge Deller
  0 siblings, 1 reply; 17+ messages in thread
From: John Ogness @ 2022-09-30 19:46 UTC (permalink / raw)
  To: Helge Deller, Petr Mladek
  Cc: Sergey Senozhatsky, Steven Rostedt, Thomas Gleixner,
	linux-kernel, James E.J. Bottomley, Greg Kroah-Hartman,
	linux-parisc, linux-fsdevel

On 2022-09-30, Helge Deller <deller@gmx.de> wrote:
>> I know that it is all hope for good. But there is also a race between
>> the hlist_empty() and hlist_entry().
>
> I wonder if pdc_console() is still needed as it is today.  When this
> was written, early_console and such didn't worked for parisc as it
> should. That's proably why we have this register/unregister in here.
>
> Would it make sense, and would we gain something for this
> printk-series, if I'd try to convert pdc_console to a standard
> earlycon or earlyprintk device?

Having an earlycon or earlyprintk device will not really help you here
since those drivers will have already unregistered.

However, once we get the new atomic/kthread interface available, it
certainly would be useful to implement the pdc_console as an atomic
console.

John Ogness

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH printk 11/18] printk: Convert console_drivers list to hlist
  2022-09-30 19:46       ` John Ogness
@ 2022-09-30 22:41         ` Helge Deller
  0 siblings, 0 replies; 17+ messages in thread
From: Helge Deller @ 2022-09-30 22:41 UTC (permalink / raw)
  To: John Ogness
  Cc: Helge Deller, Petr Mladek, Sergey Senozhatsky, Steven Rostedt,
	Thomas Gleixner, linux-kernel, James E.J. Bottomley,
	Greg Kroah-Hartman, linux-parisc, linux-fsdevel

* John Ogness <john.ogness@linutronix.de>:
> On 2022-09-30, Helge Deller <deller@gmx.de> wrote:
> >> I know that it is all hope for good. But there is also a race between
> >> the hlist_empty() and hlist_entry().
> >
> > I wonder if pdc_console() is still needed as it is today.  When this
> > was written, early_console and such didn't worked for parisc as it
> > should. That's proably why we have this register/unregister in here.
> >
> > Would it make sense, and would we gain something for this
> > printk-series, if I'd try to convert pdc_console to a standard
> > earlycon or earlyprintk device?
>
> Having an earlycon or earlyprintk device will not really help you here
> since those drivers will have already unregistered.
>
> However, once we get the new atomic/kthread interface available, it
> certainly would be useful to implement the pdc_console as an atomic
> console.

My idea was to drop most of the pdc console, so that patch #8 and parts
of patch #11 of the printk patch series could be dropped and you won't
need to take care of those parts when introducing the printk
threaded/atomic printing changes.

See patch below. Basically it drops all of the offending code.
I haven't yet checked it into my parisc for-next tree to not break
something.

Helge



From 5b697874e10729136ce7dd7b362b276f35fae56d Mon Sep 17 00:00:00 2001
From: Helge Deller <deller@gmx.de>
Date: Sat, 1 Oct 2022 00:32:07 +0200
Subject: [PATCH] parisc: Drop PDC console and convert it to an early console

Rewrite the PDC console to become an early console, which can be used
for kgdb as well.

Signed-off-by: Helge Deller <deller@gmx.de>

diff --git a/arch/parisc/include/asm/pdc.h b/arch/parisc/include/asm/pdc.h
index b643092d4b98..fcbcf9a96c11 100644
--- a/arch/parisc/include/asm/pdc.h
+++ b/arch/parisc/include/asm/pdc.h
@@ -19,9 +19,6 @@ extern unsigned long parisc_pat_pdc_cap; /* PDC capabilities (PAT) */
 #define PDC_TYPE_SYSTEM_MAP	 1 /* 32-bit, but supports PDC_SYSTEM_MAP */
 #define PDC_TYPE_SNAKE		 2 /* Doesn't support SYSTEM_MAP */

-void pdc_console_init(void);	/* in pdc_console.c */
-void pdc_console_restart(void);
-
 void setup_pdc(void);		/* in inventory.c */

 /* wrapper-functions from pdc.c */
diff --git a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c
index 2661cdd256ae..45a4d2994857 100644
--- a/arch/parisc/kernel/pdc_cons.c
+++ b/arch/parisc/kernel/pdc_cons.c
@@ -1,46 +1,24 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 /*
- *    PDC Console support - ie use firmware to dump text via boot console
+ *    PDC early console support - ie use firmware to dump text via boot console
  *
- *    Copyright (C) 1999-2003 Matthew Wilcox <willy at parisc-linux.org>
- *    Copyright (C) 2000 Martin K Petersen <mkp at mkp.net>
- *    Copyright (C) 2000 John Marvin <jsm at parisc-linux.org>
- *    Copyright (C) 2000-2003 Paul Bame <bame at parisc-linux.org>
- *    Copyright (C) 2000 Philipp Rumpf <prumpf with tux.org>
- *    Copyright (C) 2000 Michael Ang <mang with subcarrier.org>
- *    Copyright (C) 2000 Grant Grundler <grundler with parisc-linux.org>
- *    Copyright (C) 2001-2002 Ryan Bradetich <rbrad at parisc-linux.org>
- *    Copyright (C) 2001 Helge Deller <deller at parisc-linux.org>
- *    Copyright (C) 2001 Thomas Bogendoerfer <tsbogend at parisc-linux.org>
- *    Copyright (C) 2002 Randolph Chung <tausq with parisc-linux.org>
- *    Copyright (C) 2010 Guy Martin <gmsoft at tuxicoman.be>
+ *    Copyright (C) 2001-2022 Helge Deller <deller@gmx.de>
  */

 /*
- *  The PDC console is a simple console, which can be used for debugging
- *  boot related problems on HP PA-RISC machines. It is also useful when no
- *  other console works.
- *
  *  This code uses the ROM (=PDC) based functions to read and write characters
  *  from and to PDC's boot path.
  */

-/* Define EARLY_BOOTUP_DEBUG to debug kernel related boot problems.
- * On production kernels EARLY_BOOTUP_DEBUG should be undefined. */
-#define EARLY_BOOTUP_DEBUG
-
-
 #include <linux/kernel.h>
 #include <linux/console.h>
-#include <linux/string.h>
 #include <linux/init.h>
-#include <linux/major.h>
-#include <linux/tty.h>
+#include <linux/serial_core.h>
+#include <linux/kgdb.h>
 #include <asm/page.h>		/* for PAGE0 */
 #include <asm/pdc.h>		/* for iodc_call() proto and friends */

 static DEFINE_SPINLOCK(pdc_console_lock);
-static struct console pdc_cons;

 static void pdc_console_write(struct console *co, const char *s, unsigned count)
 {
@@ -54,210 +32,47 @@ static void pdc_console_write(struct console *co, const char *s, unsigned count)
 	spin_unlock_irqrestore(&pdc_console_lock, flags);
 }

-int pdc_console_poll_key(struct console *co)
+static int kgdb_pdc_read_char(void)
 {
-	int c;
 	unsigned long flags;
+	int c;

 	spin_lock_irqsave(&pdc_console_lock, flags);
 	c = pdc_iodc_getc();
 	spin_unlock_irqrestore(&pdc_console_lock, flags);

-	return c;
-}
-
-static int pdc_console_setup(struct console *co, char *options)
-{
-	return 0;
-}
-
-#if defined(CONFIG_PDC_CONSOLE)
-#include <linux/vt_kern.h>
-#include <linux/tty_flip.h>
-
-#define PDC_CONS_POLL_DELAY (30 * HZ / 1000)
-
-static void pdc_console_poll(struct timer_list *unused);
-static DEFINE_TIMER(pdc_console_timer, pdc_console_poll);
-static struct tty_port tty_port;
-
-static int pdc_console_tty_open(struct tty_struct *tty, struct file *filp)
-{
-	tty_port_tty_set(&tty_port, tty);
-	mod_timer(&pdc_console_timer, jiffies + PDC_CONS_POLL_DELAY);
-
-	return 0;
-}
-
-static void pdc_console_tty_close(struct tty_struct *tty, struct file *filp)
-{
-	if (tty->count == 1) {
-		del_timer_sync(&pdc_console_timer);
-		tty_port_tty_set(&tty_port, NULL);
-	}
+	return (c <= 0) ? NO_POLL_CHAR : c;
 }

-static int pdc_console_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
+static void kgdb_pdc_write_char(u8 chr)
 {
-	pdc_console_write(NULL, buf, count);
-	return count;
+	if (PAGE0->mem_cons.cl_class != CL_DUPLEX)
+		pdc_console_write(NULL, &chr, 1);
 }

-static unsigned int pdc_console_tty_write_room(struct tty_struct *tty)
-{
-	return 32768; /* no limit, no buffer used */
-}
-
-static const struct tty_operations pdc_console_tty_ops = {
-	.open = pdc_console_tty_open,
-	.close = pdc_console_tty_close,
-	.write = pdc_console_tty_write,
-	.write_room = pdc_console_tty_write_room,
+static struct kgdb_io kgdb_pdc_io_ops = {
+	.name = "kgdb_pdc",
+	.read_char = kgdb_pdc_read_char,
+	.write_char = kgdb_pdc_write_char,
 };

-static void pdc_console_poll(struct timer_list *unused)
-{
-	int data, count = 0;
-
-	while (1) {
-		data = pdc_console_poll_key(NULL);
-		if (data == -1)
-			break;
-		tty_insert_flip_char(&tty_port, data & 0xFF, TTY_NORMAL);
-		count ++;
-	}
-
-	if (count)
-		tty_flip_buffer_push(&tty_port);
-
-	if (pdc_cons.flags & CON_ENABLED)
-		mod_timer(&pdc_console_timer, jiffies + PDC_CONS_POLL_DELAY);
-}
-
-static struct tty_driver *pdc_console_tty_driver;
-
-static int __init pdc_console_tty_driver_init(void)
-{
-	struct tty_driver *driver;
-	int err;
-
-	/* Check if the console driver is still registered.
-	 * It is unregistered if the pdc console was not selected as the
-	 * primary console. */
-
-	struct console *tmp;
-
-	console_lock();
-	for_each_console(tmp)
-		if (tmp == &pdc_cons)
-			break;
-	console_unlock();
-
-	if (!tmp) {
-		printk(KERN_INFO "PDC console driver not registered anymore, not creating %s\n", pdc_cons.name);
-		return -ENODEV;
-	}
-
-	printk(KERN_INFO "The PDC console driver is still registered, removing CON_BOOT flag\n");
-	pdc_cons.flags &= ~CON_BOOT;
-
-	driver = tty_alloc_driver(1, TTY_DRIVER_REAL_RAW |
-			TTY_DRIVER_RESET_TERMIOS);
-	if (IS_ERR(driver))
-		return PTR_ERR(driver);
-
-	tty_port_init(&tty_port);
-
-	driver->driver_name = "pdc_cons";
-	driver->name = "ttyB";
-	driver->major = MUX_MAJOR;
-	driver->minor_start = 0;
-	driver->type = TTY_DRIVER_TYPE_SYSTEM;
-	driver->init_termios = tty_std_termios;
-	tty_set_operations(driver, &pdc_console_tty_ops);
-	tty_port_link_device(&tty_port, driver, 0);
-
-	err = tty_register_driver(driver);
-	if (err) {
-		printk(KERN_ERR "Unable to register the PDC console TTY driver\n");
-		tty_port_destroy(&tty_port);
-		tty_driver_kref_put(driver);
-		return err;
-	}
-
-	pdc_console_tty_driver = driver;
-
-	return 0;
-}
-device_initcall(pdc_console_tty_driver_init);
-
-static struct tty_driver * pdc_console_device (struct console *c, int *index)
+static int __init pdc_earlycon_setup(struct earlycon_device *device,
+				     const char *opt)
 {
-	*index = c->index;
-	return pdc_console_tty_driver;
-}
-#else
-#define pdc_console_device NULL
-#endif
-
-static struct console pdc_cons = {
-	.name =		"ttyB",
-	.write =	pdc_console_write,
-	.device =	pdc_console_device,
-	.setup =	pdc_console_setup,
-	.flags =	CON_BOOT | CON_PRINTBUFFER,
-	.index =	-1,
-};
+	struct console *earlycon_console;

-static int pdc_console_initialized;
-
-static void pdc_console_init_force(void)
-{
-	if (pdc_console_initialized)
-		return;
-	++pdc_console_initialized;
-
 	/* If the console is duplex then copy the COUT parameters to CIN. */
 	if (PAGE0->mem_cons.cl_class == CL_DUPLEX)
 		memcpy(&PAGE0->mem_kbd, &PAGE0->mem_cons, sizeof(PAGE0->mem_cons));

-	/* register the pdc console */
-	register_console(&pdc_cons);
-}
-
-void __init pdc_console_init(void)
-{
-#if defined(EARLY_BOOTUP_DEBUG) || defined(CONFIG_PDC_CONSOLE)
-	pdc_console_init_force();
-#endif
-#ifdef EARLY_BOOTUP_DEBUG
-	printk(KERN_INFO "Initialized PDC Console for debugging.\n");
-#endif
-}
-
-
-/*
- * Used for emergencies. Currently only used if an HPMC occurs. If an
- * HPMC occurs, it is possible that the current console may not be
- * properly initialised after the PDC IO reset. This routine unregisters
- * all of the current consoles, reinitializes the pdc console and
- * registers it.
- */
-
-void pdc_console_restart(void)
-{
-	struct console *console;
+	earlycon_console = device->con;
+	earlycon_console->write = pdc_console_write;
+	device->port.iotype = UPIO_MEM32BE;

-	if (pdc_console_initialized)
-		return;
+	if (IS_ENABLED(CONFIG_KGDB))
+		kgdb_register_io_module(&kgdb_pdc_io_ops);

-	/* If we've already seen the output, don't bother to print it again */
-	if (console_drivers != NULL)
-		pdc_cons.flags &= ~CON_PRINTBUFFER;
-
-	while ((console = console_drivers) != NULL)
-		unregister_console(console_drivers);
-
-	/* force registering the pdc console */
-	pdc_console_init_force();
+	return 0;
 }
+
+EARLYCON_DECLARE(pdc, pdc_earlycon_setup);
diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c
index f005ddedb50e..375f38d6e1a4 100644
--- a/arch/parisc/kernel/setup.c
+++ b/arch/parisc/kernel/setup.c
@@ -70,6 +70,10 @@ void __init setup_cmdline(char **cmdline_p)
 			strlcat(p, "tty0", COMMAND_LINE_SIZE);
 	}

+	/* default to use early console */
+	if (!strstr(p, "earlycon"))
+		strlcat(p, " earlycon=pdc", COMMAND_LINE_SIZE);
+
 #ifdef CONFIG_BLK_DEV_INITRD
 		if (boot_args[2] != 0) /* did palo pass us a ramdisk? */
 		{
@@ -139,8 +143,6 @@ void __init setup_arch(char **cmdline_p)
 	if (__pa((unsigned long) &_end) >= KERNEL_INITIAL_SIZE)
 		panic("KERNEL_INITIAL_ORDER too small!");

-	pdc_console_init();
-
 #ifdef CONFIG_64BIT
 	if(parisc_narrow_firmware) {
 		printk(KERN_INFO "Kernel is using PDC in 32-bit mode.\n");
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
index b78f1b9d45c1..f9696fbf646c 100644
--- a/arch/parisc/kernel/traps.c
+++ b/arch/parisc/kernel/traps.c
@@ -239,13 +239,6 @@ void die_if_kernel(char *str, struct pt_regs *regs, long err)
 	/* unlock the pdc lock if necessary */
 	pdc_emergency_unlock();

-	/* maybe the kernel hasn't booted very far yet and hasn't been able
-	 * to initialize the serial or STI console. In that case we should
-	 * re-enable the pdc console, so that the user will be able to
-	 * identify the problem. */
-	if (!console_drivers)
-		pdc_console_restart();
-
 	if (err)
 		printk(KERN_CRIT "%s (pid %d): %s (code %ld)\n",
 			current->comm, task_pid_nr(current), str, err);
@@ -429,10 +422,6 @@ void parisc_terminate(char *msg, struct pt_regs *regs, int code, unsigned long o
 	/* unlock the pdc lock if necessary */
 	pdc_emergency_unlock();

-	/* restart pdc console if necessary */
-	if (!console_drivers)
-		pdc_console_restart();
-
 	/* Not all paths will gutter the processor... */
 	switch(code){

@@ -482,9 +471,7 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
 	unsigned long fault_space = 0;
 	int si_code;

-	if (code == 1)
-	    pdc_console_restart();  /* switch back to pdc if HPMC */
-	else if (!irqs_disabled_flags(regs->gr[0]))
+	if (!irqs_disabled_flags(regs->gr[0]))
 	    local_irq_enable();

 	/* Security check:
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 877173907c53..898728ab2c18 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -602,21 +602,6 @@ config SERIAL_MUX_CONSOLE
 	select SERIAL_CORE_CONSOLE
 	default y

-config PDC_CONSOLE
-	bool "PDC software console support"
-	depends on PARISC && !SERIAL_MUX && VT
-	help
-	  Saying Y here will enable the software based PDC console to be
-	  used as the system console.  This is useful for machines in
-	  which the hardware based console has not been written yet.  The
-	  following steps must be completed to use the PDC console:
-
-	    1. create the device entry (mknod /dev/ttyB0 c 11 0)
-	    2. Edit the /etc/inittab to start a getty listening on /dev/ttyB0
-	    3. Add device ttyB0 to /etc/securetty (if you want to log on as
-		 root on this console.)
-	    4. Change the kernel command console parameter to: console=ttyB0
-
 config SERIAL_SUNSAB
 	tristate "Sun Siemens SAB82532 serial support"
 	depends on SPARC && PCI
diff --git a/lib/Kconfig.kgdb b/lib/Kconfig.kgdb
index 05dae05b6cc9..3b9a44008433 100644
--- a/lib/Kconfig.kgdb
+++ b/lib/Kconfig.kgdb
@@ -121,7 +121,7 @@ config KDB_DEFAULT_ENABLE

 config KDB_KEYBOARD
 	bool "KGDB_KDB: keyboard as input device"
-	depends on VT && KGDB_KDB
+	depends on VT && KGDB_KDB && !PARISC
 	default n
 	help
 	  KDB can use a PS/2 type keyboard for an input device

^ permalink raw reply related	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2022-09-30 22:42 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-24  0:04 [PATCH printk 00/18] preparation for threaded/atomic printing John Ogness
2022-09-24  0:04 ` [PATCH printk 08/18] parisc: Put console abuse into one place John Ogness
2022-09-24  0:20   ` Steven Rostedt
2022-09-30  7:54   ` Petr Mladek
2022-09-24  0:04 ` [PATCH printk 11/18] printk: Convert console_drivers list to hlist John Ogness
2022-09-24 10:53   ` Sergey Senozhatsky
2022-09-24 17:20   ` Helge Deller
2022-09-25  0:43     ` Sergey Senozhatsky
2022-09-24 17:27   ` Helge Deller
2022-09-30 14:20   ` Petr Mladek
2022-09-30 16:53     ` Helge Deller
2022-09-30 19:46       ` John Ogness
2022-09-30 22:41         ` Helge Deller
2022-09-24  6:44 ` [PATCH printk 00/18] preparation for threaded/atomic printing Greg Kroah-Hartman
2022-09-25 15:23   ` John Ogness
2022-09-24  9:47 ` Sergey Senozhatsky
2022-09-29 16:33 ` Petr Mladek

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).