From nobody Mon May 25 05:56:33 2026 Received: from out28-196.mail.aliyun.com (out28-196.mail.aliyun.com [115.124.28.196]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2D9FB2FE579 for ; Mon, 18 May 2026 09:04:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.28.196 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779095045; cv=none; b=cJNwSsvfIH4hSJ8Az4CetUQkk4XpXyI5M9zCIVJlCSaX7Cyoq+oenaDfA5Bj3o9k62N4wKg5q8+L1kuNXIAlogFlscIgmFDkBGxP7A17wrRBuMvoddd7zrA0QUQL3ozP2WRNtizlBViu70PURHcITFxGFecvfAWss4f8s35HTg4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779095045; c=relaxed/simple; bh=3aVOtj+QsazgaijdxMZH5yG2DtQ1DOXIrKAiK6IUFLs=; h=From:To:Cc:Subject:Date:Message-Id; b=o9IWQczCXcj6nTvovjsx0ANwYoX1YyAMYEekBhlv7u7Y2UTs8Z95PPbAQNMOZHfHQ5CdFSXQqaiSdJ/xdjFbIAWW1Jt9AwOa5tXsvs2th3BPzeKfabMV+meKJHntDtIMi27Gft5YcCcQnHt3Ckl3N+kgWCFsGxh1XEu04EF/qaE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=open-hieco.net; spf=pass smtp.mailfrom=open-hieco.net; arc=none smtp.client-ip=115.124.28.196 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=open-hieco.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=open-hieco.net X-Alimail-AntiSpam: AC=CONTINUE;BC=0.07449195|-1;CH=green;DM=|CONTINUE|false|;DS=CONTINUE|ham_system_inform|0.0116417-0.00137335-0.986985;FP=17132074119063948883|0|0|0|0|-1|-1|-1;HT=maildocker-contentspam033037021130;MF=lixiaochun@open-hieco.net;NM=1;PH=DS;RN=6;RT=6;SR=0;TI=SMTPD_---.hZuZLei_1779095019; Received: from localhost.localdomain(mailfrom:lixiaochun@open-hieco.net fp:SMTPD_---.hZuZLei_1779095019 cluster:ay29) by smtp.aliyun-inc.com; Mon, 18 May 2026 17:03:53 +0800 From: Xiaochun Li To: pmladek@suse.com Cc: rostedt@goodmis.org, john.ogness@linutronix.de, senozhatsky@chromium.org, linux-kernel@vger.kernel.org, Xiaochun Li Subject: [PATCH v1] printk: Unconditionally unregister boot consoles when any real console appears Date: Mon, 18 May 2026 16:42:51 +0800 Message-Id: <20260518084251.3887779-1-lixiaochun@open-hieco.net> X-Mailer: git-send-email 2.18.2 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The design of kernel message printing ensures that boot consoles are temporary and should be unregistered once a real console appears, preventing duplicate output without any loss of kernel messages. But currently, when multiple "console=3D" parameters are specified (e.g., console=3DttyS0 console=3DttyS1) together with a boot console (earlyprintk=3DttyS0 and/or earlycon=3Duart,io,0x3f8), the boot console remains active indefinitely. As a result, after the real console active, each kernel message line is printed twice consecutively that is not as expected. Currently, register_console() unregisters boot consoles only when the newly registered console has CON_CONSDEV (i.e., it is the preferred console). However, when multiple "console=3D" arguments are given for the same driver (e.g., 8250), the try_enable_preferred_console() matches only the first console_cmdline entry and returns immediately. The enabled real console (ttyS0) is therefore not the preferred one and does not set CON_CONSDEV, because preferred_console points to the last entry (ttyS1). Consequently, the boot console is never unregistered. Fix this issue by removing the CON_CONSDEV requirement and unregistering all boot consoles whenever any real console (i.e., any console without CON_BOOT flag) is registered, unless keep_bootcon or keep option append to earlyprintk is specified. This simplification relies on the existing printk buffer replay mechanism: when a real console is registered, its internal sequence number ensures it will output all messages from the entire kernel log, including those printed before it was enabled. Therefore, no messages are lost even if boot consoles are removed early. Behavior comparison: Command line: earlyprintk=3DttyS0 console=3DttyS0 console=3DttyS1 (ttyS1 is preferred) - Before fix: ttyS0 is enabled but lacks CON_CONSDEV -> the boot console is not unregistered. - After fix: ttyS0 is enabled -> the boot console is unconditionally unregistered. Command line: earlyprintk=3DttyS0 console=3DttyS1 console=3DttyS0 (ttyS0 is preferred, order swapped) - Before fix: ttyS1 is enabled but lacks CON_CONSDEV -> the boot console is kept. - After fix: ttyS1 is enabled -> the boot console is still unregistered. (ttyS1 will also replay the logs on printk buffer if COM2 was configured correctly, boot console on ttyS0 is no longer needed.) Command line: earlyprintk=3DttyS0 console=3Dtty0 console=3DttyS0 console=3D= ttyS1 (ttyS1 is the preferred console) - Before fix: tty0 (VGA) registers first -> the boot console remains. ttyS0 (8250) registers later -> the boot console still remains. - After fix: tty0 (VGA) registers first -> the boot console is unregistered. ttyS0 registers later -> CON_PRINTBUFFER is set -> it replays the entire ring buffer. Command line: earlyprintk=3DttyS0 keep_bootcon console=3DttyS0 or Command line: earlyprintk=3DttyS0,keep console=3DttyS0 - Before and after: the boot consoles remain. Signed-off-by: Xiaochun Li --- kernel/printk/printk.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 0323149548f6..920e27f63003 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -4207,8 +4207,7 @@ void register_console(struct console *newcon) */ con_printk(KERN_INFO, newcon, "enabled\n"); if (bootcon_registered && - ((newcon->flags & (CON_CONSDEV | CON_BOOT)) =3D=3D CON_CONSDEV) && - !keep_bootcon) { + !(newcon->flags & CON_BOOT) && !keep_bootcon) { struct hlist_node *tmp; =20 hlist_for_each_entry_safe(con, tmp, &console_list, node) { --=20 2.18.2