[PATCH for-6.4] printk: Unregister boot consoles on register of 1st real console

From: Lukas Wunner
Date: Thu Feb 23 2023 - 23:46:27 EST


The code comment preceding register_console() claims that:

"There are two types of consoles - bootconsoles (early_printk) and
"real" consoles (everything which is not a bootconsole) which are
handled differently. [...]
As soon as a "real" console is registered, all bootconsoles
will be unregistered automatically."

But that's not what the code does: The code unregisters bootconsoles
only when the *preferred* console registers, i.e. the last one on the
command line. If that console's driver never registers (e.g. because
it is disabled in the kernel config), bootconsoles stay around
indefinitely. Should the command line contain both a bootconsole as
well as a real console on the same serial port, all messages are logged
twice once the real console registers.

Moreover, the log buffer is replayed once the real console registers
even though the messages were already emitted by the bootconsole.

Amend the code to be congruent with the above-quoted code comment and
thereby avoid these issues.

Signed-off-by: Lukas Wunner <lukas@xxxxxxxxx>
---
kernel/printk/printk.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index fd0c9f913940..f89e865c6b23 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -3423,10 +3423,8 @@ void register_console(struct console *newcon)
* the real console are the same physical device, it's annoying to
* see the beginning boot messages twice
*/
- if (bootcon_registered &&
- ((newcon->flags & (CON_CONSDEV | CON_BOOT)) == CON_CONSDEV)) {
+ if (bootcon_registered && !(newcon->flags & CON_BOOT))
newcon->flags &= ~CON_PRINTBUFFER;
- }

newcon->dropped = 0;
console_init_seq(newcon, bootcon_registered);
@@ -3465,8 +3463,7 @@ void register_console(struct console *newcon)
* went to the bootconsole (that they do not see on the real console)
*/
con_printk(KERN_INFO, newcon, "enabled\n");
- if (bootcon_registered &&
- ((newcon->flags & (CON_CONSDEV | CON_BOOT)) == CON_CONSDEV) &&
+ if (bootcon_registered && !(newcon->flags & CON_BOOT) &&
!keep_bootcon) {
struct hlist_node *tmp;

--
2.39.1