From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wr1-f43.google.com (mail-wr1-f43.google.com [209.85.221.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D7EB737F8C1 for ; Thu, 20 Aug 2026 15:13:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.43 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787238794; cv=none; b=jWzXyJvPeq+BQxFxHgsH+j2+0zIuFKPv1hqFQ3ycXWI2iV7nY3HG7wV/Y1nCwx0dae9oLX+sc/VnpZBwEsA0L0FXoyvAZsyuHEkOdszF4xHPTmUIbRpp7z9SgHjIXi08N0f4ZHVufcdI4OT3/PCVdfhhCwMYMRd/wCxssRbHMZk= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1787238794; c=relaxed/simple; bh=hAXZjQvqErUHBpwaDc8Nh1ofXJrn69vkhk7fvivFKEI=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=gNATqnnpSO82LqL4mcSbOwCi2g/gcBlO6fSEnh9ZwzQFprTriNeYjf6peSzCDxhaJMhs3AO1gCYWg2qLOpafw54S7zjvXup2ARTP53W2tZSdsHs1XG8CB5miQdbchP5G+PtQi4ID5tUOBrVBoA3z5kcceCe8wsix4lUHei36JsQ= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=suse.com; spf=pass smtp.mailfrom=suse.com; dkim=pass (2048-bit key) header.d=suse.com header.i=@suse.com header.b=BzKIaaeq; arc=none smtp.client-ip=209.85.221.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=suse.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=suse.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=suse.com header.i=@suse.com header.b="BzKIaaeq" Received: by mail-wr1-f43.google.com with SMTP id ffacd0b85a97d-47fd4531020so1141f8f.3 for ; Thu, 20 Aug 2026 08:13:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=google; t=1787238790; x=1787843590; darn=vger.kernel.org; h=in-reply-to:content-disposition:content-type:mime-version :references:message-id:subject:cc:to:from:date:from:to:cc:subject :date:message-id:reply-to:content-type; bh=NA59gu5DXtC+TUcVpS6BFTiXfxIW0VP7j0ioMDrD8oQ=; b=BzKIaaeqwGafupEZhBG+FBzh0QH6PuSD7l/LhpxVvgiqNYNzzrizJyYBXxwHCEV4CS GOAnMGftXtns9+aOZT5rnEcciIBE9VMgmBwpqHeZgiN3YJPLrNhPHWQiQMzzt+mG1YpR MX6CnL3mZlEtLqUKSFJeeKR1xwODCmxVGHwMBsmiorfYRe8R3fnz3dZMTvoxbYPcW7g7 cElr4bkgdjG1F4yGanJIvSs3Db+swFELkLJbw90sQ4knlpXMliPTY97a3K3NDJA0iy0G o97C69rCa2poyhy4pT8dw6HNRDuu4QYeuQbrmZn/gLjzjJ+bAyUKrXzd9HYXZMc8v/qc d6uw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787238790; x=1787843590; h=in-reply-to:content-disposition:content-type:mime-version :references:message-id:subject:cc:to:from:date:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=NA59gu5DXtC+TUcVpS6BFTiXfxIW0VP7j0ioMDrD8oQ=; b=QiZYWjJqh6Q8zmnRxdsSpBLtdBYgS1eDc1xNeXjmaNF778Z8R6wg3bF4tEWJ8AbySI a2kS5l2W79BhDV+X88uIU0RwMdagiiDXSur4Tqxxn8F72RG9tnYnPLM1v4tZzeU0GBr5 HkIs1k0HuYWDtfmGVpKqFvU/2mmxkNFM8m5f2Fy2dZc2+zywSkoy1S3tBWiXGvTi5w6m 8HfF6cNQirV6gEzbqqWkRa55rd5M+kHH3SViw9R6VK9451DwNjphEzq7EBAivN5NNAm5 IWiKIp/VYuFvL5vQMg4/WNrBBzCDIOY1zESNH2gOgplHrxIEJlXR7bMBM505bLVGW/Cm N3sQ== X-Forwarded-Encrypted: i=1; AHgh+RpcmyugNhW3g7MZpeua2rZaon4xcVGmcRB//UZoWWQ9SgysXmn/gc9z8fLrioA7eBjOnUdy07+0latY0Kw=@vger.kernel.org X-Gm-Message-State: AFuF++mHaE7yWPAtona3VUTOIp225TzXCcAcT4VLIqrgTilifd3vFZ/g WFrkkgGv8UFt8iUoQLhR+25Y5XUbCTo/2dJy5bcKkOTqvyaEbLXHaFrb+7JL15P7jonGBdqzLxo K4YW5ehA= X-Gm-Gg: AR+sD12bdBpj7erwtk2VZzDpMrQ0qCsxzy9pCUJmBr/Zy9y/wxLTKOOXtck6cchR6x7 ZFavqTZHYQrnmRQjVJrhClWYDoe0VQ/S2xH7b0jcPsy8tddxoB3sLopRwhZe6AtMUn2uK8LluVu cOuupTn/GjoXbRuPUl5SCGa/IZveDwjfReFjTjwB2DF4Wqpo8HX4IpzeJKXlNuDbgmrqjYGNKN4 jiBbm+9njUxg3ERYdD+hsRuCw8nIVzThLIqPWDtFGcUaNuFm2mmqM+rhCDF+WbgZMAZVMqW8C/7 7IxQlQjjsKyv6Ge/2ZFOpnxS78QWBWSdhedkU1wPz758b5OaI6SKRDJ2k0YqLuWSWCzhT7wWX9g dSk3PXigTAmXVyTGoyJ+9x9VV4CNXhonViLfUwPoS1+u76LuAowHdhs7kHjBkyZwNK6Be33AO8e MrpJKRAWbyjEMrSVPBVvvNgeRNuXfQEEJ98S+Od5teorB86NzFh8d44Rr+DrNXzQ== X-Received: by 2002:a05:6000:401e:b0:482:a610:7a27 with SMTP id ffacd0b85a97d-482b1ff2808mr21881556f8f.20.1787238789074; Thu, 20 Aug 2026 08:13:09 -0700 (PDT) Received: from pathway.suse.cz ([176.114.240.130]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-482b1450acdsm13689131f8f.9.2026.08.20.08.13.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Aug 2026 08:13:08 -0700 (PDT) Date: Thu, 20 Aug 2026 17:13:05 +0200 From: Petr Mladek To: Xiaochun Li Cc: rostedt@goodmis.org, john.ogness@linutronix.de, senozhatsky@chromium.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH v2] printk: Remove remaining boot consoles when a real console exists Message-ID: References: <20260805084846.1802042-1-lixiaochun@open-hieco.net> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20260805084846.1802042-1-lixiaochun@open-hieco.net> On Wed 2026-08-05 16:48:46, Xiaochun Li wrote: > Boot consoles are temporary and should be removed once a real console is > available. However, the late init cleanup currently only unregisters boot > consoles that use init section memory. Other boot consoles are expected > to be removed when the real preferred console is registered. > > This does not cover cases where a real console has registered, but the > boot console was not removed because the real console did not become the > preferred console. For example, with multiple console= parameters using > the same driver, a real 8250 console may be enabled while the early > console remains registered. The result is duplicate printk output from > both consoles. > > In the mailing list discussion, two possible approaches were suggested > to fix this problem [1]. This patch implements the first one: during > printk_late_init(), check whether at least one real console is already > registered. If so, unregister all remaining boot consoles. If no real > console exists yet, keep the existing behavior and unregister only boot > consoles that reference init section memory, avoiding a period with no > console output while waiting for a deferred or modular real console. > > Suggested-by: Petr Mladek > Link: https://lore.kernel.org/lkml/ahBsSW2bB2CRfW-k@pathway.suse.cz/ # [1] > Signed-off-by: Xiaochun Li > --- > kernel/printk/printk.c | 34 +++++++++++++++++++++++----------- > 1 file changed, 23 insertions(+), 11 deletions(-) > > diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c > index 2fe9a963c823..5a5ec7ac99bd 100644 > --- a/kernel/printk/printk.c > +++ b/kernel/printk/printk.c > @@ -4420,36 +4420,48 @@ void __init console_init(void) > * be a brief interval in which no messages are logged to the console, which > * makes it difficult to diagnose problems that occur during this time. > * > - * To mitigate this problem somewhat, only unregister consoles whose memory > - * intersects with the init section. Note that all other boot consoles will > - * get unregistered when the real preferred console is registered. > + * If a real console has already registered, remove all remaining boot consoles. > + * Otherwise, mitigate the no-console interval by removing only boot consoles > + * whose memory intersects with the init section. > */ > static int __init printk_late_init(void) > { > + bool realcon_registered = false; Nit: I would call the variable "have_real_console" to follow the existing naming scheme, see have_boot_console, have_legacy_console, ... Please, change it in v2 if we need it, ... > struct hlist_node *tmp; > struct console *con; > int ret; > > console_list_lock(); > + for_each_console(con) { > + if (!(con->flags & CON_BOOT)) { > + realcon_registered = true; > + break; > + } > + } Sashiko AI worries: | Can this cause a period of missing console output if a non-visible console | (like netconsole or pstore) registers early? I do not agree. Users are able to read the messages on netconsole or pstore, so I consider them valid real consoles. | It looks like this checks only for the absence of CON_BOOT to consider a | real console present. If a real hardware serial console is deferred or | loaded as a module later, wouldn't we need to check for CON_CONSDEV to | ensure the preferred hardware console is actually available before dropping | the boot console? It does not make much sense. The CON_CONSDEV flag does not guarantee anything. It is just the best effort to mart console which will get used by /dev/console. > hlist_for_each_entry_safe(con, tmp, &console_list, node) { > if (!(con->flags & CON_BOOT)) > continue; > > - /* Check addresses that might be used for enabled consoles. */ > - if (init_section_intersects(con, sizeof(*con)) || > - init_section_contains(con->write, 0) || > - init_section_contains(con->read, 0) || > - init_section_contains(con->device, 0) || > - init_section_contains(con->unblank, 0) || > - init_section_contains(con->data, 0)) { > + if (!realcon_registered) { > + /* Check addresses that might be used for enabled consoles. */ > + if (!init_section_intersects(con, sizeof(*con)) && > + !init_section_contains(con->write, 0) && > + !init_section_contains(con->read, 0) && > + !init_section_contains(con->device, 0) && > + !init_section_contains(con->unblank, 0) && > + !init_section_contains(con->data, 0)) > + continue; > + > /* > * Please, consider moving the reported consoles out > * of the init section. > */ > pr_warn("bootconsole [%s%d] uses init memory and must be disabled even before the real one is ready\n", > con->name, con->index); > - unregister_console_locked(con); > } > + > + unregister_console_locked(con); Another comment from Sashiko AI: | Does this unconditional unregistration bypass the keep_bootcon command-line | parameter? | | If a user boots with keep_bootcon to preserve early boot consoles for | debugging, it appears this code will bypass the keep_bootcon flag check | traditionally used in register_console() and unexpectedly unregister the | debugging consoles once a real console registers. This one describes a real problem. We have to check the "keep_bootcon" flag. I suggest something like: --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -4420,36 +4420,51 @@ void __init console_init(void) * be a brief interval in which no messages are logged to the console, which * makes it difficult to diagnose problems that occur during this time. * - * To mitigate this problem somewhat, only unregister consoles whose memory - * intersects with the init section. Note that all other boot consoles will - * get unregistered when the real preferred console is registered. + * If a real console has already registered, remove all remaining boot consoles. + * Otherwise, mitigate the no-console interval by removing only boot consoles + * whose memory intersects with the init section. */ static int __init printk_late_init(void) { + bool have_real_console = false; struct hlist_node *tmp; struct console *con; int ret; console_list_lock(); + for_each_console(con) { + if (!(con->flags & CON_BOOT)) { + have_real_console = true; + break; + } + } + hlist_for_each_entry_safe(con, tmp, &console_list, node) { if (!(con->flags & CON_BOOT)) continue; - /* Check addresses that might be used for enabled consoles. */ - if (init_section_intersects(con, sizeof(*con)) || - init_section_contains(con->write, 0) || - init_section_contains(con->read, 0) || - init_section_contains(con->device, 0) || - init_section_contains(con->unblank, 0) || - init_section_contains(con->data, 0)) { + /* + * Keep the boot console when requested or as a fallback + * unless it is using an init section. + */ + if (keep_bootcon || !have_real_console) { + if (!init_section_intersects(con, sizeof(*con)) && + !init_section_contains(con->write, 0) && + !init_section_contains(con->read, 0) && + !init_section_contains(con->device, 0) && + !init_section_contains(con->unblank, 0) && + !init_section_contains(con->data, 0)) + continue; + /* * Please, consider moving the reported consoles out * of the init section. */ pr_warn("bootconsole [%s%d] uses init memory and must be disabled even before the real one is ready\n", con->name, con->index); - unregister_console_locked(con); } + + unregister_console_locked(con); } console_list_unlock(); Best Regards, Petr