From nobody Fri Feb 13 01:43:51 2026 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 59FC483CD6 for ; Mon, 3 Jun 2024 23:24:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457098; cv=none; b=BnFI+ldy/U4X+3MXH0aXgrDpdUBPLbW06QDtpyK5gFJSQCbMQFsQizllMZLNR/sgG7AtPI49n8snsipQXOLPA902L+SvT1XLs+50DiCIFwznc3OJFtTWEHgYRTX0NDFWhtqxmgCVDqwy8C78C9R54deKOTsAcI4SNp1CNU9C2jI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457098; c=relaxed/simple; bh=cECa+3SjdlOTE2gX/SC6RHnlgdcMpIyIzBaHEsoCoOg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=dwe+wQqqVRlI00fELzY9FbXyQN6VgZgtY2eQ4swd0TbzgJ/YhhvLwvu0JyyoL493gd4/VxVh5Z3HIDtdN1PA2/9bm4f3IqgAKJaWhAQisDO+B28QIIJcUIB5oLflbZuaI8HIjjU2YTsSr9FvCo8w2DsjfNY99c91hJuoi9PpGNM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=oghpHSL8; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=nfih29kq; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="oghpHSL8"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="nfih29kq" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1717457094; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=MagFz0dSmih1ouwvcZhD1e4AjKfdqWGnWa+U9V8bzUA=; b=oghpHSL8Md05RhYJnw+s1/rEBskGHpRL4CtGg+kzqFfDlUBPBUbXvFvvl0np/HA07I5S7o Od0/3yUeJPufENXQ8eWiiHYzTJRQvXsx1XIi/wsw2i5aD3sCVRhDkEDUftJDwOtU5i9/aS eefYElhpq6uQD0ikIcd11yH9w5a9KhBypdBBiAnvKMfC1suHySxT0cggNRbhGll2+zrDH+ RdNvJDsSXEypdV3NJ1lHJxAvFDCEIcJJIwevnlxLM0zRWiq6YGoCdDHuVc9wuCT/Jcoqc2 99/UJZIr7Wky6r4Xob7JxbxrXmTLMnt3k8rThBBHTzlNu38voBNEUs5W923DTg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1717457094; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=MagFz0dSmih1ouwvcZhD1e4AjKfdqWGnWa+U9V8bzUA=; b=nfih29kqBhIy6PnEMCliMKzgUbUGMU03eZS9z2x6RzAbHs4eVTWrXtMSWx6XjxW67QOxEh zXbOOy2vhPeJUOBQ== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Sreenath Vijayan , Shimoyashiki Taichi , Greg Kroah-Hartman Subject: [PATCH printk v2 01/18] printk: Add function to replay kernel log on consoles Date: Tue, 4 Jun 2024 01:30:36 +0206 Message-Id: <20240603232453.33992-2-john.ogness@linutronix.de> In-Reply-To: <20240603232453.33992-1-john.ogness@linutronix.de> References: <20240603232453.33992-1-john.ogness@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Sreenath Vijayan Add a generic function console_replay_all() for replaying the kernel log on consoles, in any context. It would allow viewing the logs on an unresponsive terminal via sysrq. Reuse the existing code from console_flush_on_panic() for resetting the sequence numbers, by introducing a new helper function __console_rewind_all(). It is safe to be called under console_lock(). Try to acquire lock on the console subsystem without waiting. If successful, reset the sequence number to oldest available record on all consoles and call console_unlock() which will automatically flush the messages to the consoles. Suggested-by: John Ogness Suggested-by: Petr Mladek Signed-off-by: Shimoyashiki Taichi Reviewed-by: John Ogness Signed-off-by: Sreenath Vijayan Link: https://lore.kernel.org/r/90ee131c643a5033d117b556c0792de65129d4c3.17= 10220326.git.sreenath.vijayan@sony.com Signed-off-by: Greg Kroah-Hartman --- include/linux/printk.h | 6 +++- kernel/printk/printk.c | 77 +++++++++++++++++++++++++++++------------- 2 files changed, 58 insertions(+), 25 deletions(-) diff --git a/include/linux/printk.h b/include/linux/printk.h index 69f40a71c438..784d2298f4cf 100644 --- a/include/linux/printk.h +++ b/include/linux/printk.h @@ -195,6 +195,7 @@ void show_regs_print_info(const char *log_lvl); extern asmlinkage void dump_stack_lvl(const char *log_lvl) __cold; extern asmlinkage void dump_stack(void) __cold; void printk_trigger_flush(void); +void console_replay_all(void); void printk_legacy_allow_panic_sync(void); extern bool nbcon_device_try_acquire(struct console *con); extern void nbcon_device_release(struct console *con); @@ -279,6 +280,10 @@ static inline void printk_trigger_flush(void) { } =20 +static inline void console_replay_all(void) +{ +} + static inline void printk_legacy_allow_panic_sync(void) { } @@ -295,7 +300,6 @@ static inline void nbcon_device_release(struct console = *con) static inline void nbcon_atomic_flush_unsafe(void) { } - #endif =20 bool this_cpu_in_panic(void); diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index b4a202591e06..b3fe1b6d7dbd 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -3201,6 +3201,40 @@ void console_unblank(void) pr_flush(1000, true); } =20 +/* + * Rewind all consoles to the oldest available record. + * + * IMPORTANT: The function is safe only when called under + * console_lock(). It is not enforced because + * it is used as a best effort in panic(). + */ +static void __console_rewind_all(void) +{ + struct console *c; + short flags; + int cookie; + u64 seq; + + seq =3D prb_first_valid_seq(prb); + + cookie =3D console_srcu_read_lock(); + for_each_console_srcu(c) { + flags =3D console_srcu_read_flags(c); + + if (flags & CON_NBCON) { + nbcon_seq_force(c, seq); + } else { + /* + * This assignment is safe only when called under + * console_lock(). On panic, legacy consoles are + * only best effort. + */ + c->seq =3D seq; + } + } + console_srcu_read_unlock(cookie); +} + /** * console_flush_on_panic - flush console content on panic * @mode: flush all messages in buffer or just the pending ones @@ -3229,30 +3263,8 @@ void console_flush_on_panic(enum con_flush_mode mode) */ console_may_schedule =3D 0; =20 - if (mode =3D=3D CONSOLE_REPLAY_ALL) { - struct console *c; - short flags; - int cookie; - u64 seq; - - seq =3D prb_first_valid_seq(prb); - - cookie =3D console_srcu_read_lock(); - for_each_console_srcu(c) { - flags =3D console_srcu_read_flags(c); - - if (flags & CON_NBCON) { - nbcon_seq_force(c, seq); - } else { - /* - * This is an unsynchronized assignment. On - * panic legacy consoles are only best effort. - */ - c->seq =3D seq; - } - } - console_srcu_read_unlock(cookie); - } + if (mode =3D=3D CONSOLE_REPLAY_ALL) + __console_rewind_all(); =20 nbcon_atomic_flush_pending(); =20 @@ -4447,6 +4459,23 @@ void kmsg_dump_rewind(struct kmsg_dump_iter *iter) } EXPORT_SYMBOL_GPL(kmsg_dump_rewind); =20 +/** + * console_replay_all - replay kernel log on consoles + * + * Try to obtain lock on console subsystem and replay all + * available records in printk buffer on the consoles. + * Does nothing if lock is not obtained. + * + * Context: Any context. + */ +void console_replay_all(void) +{ + if (console_trylock()) { + __console_rewind_all(); + /* Consoles are flushed as part of console_unlock(). */ + console_unlock(); + } +} #endif =20 #ifdef CONFIG_SMP --=20 2.39.2 From nobody Fri Feb 13 01:43:51 2026 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 A123483CDA for ; Mon, 3 Jun 2024 23:24:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457098; cv=none; b=ESKDFjY/dl54GEYsm4x3fO0EtxypordzQrTMGPAagMBfmmxyrLBxjt0/ffcDle1HL7xBJdjftRh0FKtpRFJ8mHiG/FADri9HPLOpEC9XLuS6EsPwXflP0E4sZos24tzO2s7+L1MCwtAVbLh1yR/+eooUM4VKBHMTRMu4dwTVw8A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457098; c=relaxed/simple; bh=CoTDXitrRtg3CKYBOFPhiaN3QDoc7MLZcZ6bNPspfck=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=AtK8pEyCQvJmQCLMvwh5VoSQjmG83I9REP2twPcML62ifpAaLPL8wDp9F8dfZDxMpHDZTV3Prz5FomXo/WD2uXR9iPANOynPUiQLyKjZdMeYa2ca6JpbAuxHDHzDMxZB2rw4aYeBB5viy/sBqe2quIDI5Q1BddMUi+3WEsJNUMc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=Hrgq7isc; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=ghjOLD7U; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="Hrgq7isc"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="ghjOLD7U" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1717457095; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=O88lJwD2wns3puq6qL3k1pydNocnLUHn2VIM40iN7Rs=; b=Hrgq7iscYvfmYK7gGW1ZSeX3H9rKcAChumT5PRUonNJE2RGWhpAJuV0afVZwPi8iHs80lC S98zNxS5gd+Vx3algVCU+3VFOkDuJCROuYqRbgTZl91rYM1/dsz8GLtT/OSInNsycR8+19 CeYe2qee+rF8Wb/sqV9+e7krEn64pARFymempzUDgdUIiUyCVi73LUbjfita6cF8maU3Am VqiFmmAswPYGn5ZaIdkHOvLlbaN8H8IoItLhsGjzEOcxnb+4DNexvA21DaBqJgSrnsS0TX 1LwHebWUEp8FIRLdnrYu3m/4B7383U0WHyXudO5Yjj8GeR72ykqLUuctdpskOg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1717457095; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=O88lJwD2wns3puq6qL3k1pydNocnLUHn2VIM40iN7Rs=; b=ghjOLD7UlFmG04LeAsYE6SUgGmx+FhDrWVj4JpVjn2OjvmviUXFnj9PAnwa0fZpuQeWrri COl1GlrT/fLkN+CQ== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Sreenath Vijayan , Shimoyashiki Taichi , Greg Kroah-Hartman Subject: [PATCH printk v2 02/18] tty/sysrq: Replay kernel log messages on consoles via sysrq Date: Tue, 4 Jun 2024 01:30:37 +0206 Message-Id: <20240603232453.33992-3-john.ogness@linutronix.de> In-Reply-To: <20240603232453.33992-1-john.ogness@linutronix.de> References: <20240603232453.33992-1-john.ogness@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Sreenath Vijayan When terminal is unresponsive, one cannot use dmesg to view the printk ring buffer messages. Also, syslog services may be disabled, especially on embedded systems, to check the messages after a reboot. In this scenario, replay the messages in printk ring buffer on consoles via sysrq by pressing sysrq+R. The console loglevel will determine which all kernel log messages are displayed. The messages will be displayed only when console_trylock() succeeds. Users could repeat the sysrq key when it fails. If the owner of console subsystem lock is stuck, repeating the key won't work. Suggested-by: Petr Mladek Signed-off-by: Shimoyashiki Taichi Reviewed-by: John Ogness Signed-off-by: Sreenath Vijayan Link: https://lore.kernel.org/r/cc3b9b1aae60a236c6aed1dc7b0ffa2c7cd1f183.17= 10220326.git.sreenath.vijayan@sony.com Signed-off-by: Greg Kroah-Hartman --- Documentation/admin-guide/sysrq.rst | 9 +++++++++ drivers/tty/sysrq.c | 13 ++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/Documentation/admin-guide/sysrq.rst b/Documentation/admin-guid= e/sysrq.rst index 2f2e5bd440f9..a85b3384d1e7 100644 --- a/Documentation/admin-guide/sysrq.rst +++ b/Documentation/admin-guide/sysrq.rst @@ -161,6 +161,8 @@ Command Function will be printed to your console. (``0``, for example would make it so that only emergency messages like PANICs or OOPSes would make it to your console.) + +``R`` Replay the kernel log messages on consoles. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D =20 Okay, so what can I use them for? @@ -211,6 +213,13 @@ processes. "just thaw ``it(j)``" is useful if your system becomes unresponsive due to= a frozen (probably root) filesystem via the FIFREEZE ioctl. =20 +``Replay logs(R)`` is useful to view the kernel log messages when system i= s hung +or you are not able to use dmesg command to view the messages in printk bu= ffer. +User may have to press the key combination multiple times if console syste= m is +busy. If it is completely locked up, then messages won't be printed. Output +messages depend on current console loglevel, which can be modified using +sysrq[0-9] (see above). + Sometimes SysRq seems to get 'stuck' after using it, what can I do? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ =20 diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index 02217e3c916b..e5974b8239c9 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c @@ -450,6 +450,17 @@ static const struct sysrq_key_op sysrq_unrt_op =3D { .enable_mask =3D SYSRQ_ENABLE_RTNICE, }; =20 +static void sysrq_handle_replay_logs(u8 key) +{ + console_replay_all(); +} +static struct sysrq_key_op sysrq_replay_logs_op =3D { + .handler =3D sysrq_handle_replay_logs, + .help_msg =3D "replay-kernel-logs(R)", + .action_msg =3D "Replay kernel logs on consoles", + .enable_mask =3D SYSRQ_ENABLE_DUMP, +}; + /* Key Operations table and lock */ static DEFINE_SPINLOCK(sysrq_key_table_lock); =20 @@ -519,7 +530,7 @@ static const struct sysrq_key_op *sysrq_key_table[62] = =3D { NULL, /* O */ NULL, /* P */ NULL, /* Q */ - NULL, /* R */ + &sysrq_replay_logs_op, /* R */ NULL, /* S */ NULL, /* T */ NULL, /* U */ --=20 2.39.2 From nobody Fri Feb 13 01:43:51 2026 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 AFEB483CDC for ; Mon, 3 Jun 2024 23:24:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457099; cv=none; b=E/rMNqjraj5SBJDnuO6DlDqzWUbkRktEwftGQIcKv91pqV+tmsKjBCCcQpeqHzOi82xE9+4/hm9WmDfM0wpeZcWrSwu7ZoW+SweVu2kT4bJUDUgNgkUpLCQ8jHs55NEkArVWLk4ua0+3mPp1WCZPpHQZr6T+NtTofXCgBosF5Ng= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457099; c=relaxed/simple; bh=H5QlAlECNprYLrNRQeJIyWXcYhJVcMnspTIa3/fXvfg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=okvEblFU87IERi9ztQDw1JCugn1KpdfSr/ZoMrpDpnXF3YdbtgOyLRn8h5x879G8Olm43aqr720e517uizBbeUxrmJCnEJWCxQ3HMCYk/GWz2ePrrV/rpiGLmCG33eZ6v1EgR4YM7s8TJhUZg0SOP4h2DmPziGQRv1W3QtHV7Rs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=u3XmvNih; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=idnfsnZA; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="u3XmvNih"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="idnfsnZA" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1717457095; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=BpQSbTrOL8EbyodmIDDlAP8Rc/tLKsI5HokOE/M69OM=; b=u3XmvNihKfrTxt4EoQtYUJsuYjXE9hrnlrkGwC8oi5dPhZEZoo+BD0bMYRbKkQ2wfbGrw8 CbHEqbVfKDlwlIU912YM5Ebt9TsT88kdQh3nwdP/8fXh/b4AyGzCdpUQ8bPRqJ1A0Np95b 2zGBW0muzJxj1OdGhTHliF8MKC2zKrIz/x5FEp/opogVJq1u9w1jool9UfbtvQmmmDNzFW pxsm5gM9sNtd2IGb+pcGF48Buy4Pl16e/KBWhuCPJJg6Fnf3WTsL0yTSgL/ifgE8izYnxp 6R7p7kF1EouwY8SLN+oszSahfCV4Y9UnyF3iBhxNjA2WlaybaDcWQKYfrVb8Aw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1717457095; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=BpQSbTrOL8EbyodmIDDlAP8Rc/tLKsI5HokOE/M69OM=; b=idnfsnZAzIcpW0ceZivFHDsf4DDEHPTdcve0XifhuamXG2AIo9ODP2Idg46NYZIP3ki8TH 05qXqfi/T9mHp0Cg== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Sreenath Vijayan , Shimoyashiki Taichi Subject: [PATCH printk v2 03/18] printk: Rename console_replay_all() and update context Date: Tue, 4 Jun 2024 01:30:38 +0206 Message-Id: <20240603232453.33992-4-john.ogness@linutronix.de> In-Reply-To: <20240603232453.33992-1-john.ogness@linutronix.de> References: <20240603232453.33992-1-john.ogness@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Sreenath Vijayan Rename console_replay_all() to console_try_replay_all() to make clear that the implementation is best effort. Also, the function should not be called in NMI context as it takes locks, so update the comment in code. Fixes: 693f75b91a91 ("printk: Add function to replay kernel log on consoles= ") Fixes: 1b743485e27f ("tty/sysrq: Replay kernel log messages on consoles via= sysrq") Suggested-by: Petr Mladek Signed-off-by: Shimoyashiki Taichi Signed-off-by: Sreenath Vijayan Link: https://lore.kernel.org/r/Zlguq/wU21Z8MqI4@sreenath.vijayan@sony.com Reviewed-by: Petr Mladek Signed-off-by: Petr Mladek --- drivers/tty/sysrq.c | 2 +- include/linux/printk.h | 4 ++-- kernel/printk/printk.c | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index e5974b8239c9..53f8c2329c30 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c @@ -452,7 +452,7 @@ static const struct sysrq_key_op sysrq_unrt_op =3D { =20 static void sysrq_handle_replay_logs(u8 key) { - console_replay_all(); + console_try_replay_all(); } static struct sysrq_key_op sysrq_replay_logs_op =3D { .handler =3D sysrq_handle_replay_logs, diff --git a/include/linux/printk.h b/include/linux/printk.h index 784d2298f4cf..20e1942f63ae 100644 --- a/include/linux/printk.h +++ b/include/linux/printk.h @@ -195,7 +195,7 @@ void show_regs_print_info(const char *log_lvl); extern asmlinkage void dump_stack_lvl(const char *log_lvl) __cold; extern asmlinkage void dump_stack(void) __cold; void printk_trigger_flush(void); -void console_replay_all(void); +void console_try_replay_all(void); void printk_legacy_allow_panic_sync(void); extern bool nbcon_device_try_acquire(struct console *con); extern void nbcon_device_release(struct console *con); @@ -280,7 +280,7 @@ static inline void printk_trigger_flush(void) { } =20 -static inline void console_replay_all(void) +static inline void console_try_replay_all(void) { } =20 diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index b3fe1b6d7dbd..5dcc05e1aa56 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -4460,15 +4460,15 @@ void kmsg_dump_rewind(struct kmsg_dump_iter *iter) EXPORT_SYMBOL_GPL(kmsg_dump_rewind); =20 /** - * console_replay_all - replay kernel log on consoles + * console_try_replay_all - try to replay kernel log on consoles * * Try to obtain lock on console subsystem and replay all * available records in printk buffer on the consoles. * Does nothing if lock is not obtained. * - * Context: Any context. + * Context: Any, except for NMI. */ -void console_replay_all(void) +void console_try_replay_all(void) { if (console_trylock()) { __console_rewind_all(); --=20 2.39.2 From nobody Fri Feb 13 01:43:51 2026 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 AFEFD84055 for ; Mon, 3 Jun 2024 23:24:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457099; cv=none; b=PjWyYWZs7mhx9JXp8S1LO3SPHF0pINHHEre7YOCmyuS1iAfFzFD+1ZKnOCGITlBVSuhVmquXC0nB7lLQbnM04Jzexuxhm+IPdJyO7iFK9OcjRokIRbU6DShat3rv1vw6yhVOtAfnZp35LK5gB6Q7A3RufHm3v3GGT7Ba452Tvbs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457099; c=relaxed/simple; bh=NSaVOQhSTnclzA6rY6xD2+shZ2o9qkgaV4DJcysn+uk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=WQEi3xqIuF5Ji9Y3ustT/jMZTRKqOMCo3UzmvJULVF0hFi53TMcVnvNQrYpG6r646CH5ss4knUdmgN1DDp9hY6s/Xl8XSGolQKPPLEV/3zf2T0Uv+ipej1BXup9HC8aJT7P452coiH2nYr2+NDwFRsc99Vr832LYbWUsjUUaLXw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=YmtOfsD0; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=POSMtXLS; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="YmtOfsD0"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="POSMtXLS" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1717457096; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=UKN9r+PRgpHVMNbBU6w+eKxqiQXlpWlE2QqLIxrbuYo=; b=YmtOfsD0eK3GFH/+wDPV2mIMRLzF807TH66SxA0dovV0WQiDHzNgiEzjISOBMfklwtgZKQ Vcz5BthXEE+vNi9ANkmuwTTozXj+1eaRg4ArQjULcWqf4ZYOCUyvZe4WG+LPp7NFVj3cDw 85OiQoHWV/t7JWbW0BgwxCv00ObFLJ5FB66jCP8lMJdj/UmUAVRENtzGgFzuHEOXjnJCZy 0Y+a79P3gIQu7+PpN8a7D18CjOQoz2unoWYXM5xXxzYA8IFieXSpp6S+hGI55RvZUfC6K2 VmWJv65Abqy1rbW0E45OrHL1hyb8E7nOfRlsyTub+7JAW1wiLFeL8TdHjqgYRQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1717457096; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=UKN9r+PRgpHVMNbBU6w+eKxqiQXlpWlE2QqLIxrbuYo=; b=POSMtXLSm3r30QWPhY0he1UV1lP5q7w8l6I84G6MwdtLioDgF7nzW4TafHzHyYtrtrg57b fu1DqRv25U8dPgCA== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Greg Kroah-Hartman Subject: [PATCH printk v2 04/18] printk: nbcon: Introduce printing kthreads Date: Tue, 4 Jun 2024 01:30:39 +0206 Message-Id: <20240603232453.33992-5-john.ogness@linutronix.de> In-Reply-To: <20240603232453.33992-1-john.ogness@linutronix.de> References: <20240603232453.33992-1-john.ogness@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner Provide the main implementation for running a printer kthread per nbcon console that is takeover/handover aware. Co-developed-by: John Ogness Signed-off-by: John Ogness Signed-off-by: Thomas Gleixner (Intel) --- include/linux/console.h | 26 ++++++ kernel/printk/internal.h | 26 ++++++ kernel/printk/nbcon.c | 196 +++++++++++++++++++++++++++++++++++++-- kernel/printk/printk.c | 34 +++++++ 4 files changed, 275 insertions(+), 7 deletions(-) diff --git a/include/linux/console.h b/include/linux/console.h index 4aaf053840ee..4de42ec1527c 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include =20 @@ -324,6 +325,8 @@ struct nbcon_write_context { * @nbcon_seq: Sequence number of the next record for nbcon to print * @nbcon_device_ctxt: Context available for non-printing operations * @pbufs: Pointer to nbcon private buffer + * @kthread: Printer kthread for this console + * @rcuwait: RCU-safe wait object for @kthread waking */ struct console { char name[16]; @@ -373,6 +376,27 @@ struct console { */ void (*write_atomic)(struct console *con, struct nbcon_write_context *wct= xt); =20 + /** + * @write_thread: + * + * NBCON callback to write out text in task context. + * + * This callback is called after device_lock() and with the nbcon + * console acquired. Any necessary driver synchronization should have + * been performed by the device_lock() callback. + * + * This callback is always called from task context but with migration + * disabled. + * + * The same criteria for console ownership verification and unsafe + * sections applies as with write_atomic(). The difference between + * this callback and write_atomic() is that this callback is used + * during normal operation and is always called from task context. + * This allows drivers to operate in their own locking context for + * synchronizing output to the hardware. + */ + void (*write_thread)(struct console *con, struct nbcon_write_context *wct= xt); + /** * @device_lock: * @@ -420,6 +444,8 @@ struct console { atomic_long_t __private nbcon_seq; struct nbcon_context __private nbcon_device_ctxt; struct printk_buffers *pbufs; + struct task_struct *kthread; + struct rcuwait rcuwait; }; =20 #ifdef CONFIG_LOCKDEP diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h index 0439cf2fdc22..38680c6b2b39 100644 --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h @@ -92,6 +92,7 @@ enum nbcon_prio nbcon_get_default_prio(void); void nbcon_atomic_flush_pending(void); bool nbcon_legacy_emit_next_record(struct console *con, bool *handover, int cookie); +void nbcon_kthread_create(struct console *con); =20 /* * Check if the given console is currently capable and allowed to print @@ -110,6 +111,8 @@ static inline bool console_is_usable(struct console *co= n, short flags) if (flags & CON_NBCON) { if (!con->write_atomic) return false; + if (!con->write_thread) + return false; } else { if (!con->write) return false; @@ -126,12 +129,35 @@ static inline bool console_is_usable(struct console *= con, short flags) return true; } =20 +/** + * nbcon_kthread_wake - Wake up a printk thread + * @con: Console to operate on + */ +static inline void nbcon_kthread_wake(struct console *con) +{ + /* + * Guarantee any new records can be seen by tasks preparing to wait + * before this context checks if the rcuwait is empty. + * + * The full memory barrier in rcuwait_wake_up() pairs with the full + * memory barrier within set_current_state() of + * ___rcuwait_wait_event(), which is called after prepare_to_rcuwait() + * adds the waiter but before it has checked the wait condition. + * + * This pairs with nbcon_kthread_func:A. + */ + rcuwait_wake_up(&con->rcuwait); /* LMM(nbcon_kthread_wake:A) */ +} + #else =20 #define PRINTK_PREFIX_MAX 0 #define PRINTK_MESSAGE_MAX 0 #define PRINTKRB_RECORD_MAX 0 =20 +static inline void nbcon_kthread_wake(struct console *con) { } +static inline void nbcon_kthread_create(struct console *con) { } + /* * In !PRINTK builds we still export console_sem * semaphore and some of console functions (console_unlock()/etc.), so diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c index 6e9e24aa0a7f..89b340ca303c 100644 --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -837,6 +838,7 @@ EXPORT_SYMBOL_GPL(nbcon_exit_unsafe); /** * nbcon_emit_next_record - Emit a record in the acquired context * @wctxt: The write context that will be handed to the write function + * @use_atomic: True if the write_atomic() callback is to be used * * Return: True if this context still owns the console. False if * ownership was handed over or taken. @@ -850,7 +852,7 @@ EXPORT_SYMBOL_GPL(nbcon_exit_unsafe); * When true is returned, @wctxt->ctxt.backlog indicates whether there are * still records pending in the ringbuffer, */ -static bool nbcon_emit_next_record(struct nbcon_write_context *wctxt) +static bool nbcon_emit_next_record(struct nbcon_write_context *wctxt, bool= use_atomic) { struct nbcon_context *ctxt =3D &ACCESS_PRIVATE(wctxt, ctxt); struct console *con =3D ctxt->console; @@ -899,8 +901,14 @@ static bool nbcon_emit_next_record(struct nbcon_write_= context *wctxt) nbcon_state_read(con, &cur); wctxt->unsafe_takeover =3D cur.unsafe_takeover; =20 - if (con->write_atomic) { + if (use_atomic && + con->write_atomic) { con->write_atomic(con, wctxt); + + } else if (!use_atomic && + con->write_thread) { + con->write_thread(con, wctxt); + } else { /* * This function should never be called for legacy consoles. @@ -936,6 +944,120 @@ static bool nbcon_emit_next_record(struct nbcon_write= _context *wctxt) return nbcon_context_exit_unsafe(ctxt); } =20 +/** + * nbcon_kthread_should_wakeup - Check whether a printer thread should wak= eup + * @con: Console to operate on + * @ctxt: The nbcon context from nbcon_context_try_acquire() + * + * Return: True if the thread should shutdown or if the console is + * allowed to print and a record is available. False otherwise. + * + * After the thread wakes up, it must first check if it should shutdown be= fore + * attempting any printing. + */ +static bool nbcon_kthread_should_wakeup(struct console *con, struct nbcon_= context *ctxt) +{ + bool ret =3D false; + short flags; + int cookie; + + if (kthread_should_stop()) + return true; + + cookie =3D console_srcu_read_lock(); + + flags =3D console_srcu_read_flags(con); + if (console_is_usable(con, flags)) { + /* Bring the sequence in @ctxt up to date */ + ctxt->seq =3D nbcon_seq_read(con); + + ret =3D prb_read_valid(prb, ctxt->seq, NULL); + } + + console_srcu_read_unlock(cookie); + return ret; +} + +/** + * nbcon_kthread_func - The printer thread function + * @__console: Console to operate on + * + * Return: 0 + */ +static int nbcon_kthread_func(void *__console) +{ + struct console *con =3D __console; + struct nbcon_write_context wctxt =3D { + .ctxt.console =3D con, + .ctxt.prio =3D NBCON_PRIO_NORMAL, + }; + struct nbcon_context *ctxt =3D &ACCESS_PRIVATE(&wctxt, ctxt); + short con_flags; + bool backlog; + int cookie; + int ret; + +wait_for_event: + /* + * Guarantee this task is visible on the rcuwait before + * checking the wake condition. + * + * The full memory barrier within set_current_state() of + * ___rcuwait_wait_event() pairs with the full memory + * barrier within rcuwait_has_sleeper(). + * + * This pairs with rcuwait_has_sleeper:A and nbcon_kthread_wake:A. + */ + ret =3D rcuwait_wait_event(&con->rcuwait, + nbcon_kthread_should_wakeup(con, ctxt), + TASK_INTERRUPTIBLE); /* LMM(nbcon_kthread_func:A) */ + + if (kthread_should_stop()) + return 0; + + /* Wait was interrupted by a spurious signal, go back to sleep. */ + if (ret) + goto wait_for_event; + + do { + backlog =3D false; + + cookie =3D console_srcu_read_lock(); + + con_flags =3D console_srcu_read_flags(con); + + if (console_is_usable(con, con_flags)) { + unsigned long lock_flags; + + con->device_lock(con, &lock_flags); + + /* + * Ensure this stays on the CPU to make handover and + * takeover possible. + */ + cant_migrate(); + + if (nbcon_context_try_acquire(ctxt)) { + /* + * If the emit fails, this context is no + * longer the owner. + */ + if (nbcon_emit_next_record(&wctxt, false)) { + nbcon_context_release(ctxt); + backlog =3D ctxt->backlog; + } + } + + con->device_unlock(con, lock_flags); + } + + console_srcu_read_unlock(cookie); + + } while (backlog); + + goto wait_for_event; +} + /* Track the nbcon emergency nesting per CPU. */ static DEFINE_PER_CPU(unsigned int, nbcon_pcpu_emergency_nesting); static unsigned int early_nbcon_pcpu_emergency_nesting __initdata; @@ -1012,7 +1134,7 @@ static bool nbcon_atomic_emit_one(struct nbcon_write_= context *wctxt) * The higher priority printing context takes over responsibility * to print the pending records. */ - if (!nbcon_emit_next_record(wctxt)) + if (!nbcon_emit_next_record(wctxt, true)) return false; =20 nbcon_context_release(ctxt); @@ -1113,7 +1235,7 @@ static int __nbcon_atomic_flush_pending_con(struct co= nsole *con, u64 stop_seq, * handed over or taken over. In both cases the context is no * longer valid. */ - if (!nbcon_emit_next_record(&wctxt)) + if (!nbcon_emit_next_record(&wctxt, true)) return -EAGAIN; =20 if (!ctxt->backlog) { @@ -1172,10 +1294,10 @@ static void nbcon_atomic_flush_pending_con(struct c= onsole *con, u64 stop_seq, =20 /* * If flushing was successful but more records are available, this - * context must flush those remaining records because there is no - * other context that will do it. + * context must flush those remaining records if the printer thread + * is not available do it. */ - if (prb_read_valid(prb, nbcon_seq_read(con), NULL)) { + if (!con->kthread && prb_read_valid(prb, nbcon_seq_read(con), NULL)) { stop_seq =3D prb_next_reserve_seq(prb); goto again; } @@ -1332,6 +1454,63 @@ void nbcon_cpu_emergency_flush(void) } } =20 +/* + * nbcon_kthread_stop - Stop a printer thread + * @con: Console to operate on + */ +static void nbcon_kthread_stop(struct console *con) +{ + lockdep_assert_console_list_lock_held(); + + if (!con->kthread) + return; + + kthread_stop(con->kthread); + con->kthread =3D NULL; +} + +/** + * nbcon_kthread_create - Create a printer thread + * @con: Console to operate on + * + * If it fails, let the console proceed. The atomic part might + * be usable and useful. + */ +void nbcon_kthread_create(struct console *con) +{ + struct task_struct *kt; + + lockdep_assert_console_list_lock_held(); + + if (!(con->flags & CON_NBCON) || !con->write_thread) + return; + + if (con->kthread) + return; + + /* + * Printer threads cannot be started as long as any boot console is + * registered because there is no way to synchronize the hardware + * registers between boot console code and regular console code. + */ + if (have_boot_console) + return; + + kt =3D kthread_run(nbcon_kthread_func, con, "pr/%s%d", con->name, con->in= dex); + if (IS_ERR(kt)) { + con_printk(KERN_ERR, con, "failed to start printing thread\n"); + return; + } + + con->kthread =3D kt; + + /* + * It is important that console printing threads are scheduled + * shortly after a printk call and with generous runtime budgets. + */ + sched_set_normal(con->kthread, -20); +} + /** * nbcon_alloc - Allocate buffers needed by the nbcon console * @con: Console to allocate buffers for @@ -1377,6 +1556,7 @@ void nbcon_init(struct console *con, u64 init_seq) /* nbcon_alloc() must have been called and successful! */ BUG_ON(!con->pbufs); =20 + rcuwait_init(&con->rcuwait); nbcon_seq_force(con, init_seq); nbcon_state_set(con, &state); } @@ -1389,6 +1569,7 @@ void nbcon_free(struct console *con) { struct nbcon_state state =3D { }; =20 + nbcon_kthread_stop(con); nbcon_state_set(con, &state); =20 /* Boot consoles share global printk buffers. */ @@ -1458,6 +1639,7 @@ void nbcon_device_release(struct console *con) */ cookie =3D console_srcu_read_lock(); if (console_is_usable(con, console_srcu_read_flags(con)) && + !con->kthread && prb_read_valid(prb, nbcon_seq_read(con), NULL)) { __nbcon_atomic_flush_pending_con(con, prb_next_reserve_seq(prb), false); } diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 5dcc05e1aa56..137bd9a721c4 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -2685,6 +2685,8 @@ void suspend_console(void) void resume_console(void) { struct console *con; + short flags; + int cookie; =20 if (!console_suspend_enabled) return; @@ -2701,6 +2703,14 @@ void resume_console(void) */ synchronize_srcu(&console_srcu); =20 + cookie =3D console_srcu_read_lock(); + for_each_console_srcu(con) { + flags =3D console_srcu_read_flags(con); + if (flags & CON_NBCON) + nbcon_kthread_wake(con); + } + console_srcu_read_unlock(cookie); + pr_flush(1000, true); } =20 @@ -3021,6 +3031,13 @@ static bool console_flush_all(bool do_cond_resched, = u64 *next_seq, bool *handove u64 printk_seq; bool progress; =20 + /* + * console_flush_all() is only for legacy consoles, + * unless the nbcon console has no kthread printer. + */ + if ((flags & CON_NBCON) && con->kthread) + continue; + if (!console_is_usable(con, flags)) continue; any_usable =3D true; @@ -3326,9 +3343,26 @@ EXPORT_SYMBOL(console_stop); =20 void console_start(struct console *console) { + short flags; + int cookie; + console_list_lock(); console_srcu_write_flags(console, console->flags | CON_ENABLED); console_list_unlock(); + + /* + * Ensure that all SRCU list walks have completed. The related + * printing context must be able to see it is enabled so that + * it is guaranteed to wake up and resume printing. + */ + synchronize_srcu(&console_srcu); + + cookie =3D console_srcu_read_lock(); + flags =3D console_srcu_read_flags(console); + if (flags & CON_NBCON) + nbcon_kthread_wake(console); + console_srcu_read_unlock(cookie); + __pr_flush(console, 1000, true); } EXPORT_SYMBOL(console_start); --=20 2.39.2 From nobody Fri Feb 13 01:43:51 2026 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 6F2CC13D2B6 for ; Mon, 3 Jun 2024 23:24:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457101; cv=none; b=ctYBUu8ZCn1ukvgVt7Ni7jgguVvbphu7GSvqv+wivIC62r1CLmYtKsI9xVrQvS/KGgf72EOgQXDule8c5FQVLsoBf+B8TR/DANru7GvSZCSy9QqPAa/6kz6z4+h2ALw5Gx413sbHcssaMJqHKTOr1KGq9LsvnxNF0SjQaOPL0yg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457101; c=relaxed/simple; bh=nJLUOO0kFbQq0mpsWpx/7kA8MXGjckBsDAJO8NTpM6E=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=imtgu7wmBanP3AWaxQE586I36OTGsMNELklUYS+u6GmFDqr2ISclFRi/V8cAPBrT2HHqa5WZuFW2I0eBMCy8Aq1zGwunHWkmbDWIPNWEyWbkesEF0cfaOAMqPrc9t2OskqCtw3aP0GBwFTLrNxTFhMqodduJ1o1di7Fs2/Sq3tM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=qV+sNGum; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=Odj4u7ry; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="qV+sNGum"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="Odj4u7ry" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1717457096; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Dj4gOrMYbFMlZqhfQ1sjWqCRmrh47Yb6HFMI47V4kYM=; b=qV+sNGumgD9wkX7Nv8ydFkhKqx9YqMjfbJ8zEq9ngIMylq4Ev76annalIm9kksCu5+HfFe 0bcAvNygHFrlh7zvE6jGtoYi4KYzHR6sp2GJqMGu4+lF98mLP5nURHdvjCePu++MhXEeQR SLGZyZwKYcgvKGBF+HG6MkWwVeoJJ2e4LTiABIe2yitQ6PUE8unOk6yizO38mtQowL4qcU 9PsiFmgPDTouoagtWYmpOL4GKX04VPKBBCzyeD243BnH7Ige0D9N2YZjYxPZob2j3psozW 9Ps1+Vvpi5MKDkaLpT92WQmSiwqeCRTqDALqIpGCWPsv5WIYC/IHDsBkHhK1nw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1717457096; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Dj4gOrMYbFMlZqhfQ1sjWqCRmrh47Yb6HFMI47V4kYM=; b=Odj4u7ryDDsbcjDhjQhN0ZkCrkfM7T/t16qNZj1P56qCxrpCFxqIIbSVXKctpwrhWkRXmg t4hFUzIaZ+YnuQDw== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v2 05/18] printk: Atomic print in printk context on shutdown Date: Tue, 4 Jun 2024 01:30:40 +0206 Message-Id: <20240603232453.33992-6-john.ogness@linutronix.de> In-Reply-To: <20240603232453.33992-1-john.ogness@linutronix.de> References: <20240603232453.33992-1-john.ogness@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" For nbcon consoles, normally the printing is handled by the dedicated console printing threads. However, on shutdown the printing threads may not get a chance to print the final messages. When shutting down or rebooting (system_state > SYSTEM_RUNNING), perform atomic printing from the printk() caller context. Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- kernel/printk/nbcon.c | 5 +++-- kernel/printk/printk.c | 7 ++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c index 89b340ca303c..19f0db6945e4 100644 --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c @@ -1297,7 +1297,8 @@ static void nbcon_atomic_flush_pending_con(struct con= sole *con, u64 stop_seq, * context must flush those remaining records if the printer thread * is not available do it. */ - if (!con->kthread && prb_read_valid(prb, nbcon_seq_read(con), NULL)) { + if ((!con->kthread || (system_state > SYSTEM_RUNNING)) && + prb_read_valid(prb, nbcon_seq_read(con), NULL)) { stop_seq =3D prb_next_reserve_seq(prb); goto again; } @@ -1639,7 +1640,7 @@ void nbcon_device_release(struct console *con) */ cookie =3D console_srcu_read_lock(); if (console_is_usable(con, console_srcu_read_flags(con)) && - !con->kthread && + (!con->kthread || (system_state > SYSTEM_RUNNING)) && prb_read_valid(prb, nbcon_seq_read(con), NULL)) { __nbcon_atomic_flush_pending_con(con, prb_next_reserve_seq(prb), false); } diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 137bd9a721c4..b58db15d2033 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -2389,12 +2389,17 @@ asmlinkage int vprintk_emit(int facility, int level, * * - When this CPU is in panic. * + * - During shutdown, since the printing threads may not get + * a chance to print the final messages. + * * Note that if boot consoles are registered, the console * lock/unlock dance must be relied upon instead because nbcon * consoles cannot print simultaneously with boot consoles. */ - if (is_panic_context) + if (is_panic_context || + (system_state > SYSTEM_RUNNING)) { nbcon_atomic_flush_pending(); + } } =20 if (do_trylock_unlock) { --=20 2.39.2 From nobody Fri Feb 13 01:43:51 2026 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 92A1A13D501 for ; Mon, 3 Jun 2024 23:24:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457101; cv=none; b=JJufhVEYEs3/nu8wO+EhDRmfHkVmM6ZdJat2+dCDCR4rtPHotb66zpuYHM27Pi3cxXXz8bIzlhOeJOtg5aqGpAJenKQvadII29Zgj9uEQScwWnvVsldHavPRqbVJrhhApGyVSnWX1Pw5QZf1Tn4c+lYw94GK5rdef6rzRJcGxz0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457101; c=relaxed/simple; bh=/DV2OcitrYBM0e5R61yRVkhYgmop2W7tbmLqenGV6WE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ZgrpQ1Yx7E+KG5F31lyEWcDp1NB0jL1oKbw3VGlDXXFACiW2hqWNnAK/6jrpLe/8uZhvdu1vb/e5aYziB5tBG2Fy1aGeg4eX62MmTD+DApsFBt4cQXGy2kpicLI/hXeNrSGr5jBEGWtntKW+9dpCaXAMcIXQQt9JVsWXD8P6ZKU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=WbDpZ1qA; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=r52PlJP0; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="WbDpZ1qA"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="r52PlJP0" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1717457096; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Zsvdhza0eQIM2Wg3mYfbF9S4P/mMid6egaOJ9nhJBnY=; b=WbDpZ1qArIfYi2docYTDqgesViQic8j5CxcXpac0H4zE86JmZpdGGdWUFtI1GjmHftOyVQ 5aTrtZiw0abPIeDEoNvSqRg21Xt+YP7M4jEduoBJgxpRwgy9rvMFJuwJTIFhXvBmad3CCA PPF30IDYXWI84u5DuLbj2Fi64MD/qnfv3nmRX6Vqh4Id3TsVWW40i+lBIQyPhGD9hc94LX RMEciHUj46XidYAi2FlCvELJu/YtxErqQ8TeU4JOx+dGHyHh6ZMYIHsC6Ql0okT3xQ+VOZ WzBqQMLdq7bGZKZB/+CkDc5DpesvyM6DO6al7lQd5LAHqp20imeEyzD7EGHNUA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1717457096; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Zsvdhza0eQIM2Wg3mYfbF9S4P/mMid6egaOJ9nhJBnY=; b=r52PlJP0sUKoBwwZZG0HKbQvFRtETwvyZ812y+kkrdVqZZBAST3YtRLiLvPJcaNv0kIVQW p9yJlxDsJ/DLpACA== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v2 06/18] printk: nbcon: Add context to console_is_usable() Date: Tue, 4 Jun 2024 01:30:41 +0206 Message-Id: <20240603232453.33992-7-john.ogness@linutronix.de> In-Reply-To: <20240603232453.33992-1-john.ogness@linutronix.de> References: <20240603232453.33992-1-john.ogness@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The nbcon consoles have two callbacks to be used for different contexts. In order to determine if an nbcon console is usable, console_is_usable() needs to know if it is a context that will use the write_atomic() callback or the write_thread() callback. Add an extra parameter @use_atomic to specify this. Signed-off-by: John Ogness --- kernel/printk/internal.h | 16 ++++++++++------ kernel/printk/nbcon.c | 8 ++++---- kernel/printk/printk.c | 6 ++++-- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h index 38680c6b2b39..243d3d3bc889 100644 --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h @@ -100,7 +100,7 @@ void nbcon_kthread_create(struct console *con); * which can also play a role in deciding if @con can be used to print * records. */ -static inline bool console_is_usable(struct console *con, short flags) +static inline bool console_is_usable(struct console *con, short flags, boo= l use_atomic) { if (!(flags & CON_ENABLED)) return false; @@ -109,10 +109,13 @@ static inline bool console_is_usable(struct console *= con, short flags) return false; =20 if (flags & CON_NBCON) { - if (!con->write_atomic) - return false; - if (!con->write_thread) - return false; + if (use_atomic) { + if (!con->write_atomic) + return false; + } else { + if (!con->write_thread) + return false; + } } else { if (!con->write) return false; @@ -177,7 +180,8 @@ static inline void nbcon_atomic_flush_pending(void) { } static inline bool nbcon_legacy_emit_next_record(struct console *con, bool= *handover, int cookie) { return false; } =20 -static inline bool console_is_usable(struct console *con, short flags) { r= eturn false; } +static inline bool console_is_usable(struct console *con, short flags, + bool use_atomic) { return false; } =20 #endif /* CONFIG_PRINTK */ =20 diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c index 19f0db6945e4..4200953d368e 100644 --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c @@ -967,7 +967,7 @@ static bool nbcon_kthread_should_wakeup(struct console = *con, struct nbcon_contex cookie =3D console_srcu_read_lock(); =20 flags =3D console_srcu_read_flags(con); - if (console_is_usable(con, flags)) { + if (console_is_usable(con, flags, false)) { /* Bring the sequence in @ctxt up to date */ ctxt->seq =3D nbcon_seq_read(con); =20 @@ -1026,7 +1026,7 @@ static int nbcon_kthread_func(void *__console) =20 con_flags =3D console_srcu_read_flags(con); =20 - if (console_is_usable(con, con_flags)) { + if (console_is_usable(con, con_flags, false)) { unsigned long lock_flags; =20 con->device_lock(con, &lock_flags); @@ -1322,7 +1322,7 @@ static void __nbcon_atomic_flush_pending(u64 stop_seq= , bool allow_unsafe_takeove if (!(flags & CON_NBCON)) continue; =20 - if (!console_is_usable(con, flags)) + if (!console_is_usable(con, flags, true)) continue; =20 if (nbcon_seq_read(con) >=3D stop_seq) @@ -1639,7 +1639,7 @@ void nbcon_device_release(struct console *con) * the console is usable throughout flushing. */ cookie =3D console_srcu_read_lock(); - if (console_is_usable(con, console_srcu_read_flags(con)) && + if (console_is_usable(con, console_srcu_read_flags(con), true) && (!con->kthread || (system_state > SYSTEM_RUNNING)) && prb_read_valid(prb, nbcon_seq_read(con), NULL)) { __nbcon_atomic_flush_pending_con(con, prb_next_reserve_seq(prb), false); diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index b58db15d2033..a2c4fe3d21cc 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -3043,7 +3043,7 @@ static bool console_flush_all(bool do_cond_resched, u= 64 *next_seq, bool *handove if ((flags & CON_NBCON) && con->kthread) continue; =20 - if (!console_is_usable(con, flags)) + if (!console_is_usable(con, flags, true)) continue; any_usable =3D true; =20 @@ -4018,8 +4018,10 @@ static bool __pr_flush(struct console *con, int time= out_ms, bool reset_on_progre * that they make forward progress, so only increment * @diff for usable consoles. */ - if (!console_is_usable(c, flags)) + if (!console_is_usable(c, flags, true) && + !console_is_usable(c, flags, false)) { continue; + } =20 if (flags & CON_NBCON) { printk_seq =3D nbcon_seq_read(c); --=20 2.39.2 From nobody Fri Feb 13 01:43:51 2026 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 910F313CF96 for ; Mon, 3 Jun 2024 23:24:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457101; cv=none; b=qD9UDgj3NOQDj2LDxixxdd4a8LvGr/mvYSHkVfWJD3Z8D3EemUShygd63IwT3Z/F+kVvmRmCX4RwcvJ7rvyJOaPOWgDpUTQfVZo7mTFBByGkRHaVmmDAXGniNSWHz9nV4kEQtcZiUPnJUuUrYsTpx2/R/7kCSJ8C2u+GT1FEt34= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457101; c=relaxed/simple; bh=h2xMza0pIQO539SBEF2bOG10SNxaO64Y36tbIZ1NJiw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=OTXbpkaTxNx4y548u+vHVp9nLgV0SQ9jeekcq3Z4xOCneG6sOALJ6bm1gg7z0jff0+qQz3amKW4A9v3VOrAustkZH91hR8kJ6HpCsP+4wfnFKv6cBw46u4UPK58ovLbqZTvfoKJT/c8B/nvoK8w8ZXM3TPhA7U7wxNwf5YZ6VL0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=y8Ji3U76; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=1jC6egg5; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="y8Ji3U76"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="1jC6egg5" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1717457097; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=pr40aimvVoxs/7225bC4/W64BDXKDTy5/ujSTndIDGE=; b=y8Ji3U76CjKRLf3D9VTzoCW2CEw+//r5l49+k97RHLBIIMjJamgP6u1SnM/tVxw66knEyQ m5Me5QlmXTbCT0JALBFys3p37g6oP/Z4wJ0V3fkJSPWCspKk9kv4+ef5dyP74r9AUFsWNK Z1V8c8f0iGTqoYP5KVYYPF/dQ6HXxyMgN0lIOplS3e64Y+d6NgXMes4sqS4HBRbmlDMy0Y gykfkQ0E9okxEzhxKeLV79MG2x0pU+fPXXmFptezobWhNKMSu+yFDyduAUrBzc1yL0yd4c CazzkcJyOH2g6sScPu7LUkKfkrJ2RB7vmbEgrVdjQOixVP1mVSc66lxixT8Kog== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1717457097; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=pr40aimvVoxs/7225bC4/W64BDXKDTy5/ujSTndIDGE=; b=1jC6egg58HtK5mqFOWq9YgaeY2QhFJsGl9NuJnAEnzv+AGEOGCzE/gpNhG4qWw8HMiU2jY 9gi2mfcZAs65aCBQ== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Greg Kroah-Hartman , "Paul E. McKenney" Subject: [PATCH printk v2 07/18] printk: nbcon: Add printer thread wakeups Date: Tue, 4 Jun 2024 01:30:42 +0206 Message-Id: <20240603232453.33992-8-john.ogness@linutronix.de> In-Reply-To: <20240603232453.33992-1-john.ogness@linutronix.de> References: <20240603232453.33992-1-john.ogness@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner Add a function to wakeup the printer threads. The printer threads are woken when: - a record is added to the printk ringbuffer - consoles are resumed - triggered via printk_trigger_flush() - consoles should be replayed via sysrq The actual waking is performed via irq_work so that the function can be called from any context. Co-developed-by: John Ogness Signed-off-by: John Ogness Signed-off-by: Thomas Gleixner (Intel) --- include/linux/console.h | 3 +++ kernel/printk/internal.h | 1 + kernel/printk/nbcon.c | 56 ++++++++++++++++++++++++++++++++++++++++ kernel/printk/printk.c | 8 ++++++ 4 files changed, 68 insertions(+) diff --git a/include/linux/console.h b/include/linux/console.h index 4de42ec1527c..adcc1a74aeee 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -16,6 +16,7 @@ =20 #include #include +#include #include #include #include @@ -327,6 +328,7 @@ struct nbcon_write_context { * @pbufs: Pointer to nbcon private buffer * @kthread: Printer kthread for this console * @rcuwait: RCU-safe wait object for @kthread waking + * @irq_work: Defer @kthread waking to IRQ work context */ struct console { char name[16]; @@ -446,6 +448,7 @@ struct console { struct printk_buffers *pbufs; struct task_struct *kthread; struct rcuwait rcuwait; + struct irq_work irq_work; }; =20 #ifdef CONFIG_LOCKDEP diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h index 243d3d3bc889..b2b5c10a4321 100644 --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h @@ -93,6 +93,7 @@ void nbcon_atomic_flush_pending(void); bool nbcon_legacy_emit_next_record(struct console *con, bool *handover, int cookie); void nbcon_kthread_create(struct console *con); +void nbcon_wake_threads(void); =20 /* * Check if the given console is currently capable and allowed to print diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c index 4200953d368e..4ab47cc014a3 100644 --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c @@ -1058,6 +1058,61 @@ static int nbcon_kthread_func(void *__console) goto wait_for_event; } =20 +/** + * nbcon_irq_work - irq work to wake printk thread + * @irq_work: The irq work to operate on + */ +static void nbcon_irq_work(struct irq_work *irq_work) +{ + struct console *con =3D container_of(irq_work, struct console, irq_work); + + nbcon_kthread_wake(con); +} + +static inline bool rcuwait_has_sleeper(struct rcuwait *w) +{ + bool has_sleeper; + + rcu_read_lock(); + /* + * Guarantee any new records can be seen by tasks preparing to wait + * before this context checks if the rcuwait is empty. + * + * This full memory barrier pairs with the full memory barrier within + * set_current_state() of ___rcuwait_wait_event(), which is called + * after prepare_to_rcuwait() adds the waiter but before it has + * checked the wait condition. + * + * This pairs with nbcon_kthread_func:A. + */ + smp_mb(); /* LMM(rcuwait_has_sleeper:A) */ + has_sleeper =3D !!rcu_dereference(w->task); + rcu_read_unlock(); + + return has_sleeper; +} + +/** + * nbcon_wake_threads - Wake up printing threads using irq_work + */ +void nbcon_wake_threads(void) +{ + struct console *con; + int cookie; + + cookie =3D console_srcu_read_lock(); + for_each_console_srcu(con) { + /* + * Only schedule irq_work if the printing thread is + * actively waiting. If not waiting, the thread will + * notice by itself that it has work to do. + */ + if (con->kthread && rcuwait_has_sleeper(&con->rcuwait)) + irq_work_queue(&con->irq_work); + } + console_srcu_read_unlock(cookie); +} + /* Track the nbcon emergency nesting per CPU. */ static DEFINE_PER_CPU(unsigned int, nbcon_pcpu_emergency_nesting); static unsigned int early_nbcon_pcpu_emergency_nesting __initdata; @@ -1558,6 +1613,7 @@ void nbcon_init(struct console *con, u64 init_seq) BUG_ON(!con->pbufs); =20 rcuwait_init(&con->rcuwait); + init_irq_work(&con->irq_work, nbcon_irq_work); nbcon_seq_force(con, init_seq); nbcon_state_set(con, &state); } diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index a2c4fe3d21cc..457c01311a95 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -2402,6 +2402,8 @@ asmlinkage int vprintk_emit(int facility, int level, } } =20 + nbcon_wake_threads(); + if (do_trylock_unlock) { /* * The caller may be holding system-critical or @@ -2708,6 +2710,10 @@ void resume_console(void) */ synchronize_srcu(&console_srcu); =20 + /* + * Since this runs in task context, wake the threaded printers + * directly rather than scheduling irq_work to do it. + */ cookie =3D console_srcu_read_lock(); for_each_console_srcu(con) { flags =3D console_srcu_read_flags(con); @@ -4178,6 +4184,7 @@ void defer_console_output(void) =20 void printk_trigger_flush(void) { + nbcon_wake_threads(); defer_console_output(); } =20 @@ -4513,6 +4520,7 @@ void console_try_replay_all(void) { if (console_trylock()) { __console_rewind_all(); + nbcon_wake_threads(); /* Consoles are flushed as part of console_unlock(). */ console_unlock(); } --=20 2.39.2 From nobody Fri Feb 13 01:43:51 2026 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 6029713D2B3 for ; Mon, 3 Jun 2024 23:24:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457100; cv=none; b=Q3AW6nT94bsnMAHwZSLvcWor+Y9B2QYuyU9Nij+s3xA0cAlP8u698UkL57a9wCiMUexd8ivRuH9mVDt+nEpuRT5YEKtmq3eDH5W2Mesz+XmDsixRCl3BCjq1SAnm9CXB9lvxZWS1eilvNjdfj4JkShz2uop1/Q4B/NAEW6k/6kk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457100; c=relaxed/simple; bh=1GPxJsazjgFSmtvziKA2daYP2cJk4PeD/79aElPpmV8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ZL2POwXgCnrKRTOpMOCa6wqt1u35Nqb2QCe2ghp8BoI3I0WSbHM9A8G0Y/gAuffnxL4H86iVjOIFk7SWLgSr1RH8RVX/sYMmIhxp9QFtKJSonlNM8TWbkvo0Tgjk7aSoWpZExo9+h86WevrzQrG3+uZ0IvvNBtQZq6FmWZEO4So= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=Ugy8mT27; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=EoHxWt/n; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="Ugy8mT27"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="EoHxWt/n" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1717457097; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=J3r539HPiGZ1ucztmTvwYfwwdyMDVQwx7ANJGpwQWgU=; b=Ugy8mT27KdRZEzx99VjJZzeebPpUyaWC554x2HvHaMK4xKaZlrkbdIG9Wu+Dy2RX6Iz9yv s2+BZXyqq6sENqhYcb/RJWKGbowNN9x3mY/UtKgP6Rs/mt3FGsizQsS85ePBz7tHJtkFxC LWl+rJPaNYFv1QRjKqMmKSaIxhP8NfWPCCAG/Zfj0Z+yB4eqm29PhYqs0Worv2Eif0q/tM zVVWNzDo/183+vRmg+t1PyDpSXfNHpQ7bUkxJs8WRJLV/DObJS8epL3+ayvhBbsEA0Vndn ro72ykqUn7MT2Hle36AmdHKC4vTH4AxWsYQU/agXxugV0wBoBbklm3qKf+TPXQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1717457097; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=J3r539HPiGZ1ucztmTvwYfwwdyMDVQwx7ANJGpwQWgU=; b=EoHxWt/nLPkRcB9vqfRfKnHhGNiNmYiGJ/6KIay44Uw62QdQGjp8cqwYhJAlcfxXNWi6sb RSJc4NUoFRAcAqBg== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v2 08/18] printk: nbcon: Stop threads on shutdown/reboot Date: Tue, 4 Jun 2024 01:30:43 +0206 Message-Id: <20240603232453.33992-9-john.ogness@linutronix.de> In-Reply-To: <20240603232453.33992-1-john.ogness@linutronix.de> References: <20240603232453.33992-1-john.ogness@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Register a syscore_ops shutdown function to stop all threaded printers on shutdown/reboot. This allows printk to cleanly transition back to atomic printing in order to provide a robust mechanism for outputting the final messages. Signed-off-by: John Ogness --- kernel/printk/nbcon.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c index 4ab47cc014a3..f60d47b5db8a 100644 --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "internal.h" #include "printk_ringbuffer.h" @@ -1703,3 +1704,33 @@ void nbcon_device_release(struct console *con) console_srcu_read_unlock(cookie); } EXPORT_SYMBOL_GPL(nbcon_device_release); + +/** + * printk_kthread_shutdown - shutdown all threaded printers + * + * On system shutdown all threaded printers are stopped. This allows printk + * to transition back to atomic printing, thus providing a robust mechanism + * for the final shutdown/reboot messages to be output. + */ +static void printk_kthread_shutdown(void) +{ + struct console *con; + + console_list_lock(); + for_each_console(con) { + if (con->flags & CON_NBCON) + nbcon_kthread_stop(con); + } + console_list_unlock(); +} + +static struct syscore_ops printk_syscore_ops =3D { + .shutdown =3D printk_kthread_shutdown, +}; + +static int __init printk_init_ops(void) +{ + register_syscore_ops(&printk_syscore_ops); + return 0; +} +device_initcall(printk_init_ops); --=20 2.39.2 From nobody Fri Feb 13 01:43:51 2026 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 E7D7713D514 for ; Mon, 3 Jun 2024 23:24:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457101; cv=none; b=s3o6helxLTpnovVu2k17iEX2dq97N/gqpfkB198N9ZBlFSb6TiGfRFYDlaDGfdFNbtusbnHQFnoUGxx67rzHXMqKyN3JxcmJkf9aCg7AwNvVV0zbQr00il+bQi1ABMjZNRvzJ48eexe5hUqI8FNBdLOxSUiMuZOhGArkUAqYXcg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457101; c=relaxed/simple; bh=0C4dgeMH1ETa6qI9bAimpP79piYd69dT3io4/eKnesI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=oCKvKPWKZev2PFePevg7chkmx1fTHsSjbHyQc/DhJAlptifjlhzmC4r2gzelLweM37b3D5CpXsZb3tPUqWwYO2E7OfCuKAyR4SM792983wnbuogJzTI/EFNLIp/QLpKrIbTFbjk67qjs/HU6R6c4lJVLijsC1AzNYSuUlKAqZP4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=Cf/WNiPf; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=aRZRf3JJ; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="Cf/WNiPf"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="aRZRf3JJ" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1717457098; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Ji2vckRR4GEO79DzWO5vikRvAUqQwqYX0LChtt8+KCk=; b=Cf/WNiPfWk/c2NUVJioPZfMvn734wrwsRmyytNh284GH/uMvneFJoeLKu0CPIkNO962IpN GqiskNPnw6NpIj2LlBSJY3uCTTNxjL56me7to9K05+V7FWAwVL8kdGpjAmMRNzCnXzg9aE KCGRs/KNEIin0B8USkbG59aA1pM3ggt6vjwNDIdGgcS6wUKseA0xa1tIOcIPnq0K3TC5T4 dwtSVdZzYiqqY5pBeSvBsHrps4Qitw+DCr7LtT3plNLmGecRRz2KtODr946ULNoXey08L3 lq78UeuTs4tFOVvqib8vOAKBwDEdG2f6bqH7DPv5SbN5C49xexbZejL8pP/HQA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1717457098; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Ji2vckRR4GEO79DzWO5vikRvAUqQwqYX0LChtt8+KCk=; b=aRZRf3JJDumguiJ5WAHM/E8orw//pK6WDfVRhubwshWKW5ZJtcOL9qdSHgeFrUb/XFIsS6 OhzmNEXN0tZnGDCw== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v2 09/18] printk: nbcon: Start printing threads Date: Tue, 4 Jun 2024 01:30:44 +0206 Message-Id: <20240603232453.33992-10-john.ogness@linutronix.de> In-Reply-To: <20240603232453.33992-1-john.ogness@linutronix.de> References: <20240603232453.33992-1-john.ogness@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" If there are no boot consoles, the printing threads are started in early_initcall. If there are boot consoles, the printing threads are started after the last boot console has unregistered. The printing threads do not need to be concerned about boot consoles because boot consoles cannot register once a non-boot console has registered. Until a printing thread of a console has started, that console will print using atomic_write() in the printk() caller context. Signed-off-by: John Ogness --- kernel/printk/internal.h | 2 ++ kernel/printk/nbcon.c | 18 +++++++++++++++++- kernel/printk/printk.c | 14 ++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h index b2b5c10a4321..5d4722310850 100644 --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h @@ -48,6 +48,7 @@ struct printk_ringbuffer; struct dev_printk_info; =20 extern struct printk_ringbuffer *prb; +extern bool printk_threads_enabled; =20 __printf(4, 0) int vprintk_store(int facility, int level, @@ -161,6 +162,7 @@ static inline void nbcon_kthread_wake(struct console *c= on) =20 static inline void nbcon_kthread_wake(struct console *con) { } static inline void nbcon_kthread_create(struct console *con) { } +#define printk_threads_enabled (false) =20 /* * In !PRINTK builds we still export console_sem diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c index f60d47b5db8a..480a0ced2708 100644 --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c @@ -213,6 +213,8 @@ static void nbcon_seq_try_update(struct nbcon_context *= ctxt, u64 new_seq) } } =20 +bool printk_threads_enabled __ro_after_init; + /** * nbcon_context_try_acquire_direct - Try to acquire directly * @ctxt: The context of the caller @@ -1542,7 +1544,7 @@ void nbcon_kthread_create(struct console *con) if (!(con->flags & CON_NBCON) || !con->write_thread) return; =20 - if (con->kthread) + if (!printk_threads_enabled || con->kthread) return; =20 /* @@ -1568,6 +1570,19 @@ void nbcon_kthread_create(struct console *con) sched_set_normal(con->kthread, -20); } =20 +static int __init printk_setup_threads(void) +{ + struct console *con; + + console_list_lock(); + printk_threads_enabled =3D true; + for_each_console(con) + nbcon_kthread_create(con); + console_list_unlock(); + return 0; +} +early_initcall(printk_setup_threads); + /** * nbcon_alloc - Allocate buffers needed by the nbcon console * @con: Console to allocate buffers for @@ -1617,6 +1632,7 @@ void nbcon_init(struct console *con, u64 init_seq) init_irq_work(&con->irq_work, nbcon_irq_work); nbcon_seq_force(con, init_seq); nbcon_state_set(con, &state); + nbcon_kthread_create(con); } =20 /** diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 457c01311a95..4613f9145a8e 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -2389,6 +2389,9 @@ asmlinkage int vprintk_emit(int facility, int level, * * - When this CPU is in panic. * + * - When booting, before the printing threads have been + * started. + * * - During shutdown, since the printing threads may not get * a chance to print the final messages. * @@ -2397,6 +2400,7 @@ asmlinkage int vprintk_emit(int facility, int level, * consoles cannot print simultaneously with boot consoles. */ if (is_panic_context || + !printk_threads_enabled || (system_state > SYSTEM_RUNNING)) { nbcon_atomic_flush_pending(); } @@ -3742,6 +3746,7 @@ EXPORT_SYMBOL(register_console); static int unregister_console_locked(struct console *console) { bool use_device_lock =3D (console->flags & CON_NBCON) && console->write_a= tomic; + bool is_boot_con =3D (console->flags & CON_BOOT); bool found_legacy_con =3D false; bool found_nbcon_con =3D false; bool found_boot_con =3D false; @@ -3824,6 +3829,15 @@ static int unregister_console_locked(struct console = *console) if (!found_nbcon_con) have_nbcon_console =3D found_nbcon_con; =20 + /* + * When the last boot console unregisters, start up the + * printing threads. + */ + if (is_boot_con && !have_boot_console) { + for_each_console(c) + nbcon_kthread_create(c); + } + return res; } =20 --=20 2.39.2 From nobody Fri Feb 13 01:43:51 2026 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 4F56C13D527 for ; Mon, 3 Jun 2024 23:25:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457102; cv=none; b=j0PJrm38rBJcQp894xV2wXuzT9UbeomW9oQ344JgdHpTX+Uw3yumQR+Q8QH+TnN/64gxEdjXEWNKsZZxE0FOhikyUsCh8l8DJYeR9TbQLm5hifFpLKg/N/LsmrZtJ57CqlMcv06qOVcT1A+1z15Phdhiavd7fMg1JzgTJSoJhC8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457102; c=relaxed/simple; bh=WzH60LE1JHbgrXr8Xp82kiXt9WKVqavSDQunTGSY/BU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=dJ9WlNnDhMU3IbJAclWD1qBUU3IEqzsx3TtTCElk8s2F4I5AEyUj5F5qKNdjibk9pXpHBk4dYLfzzHmcv1ONncdUe9rBzQnrPO6oAb0wEt3qs7Fh+tn1cAxCwcEAnei3yxOjLgRT06VHHkol8NzTzu96Bf0Zc2loProPC9aiHWM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=x4a20jNB; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=1NBbkf+i; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="x4a20jNB"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="1NBbkf+i" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1717457098; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=4oYaY6vh/25J7oqncloRHx8iudin+UX3Lw2NmnwW3ms=; b=x4a20jNBcfTKskpVL5KHWROuttjcpcX9tuRFrAxhpqJvysj3BpITSI3LI5MksQG8UC/ZVE hmt/ArLodPuOT19k+28sEMGnIHip8R3+WT2VASeDwvPDC8WK71e6hsWi0Yg7s5Q+j/Jpmk k87wrYYYXwmhwEYc/VvAz/6esle6+SWdyDY5R+pdxV6GWC8N6GEVvTbhqTSEm7PCCZ+DRM Omj50ebW4B1vY2HnwMmpb8P8YB37y4J0H7aTbjeRftEMr2zD8VwE+SwgLIJ2ivtzxTjRHR cFvp9EE6C+mVEStIeGKBzF3pY180Pm3LAe0N8T05FXw5K7KiygnjQaTKFkbEsg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1717457098; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=4oYaY6vh/25J7oqncloRHx8iudin+UX3Lw2NmnwW3ms=; b=1NBbkf+i0YZ7KR/qAerh2MAF+2aJNWczX8I9aHGeefDlnwTeWaxLrslvmjJF2/eDBxeT3H vuAejtit7IH6uPBg== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v2 10/18] printk: Provide helper for message prepending Date: Tue, 4 Jun 2024 01:30:45 +0206 Message-Id: <20240603232453.33992-11-john.ogness@linutronix.de> In-Reply-To: <20240603232453.33992-1-john.ogness@linutronix.de> References: <20240603232453.33992-1-john.ogness@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In order to support prepending different texts to printk messages, split out the prepending code into a helper function. Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- kernel/printk/printk.c | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 4613f9145a8e..fcbf794a0aaf 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -2806,30 +2806,25 @@ static void __console_unlock(void) #ifdef CONFIG_PRINTK =20 /* - * Prepend the message in @pmsg->pbufs->outbuf with a "dropped message". T= his - * is achieved by shifting the existing message over and inserting the dro= pped - * message. + * Prepend the message in @pmsg->pbufs->outbuf with the message in + * @pmsg->pbufs->scratchbuf. This is achieved by shifting the existing mes= sage + * over and inserting the scratchbuf message. * * @pmsg is the printk message to prepend. * - * @dropped is the dropped count to report in the dropped message. + * @len is the length of the message in @pmsg->pbufs->scratchbuf. * * If the message text in @pmsg->pbufs->outbuf does not have enough space = for - * the dropped message, the message text will be sufficiently truncated. + * the scratchbuf message, the message text will be sufficiently truncated. * * If @pmsg->pbufs->outbuf is modified, @pmsg->outbuf_len is updated. */ -void console_prepend_dropped(struct printk_message *pmsg, unsigned long dr= opped) +static void __console_prepend_scratch(struct printk_message *pmsg, size_t = len) { struct printk_buffers *pbufs =3D pmsg->pbufs; - const size_t scratchbuf_sz =3D sizeof(pbufs->scratchbuf); const size_t outbuf_sz =3D sizeof(pbufs->outbuf); char *scratchbuf =3D &pbufs->scratchbuf[0]; char *outbuf =3D &pbufs->outbuf[0]; - size_t len; - - len =3D scnprintf(scratchbuf, scratchbuf_sz, - "** %lu printk messages dropped **\n", dropped); =20 /* * Make sure outbuf is sufficiently large before prepending. @@ -2851,6 +2846,27 @@ void console_prepend_dropped(struct printk_message *= pmsg, unsigned long dropped) pmsg->outbuf_len +=3D len; } =20 +/* + * Prepend the message in @pmsg->pbufs->outbuf with a "dropped message". + * @pmsg->outbuf_len is updated appropriately. + * + * @pmsg is the printk message to prepend. + * + * @dropped is the dropped count to report in the dropped message. + */ +void console_prepend_dropped(struct printk_message *pmsg, unsigned long dr= opped) +{ + struct printk_buffers *pbufs =3D pmsg->pbufs; + const size_t scratchbuf_sz =3D sizeof(pbufs->scratchbuf); + char *scratchbuf =3D &pbufs->scratchbuf[0]; + size_t len; + + len =3D scnprintf(scratchbuf, scratchbuf_sz, + "** %lu printk messages dropped **\n", dropped); + + __console_prepend_scratch(pmsg, len); +} + /* * Read and format the specified record (or a later record if the specified * record is not available). --=20 2.39.2 From nobody Fri Feb 13 01:43:51 2026 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 B7BF913D606 for ; Mon, 3 Jun 2024 23:25:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457102; cv=none; b=sf7j+WkxXUX/c6I+PhNelzMV5V+BtFPkNl3Do3htRYapE3lghbyDYO46YzJFZI2zZmndRKpgsTdb0dZ+1KoL622PE51BkxQcbY/Ck97X4C+SxpQGrx5pcfz11C89XJZV8YqBkrEftCPIvfdstcudyPHDoKw4ndB3VEJ5kIcObWw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457102; c=relaxed/simple; bh=zCdEe8+RH4XlG7eBx9a3rSWZHIqYz7vbbkZgHROBGK8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=cJv0baMvbPGlg7QNeWp1aIs+pambcAjZXS6UZSi8jTo9Ri2x3RHCC/bs3HTv0gUrwMf3KBIq0n+Q0ii/19k2dv5rTA+cXhR+H7F6bWwb/beJI9101Bo8kOlrboo6WeiQFEb8cpygWNN2dnS271N7u89xdV5ont9yTwY2d/tqv5s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=DHV8Zwi6; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=unMpXQQf; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="DHV8Zwi6"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="unMpXQQf" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1717457099; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=HSPbGXrcPCHiCR0e1KtRGjSW0V56pt20H3Bnio+pcfI=; b=DHV8Zwi6y4rTdb9NOOkhROyJ4R4g2iCWZHE83mUWDGdEAN87ebE3cnzLGhO8hHWJGrzl6K 7mvj17Gu10Thx+hvdO4vkkam24FDvzYgnQm47mO+xKKzTQwf+/to7uYDTlHAFiSK8EqeLp 8yWsPk4lCq/7nLlkHRoATl5G9mIyRyQRySKwngeYSqay+nF1YjNyWBm2FRV7KH/vwlstnc S3o3sIotQk+NhUZsZPKteTPlxX98GtTjxjOLLDMNaHTRbpo2eeJHwRQCu1bILU5W0nfWGb AeeWbSMxQTCpPco2KLF7OfRCIwM9Juqr9Eee7nq4HIAB0tPrJDTpXFWF0Z/8rQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1717457099; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=HSPbGXrcPCHiCR0e1KtRGjSW0V56pt20H3Bnio+pcfI=; b=unMpXQQf6Rr8AddTHoAqNxnxTkclhT2pnume2VqwfVqUZTbKWj/ltvZQFRQek6vYXqTH7M TReXtirtTJ5bBRDw== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Greg Kroah-Hartman Subject: [PATCH printk v2 11/18] printk: nbcon: Show replay message on takeover Date: Tue, 4 Jun 2024 01:30:46 +0206 Message-Id: <20240603232453.33992-12-john.ogness@linutronix.de> In-Reply-To: <20240603232453.33992-1-john.ogness@linutronix.de> References: <20240603232453.33992-1-john.ogness@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" An emergency or panic context can takeover console ownership while the current owner was printing a printk message. The atomic printer will re-print the message that the previous owner was printing. However, this can look confusing to the user and may even seem as though a message was lost. [3430014.1 [3430014.181123] usb 1-2: Product: USB Audio Add a new field @nbcon_prev_seq to struct console to track the sequence number to print that was assigned to the previous console owner. If this matches the sequence number to print that the current owner is assigned, then a takeover must have occurred. In this case, print an additional message to inform the user that the previous message is being printed again. [3430014.1 ** replaying previous printk message ** [3430014.181123] usb 1-2: Product: USB Audio Signed-off-by: John Ogness --- include/linux/console.h | 3 +++ kernel/printk/internal.h | 1 + kernel/printk/nbcon.c | 24 ++++++++++++++++++++++++ kernel/printk/printk.c | 19 +++++++++++++++++++ 4 files changed, 47 insertions(+) diff --git a/include/linux/console.h b/include/linux/console.h index adcc1a74aeee..9927f08ac054 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -325,6 +325,7 @@ struct nbcon_write_context { * @nbcon_state: State for nbcon consoles * @nbcon_seq: Sequence number of the next record for nbcon to print * @nbcon_device_ctxt: Context available for non-printing operations + * @nbcon_prev_seq: Seq num the previous nbcon owner was assigned to print * @pbufs: Pointer to nbcon private buffer * @kthread: Printer kthread for this console * @rcuwait: RCU-safe wait object for @kthread waking @@ -445,6 +446,8 @@ struct console { atomic_t __private nbcon_state; atomic_long_t __private nbcon_seq; struct nbcon_context __private nbcon_device_ctxt; + atomic_long_t __private nbcon_prev_seq; + struct printk_buffers *pbufs; struct task_struct *kthread; struct rcuwait rcuwait; diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h index 5d4722310850..9e027e08918d 100644 --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h @@ -233,4 +233,5 @@ bool printk_get_next_message(struct printk_message *pms= g, u64 seq, =20 #ifdef CONFIG_PRINTK void console_prepend_dropped(struct printk_message *pmsg, unsigned long dr= opped); +void console_prepend_replay(struct printk_message *pmsg); #endif diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c index 480a0ced2708..8c92b076c745 100644 --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c @@ -866,6 +866,7 @@ static bool nbcon_emit_next_record(struct nbcon_write_c= ontext *wctxt, bool use_a unsigned long con_dropped; struct nbcon_state cur; unsigned long dropped; + unsigned long ulseq; =20 /* * The printk buffers are filled within an unsafe section. This @@ -891,6 +892,28 @@ static bool nbcon_emit_next_record(struct nbcon_write_= context *wctxt, bool use_a if (dropped && !is_extended) console_prepend_dropped(&pmsg, dropped); =20 + /* + * If the previous owner was assigned the same record, this context + * has taken over ownership and is replaying the record. Prepend a + * message to let the user know the record is replayed. + */ + ulseq =3D atomic_long_read(&ACCESS_PRIVATE(con, nbcon_prev_seq)); + if (__ulseq_to_u64seq(prb, ulseq) =3D=3D pmsg.seq) { + console_prepend_replay(&pmsg); + } else { + /* + * Ensure this context is still the owner before trying to + * update @nbcon_prev_seq. Otherwise the value in @ulseq may + * not be from the previous owner. + */ + nbcon_state_read(con, &cur); + if (!nbcon_context_can_proceed(ctxt, &cur)) + return false; + + atomic_long_try_cmpxchg(&ACCESS_PRIVATE(con, nbcon_prev_seq), &ulseq, + __u64seq_to_ulseq(pmsg.seq)); + } + if (!nbcon_context_exit_unsafe(ctxt)) return false; =20 @@ -1631,6 +1654,7 @@ void nbcon_init(struct console *con, u64 init_seq) rcuwait_init(&con->rcuwait); init_irq_work(&con->irq_work, nbcon_irq_work); nbcon_seq_force(con, init_seq); + atomic_long_set(&ACCESS_PRIVATE(con, nbcon_prev_seq), -1UL); nbcon_state_set(con, &state); nbcon_kthread_create(con); } diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index fcbf794a0aaf..cf0d612329bf 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -2867,6 +2867,25 @@ void console_prepend_dropped(struct printk_message *= pmsg, unsigned long dropped) __console_prepend_scratch(pmsg, len); } =20 +/* + * Prepend the message in @pmsg->pbufs->outbuf with a "replay message". + * @pmsg->outbuf_len is updated appropriately. + * + * @pmsg is the printk message to prepend. + */ +void console_prepend_replay(struct printk_message *pmsg) +{ + struct printk_buffers *pbufs =3D pmsg->pbufs; + const size_t scratchbuf_sz =3D sizeof(pbufs->scratchbuf); + char *scratchbuf =3D &pbufs->scratchbuf[0]; + size_t len; + + len =3D scnprintf(scratchbuf, scratchbuf_sz, + "** replaying previous printk message **\n"); + + __console_prepend_scratch(pmsg, len); +} + /* * Read and format the specified record (or a later record if the specified * record is not available). --=20 2.39.2 From nobody Fri Feb 13 01:43:51 2026 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 94E3713D53F for ; Mon, 3 Jun 2024 23:25:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457104; cv=none; b=WOFBovltMwNk5izCsItcC707pw87IJ7S+G5OtGoNpSr/EwGCiYVDzWKqJBsbXQaWgZkPZFIs2D023JWWThLD6BtWQwKQJ618R/psZ2ohjuTqjG64b6wBaU+myITWEChpcvv5wv4T22dsEPE9n5aoifzCV+4U8pS0R5I4AZhCEZI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457104; c=relaxed/simple; bh=Qpbh6S0vMr3xMV0dEW6ODYGTREpji1A/L+daDlqLjks=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=jFAoG5vPPjCTUW9qqWabcltC9Gb+3WJU5F63xXMQY3UGP868+Rm2ixWxsdrM43y0wHiv34qh4xM1bLrO+sPmqnsh66hw8aQTGYWUyyDiNfeoPflP5/ohJa6/zxrq1REs2oJS5rJqu/MP0K0s9lt/W7ID3gHuIzqC9+GATOOoy7Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=wMptiP0I; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=S7aGHJud; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="wMptiP0I"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="S7aGHJud" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1717457099; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=giQlWc+fvOZG97Qbc4QRaL+AklRGm8hofCFroqwrQhs=; b=wMptiP0I4vVkSs2kjbBPx/jx+CKtmi4xdAUyDN3wWfvYmRiZWcCte2EDyJFl1vRvocNYyZ kDl4EI0JKrPcC6TfkIFzl4rJIvQF7FNq3yspjqnQcaeTSq7jOvui+KJqqptRFuYARKMN40 H6yifKa1mKLFpOLpyLHNhiNZcrFWEif59Yj2zlAHKc/HZl2xl4mMW79xg5Z1hldV1rY38/ lUrEy6DsZ6pDijX2bI4dDI0Yy7DJRTOTCBd/R8MCk42RP+CERbUAIfmlK/6dxAXxzyUXek VgWy4ZOsVITVX/J3HhcJ4dA8WSIkqTt+HjuXi3qN1Ywm0eXYxzYz3RBTbcTxaw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1717457099; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=giQlWc+fvOZG97Qbc4QRaL+AklRGm8hofCFroqwrQhs=; b=S7aGHJudUHy1vurzJF8GQ7ZoIvLroPtVd0XAZGwf4LHxA1Y5fu59GTIqVb3DdvIe11zsuh hz/BzisigfsaYlBA== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v2 12/18] printk: Add kthread for all legacy consoles Date: Tue, 4 Jun 2024 01:30:47 +0206 Message-Id: <20240603232453.33992-13-john.ogness@linutronix.de> In-Reply-To: <20240603232453.33992-1-john.ogness@linutronix.de> References: <20240603232453.33992-1-john.ogness@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The write callback of legacy consoles makes use of spinlocks. This is not permitted with PREEMPT_RT in atomic contexts. For PREEMPT_RT, create a new kthread to handle printing of all the legacy consoles (and nbcon consoles if boot consoles are registered). Since, if running from the kthread, the consoles are printing in a task context, the legacy nbcon printing can use the device_lock(), write_thread(), device_unlock() callbacks for printing. Introduce the macro force_printkthreads() to query if the forced threading of legacy consoles is in effect. These changes only affect CONFIG_PREEMPT_RT. Signed-off-by: John Ogness --- kernel/printk/internal.h | 11 +- kernel/printk/nbcon.c | 54 ++++++--- kernel/printk/printk.c | 241 ++++++++++++++++++++++++++++++++------- 3 files changed, 246 insertions(+), 60 deletions(-) diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h index 9e027e08918d..b66dfa865591 100644 --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h @@ -21,6 +21,12 @@ int devkmsg_sysctl_set_loglvl(struct ctl_table *table, i= nt write, (con->flags & CON_BOOT) ? "boot" : "", \ con->name, con->index, ##__VA_ARGS__) =20 +#ifdef CONFIG_PREEMPT_RT +# define force_printkthreads() (true) +#else +# define force_printkthreads() (false) +#endif + #ifdef CONFIG_PRINTK =20 #ifdef CONFIG_PRINTK_CALLER @@ -92,9 +98,10 @@ void nbcon_free(struct console *con); enum nbcon_prio nbcon_get_default_prio(void); void nbcon_atomic_flush_pending(void); bool nbcon_legacy_emit_next_record(struct console *con, bool *handover, - int cookie); + int cookie, bool use_atomic); void nbcon_kthread_create(struct console *con); void nbcon_wake_threads(void); +void nbcon_legacy_kthread_create(void); =20 /* * Check if the given console is currently capable and allowed to print @@ -181,7 +188,7 @@ static inline void nbcon_free(struct console *con) { } static inline enum nbcon_prio nbcon_get_default_prio(void) { return NBCON_= PRIO_NONE; } static inline void nbcon_atomic_flush_pending(void) { } static inline bool nbcon_legacy_emit_next_record(struct console *con, bool= *handover, - int cookie) { return false; } + int cookie, bool use_atomic) { return false; } =20 static inline bool console_is_usable(struct console *con, short flags, bool use_atomic) { return false; } diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c index 8c92b076c745..e8060b5abdf8 100644 --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c @@ -1185,9 +1185,10 @@ enum nbcon_prio nbcon_get_default_prio(void) } =20 /* - * nbcon_atomic_emit_one - Print one record for an nbcon console using the - * write_atomic() callback + * nbcon_emit_one - Print one record for an nbcon console using the + * specified callback * @wctxt: An initialized write context struct to use for this context + * @use_atomic: True if the write_atomic() callback is to be used * * Return: True, when a record has been printed and there are still * pending records. The caller might want to continue flushing. @@ -1200,7 +1201,7 @@ enum nbcon_prio nbcon_get_default_prio(void) * This is an internal helper to handle the locking of the console before * calling nbcon_emit_next_record(). */ -static bool nbcon_atomic_emit_one(struct nbcon_write_context *wctxt) +static bool nbcon_emit_one(struct nbcon_write_context *wctxt, bool use_ato= mic) { struct nbcon_context *ctxt =3D &ACCESS_PRIVATE(wctxt, ctxt); =20 @@ -1215,7 +1216,7 @@ static bool nbcon_atomic_emit_one(struct nbcon_write_= context *wctxt) * The higher priority printing context takes over responsibility * to print the pending records. */ - if (!nbcon_emit_next_record(wctxt, true)) + if (!nbcon_emit_next_record(wctxt, use_atomic)) return false; =20 nbcon_context_release(ctxt); @@ -1232,6 +1233,7 @@ static bool nbcon_atomic_emit_one(struct nbcon_write_= context *wctxt) * both the console_lock and the SRCU read lock. Otherwise it * is set to false. * @cookie: The cookie from the SRCU read lock. + * @use_atomic: True if the write_atomic() callback is to be used * * Context: Any context except NMI. * Return: True, when a record has been printed and there are still @@ -1247,26 +1249,38 @@ static bool nbcon_atomic_emit_one(struct nbcon_writ= e_context *wctxt) * Essentially it is the nbcon version of console_emit_next_record(). */ bool nbcon_legacy_emit_next_record(struct console *con, bool *handover, - int cookie) + int cookie, bool use_atomic) { struct nbcon_write_context wctxt =3D { }; struct nbcon_context *ctxt =3D &ACCESS_PRIVATE(&wctxt, ctxt); unsigned long flags; bool progress; =20 - /* Use the same procedure as console_emit_next_record(). */ - printk_safe_enter_irqsave(flags); - console_lock_spinning_enable(); - stop_critical_timings(); + ctxt->console =3D con; =20 - ctxt->console =3D con; - ctxt->prio =3D nbcon_get_default_prio(); + if (use_atomic) { + /* Use the same procedure as console_emit_next_record(). */ + printk_safe_enter_irqsave(flags); + console_lock_spinning_enable(); + stop_critical_timings(); =20 - progress =3D nbcon_atomic_emit_one(&wctxt); + ctxt->prio =3D nbcon_get_default_prio(); + progress =3D nbcon_emit_one(&wctxt, use_atomic); =20 - start_critical_timings(); - *handover =3D console_lock_spinning_disable_and_check(cookie); - printk_safe_exit_irqrestore(flags); + start_critical_timings(); + *handover =3D console_lock_spinning_disable_and_check(cookie); + printk_safe_exit_irqrestore(flags); + } else { + *handover =3D false; + + con->device_lock(con, &flags); + cant_migrate(); + + ctxt->prio =3D nbcon_get_default_prio(); + progress =3D nbcon_emit_one(&wctxt, use_atomic); + + con->device_unlock(con, flags); + } =20 return progress; } @@ -1494,7 +1508,9 @@ void nbcon_cpu_emergency_exit(void) * to handle it. */ do_trigger_flush =3D true; - if (printing_via_unlock && !is_printk_deferred()) { + if (!force_printkthreads() && + printing_via_unlock && + !is_printk_deferred()) { if (console_trylock()) { do_trigger_flush =3D false; console_unlock(); @@ -1530,7 +1546,9 @@ void nbcon_cpu_emergency_flush(void) =20 nbcon_atomic_flush_pending(); =20 - if (printing_via_unlock && !is_printk_deferred()) { + if (!force_printkthreads() && + printing_via_unlock && + !is_printk_deferred()) { if (console_trylock()) console_unlock(); } @@ -1601,6 +1619,8 @@ static int __init printk_setup_threads(void) printk_threads_enabled =3D true; for_each_console(con) nbcon_kthread_create(con); + if (force_printkthreads() && printing_via_unlock) + nbcon_legacy_kthread_create(); console_list_unlock(); return 0; } diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index cf0d612329bf..1c63fd0c1166 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -487,6 +487,9 @@ bool have_boot_console; =20 #ifdef CONFIG_PRINTK DECLARE_WAIT_QUEUE_HEAD(log_wait); + +static DECLARE_WAIT_QUEUE_HEAD(legacy_wait); + /* All 3 protected by @syslog_lock. */ /* the next printk record to read by syslog(READ) or /proc/kmsg */ static u64 syslog_seq; @@ -2345,7 +2348,8 @@ asmlinkage int vprintk_emit(int facility, int level, const struct dev_printk_info *dev_info, const char *fmt, va_list args) { - bool do_trylock_unlock =3D printing_via_unlock; + bool do_trylock_unlock =3D !force_printkthreads() && + printing_via_unlock; int printed_len; =20 /* Suppress unimportant messages after panic happens */ @@ -2468,6 +2472,14 @@ EXPORT_SYMBOL(_printk); static bool pr_flush(int timeout_ms, bool reset_on_progress); static bool __pr_flush(struct console *con, int timeout_ms, bool reset_on_= progress); =20 +static struct task_struct *nbcon_legacy_kthread; + +static inline void wake_up_legacy_kthread(void) +{ + if (nbcon_legacy_kthread) + wake_up_interruptible(&legacy_wait); +} + #else /* CONFIG_PRINTK */ =20 #define printk_time false @@ -2481,6 +2493,8 @@ static u64 syslog_seq; static bool pr_flush(int timeout_ms, bool reset_on_progress) { return true= ; } static bool __pr_flush(struct console *con, int timeout_ms, bool reset_on_= progress) { return true; } =20 +static inline void nbcon_legacy_kthread_create(void) { } +static inline void wake_up_legacy_kthread(void) { } #endif /* CONFIG_PRINTK */ =20 #ifdef CONFIG_EARLY_PRINTK @@ -2726,6 +2740,8 @@ void resume_console(void) } console_srcu_read_unlock(cookie); =20 + wake_up_legacy_kthread(); + pr_flush(1000, true); } =20 @@ -2740,7 +2756,9 @@ void resume_console(void) */ static int console_cpu_notify(unsigned int cpu) { - if (!cpuhp_tasks_frozen && printing_via_unlock) { + if (!force_printkthreads() && + !cpuhp_tasks_frozen && + printing_via_unlock) { /* If trylock fails, someone else is doing the printing */ if (console_trylock()) console_unlock(); @@ -3000,31 +3018,43 @@ static bool console_emit_next_record(struct console= *con, bool *handover, int co con->dropped =3D 0; } =20 - /* - * While actively printing out messages, if another printk() - * were to occur on another CPU, it may wait for this one to - * finish. This task can not be preempted if there is a - * waiter waiting to take over. - * - * Interrupts are disabled because the hand over to a waiter - * must not be interrupted until the hand over is completed - * (@console_waiter is cleared). - */ - printk_safe_enter_irqsave(flags); - console_lock_spinning_enable(); + /* Write everything out to the hardware. */ =20 - /* Do not trace print latency. */ - stop_critical_timings(); + if (force_printkthreads()) { + /* + * With forced threading this function is either in a thread + * or panic context. So there is no need for concern about + * printk reentrance or handovers. + */ =20 - /* Write everything out to the hardware. */ - con->write(con, outbuf, pmsg.outbuf_len); + con->write(con, outbuf, pmsg.outbuf_len); + con->seq =3D pmsg.seq + 1; + } else { + /* + * While actively printing out messages, if another printk() + * were to occur on another CPU, it may wait for this one to + * finish. This task can not be preempted if there is a + * waiter waiting to take over. + * + * Interrupts are disabled because the hand over to a waiter + * must not be interrupted until the hand over is completed + * (@console_waiter is cleared). + */ + printk_safe_enter_irqsave(flags); + console_lock_spinning_enable(); =20 - start_critical_timings(); + /* Do not trace print latency. */ + stop_critical_timings(); =20 - con->seq =3D pmsg.seq + 1; + con->write(con, outbuf, pmsg.outbuf_len); =20 - *handover =3D console_lock_spinning_disable_and_check(cookie); - printk_safe_exit_irqrestore(flags); + start_critical_timings(); + + con->seq =3D pmsg.seq + 1; + + *handover =3D console_lock_spinning_disable_and_check(cookie); + printk_safe_exit_irqrestore(flags); + } skip: return true; } @@ -3088,12 +3118,13 @@ static bool console_flush_all(bool do_cond_resched,= u64 *next_seq, bool *handove if ((flags & CON_NBCON) && con->kthread) continue; =20 - if (!console_is_usable(con, flags, true)) + if (!console_is_usable(con, flags, !do_cond_resched)) continue; any_usable =3D true; =20 if (flags & CON_NBCON) { - progress =3D nbcon_legacy_emit_next_record(con, handover, cookie); + progress =3D nbcon_legacy_emit_next_record(con, handover, cookie, + !do_cond_resched); printk_seq =3D nbcon_seq_read(con); } else { progress =3D console_emit_next_record(con, handover, cookie); @@ -3132,19 +3163,7 @@ static bool console_flush_all(bool do_cond_resched, = u64 *next_seq, bool *handove return false; } =20 -/** - * console_unlock - unblock the console subsystem from printing - * - * Releases the console_lock which the caller holds to block printing of - * the console subsystem. - * - * While the console_lock was held, console output may have been buffered - * by printk(). If this is the case, console_unlock(); emits - * the output prior to releasing the lock. - * - * console_unlock(); may be called from any context. - */ -void console_unlock(void) +static void console_flush_and_unlock(void) { bool do_cond_resched; bool handover; @@ -3188,6 +3207,32 @@ void console_unlock(void) */ } while (prb_read_valid(prb, next_seq, NULL) && console_trylock()); } + +/** + * console_unlock - unblock the console subsystem from printing + * + * Releases the console_lock which the caller holds to block printing of + * the console subsystem. + * + * While the console_lock was held, console output may have been buffered + * by printk(). If this is the case, console_unlock(); emits + * the output prior to releasing the lock. + * + * console_unlock(); may be called from any context. + */ +void console_unlock(void) +{ + /* + * Forced threading relies on kthread and atomic consoles for + * printing. It never attempts to print from console_unlock(). + */ + if (force_printkthreads()) { + __console_unlock(); + return; + } + + console_flush_and_unlock(); +} EXPORT_SYMBOL(console_unlock); =20 /** @@ -3411,12 +3456,107 @@ void console_start(struct console *console) flags =3D console_srcu_read_flags(console); if (flags & CON_NBCON) nbcon_kthread_wake(console); + else + wake_up_legacy_kthread(); console_srcu_read_unlock(cookie); =20 __pr_flush(console, 1000, true); } EXPORT_SYMBOL(console_start); =20 +#ifdef CONFIG_PRINTK +static bool printer_should_wake(void) +{ + bool available =3D false; + struct console *con; + int cookie; + + if (kthread_should_stop()) + return true; + + cookie =3D console_srcu_read_lock(); + for_each_console_srcu(con) { + short flags =3D console_srcu_read_flags(con); + u64 printk_seq; + + /* + * The legacy printer thread is only for legacy consoles, + * unless the nbcon console has no kthread printer. + */ + if ((flags & CON_NBCON) && con->kthread) + continue; + + if (!console_is_usable(con, flags, false)) + continue; + + if (flags & CON_NBCON) { + printk_seq =3D nbcon_seq_read(con); + } else { + /* + * It is safe to read @seq because only this + * thread context updates @seq. + */ + printk_seq =3D con->seq; + } + + if (prb_read_valid(prb, printk_seq, NULL)) { + available =3D true; + break; + } + } + console_srcu_read_unlock(cookie); + + return available; +} + +static int nbcon_legacy_kthread_func(void *unused) +{ + int error; + + for (;;) { + error =3D wait_event_interruptible(legacy_wait, printer_should_wake()); + + if (kthread_should_stop()) + break; + + if (error) + continue; + + console_lock(); + console_flush_and_unlock(); + } + + return 0; +} + +void nbcon_legacy_kthread_create(void) +{ + struct task_struct *kt; + + lockdep_assert_held(&console_mutex); + + if (!force_printkthreads()) + return; + + if (!printk_threads_enabled || nbcon_legacy_kthread) + return; + + kt =3D kthread_run(nbcon_legacy_kthread_func, NULL, "pr/legacy"); + if (IS_ERR(kt)) { + pr_err("unable to start legacy printing thread\n"); + return; + } + + nbcon_legacy_kthread =3D kt; + + /* + * It is important that console printing threads are scheduled + * shortly after a printk call and with generous runtime budgets. + */ + sched_set_normal(nbcon_legacy_kthread, -20); +} +#endif /* CONFIG_PRINTK */ + static int __read_mostly keep_bootcon; =20 static int __init keep_bootcon_setup(char *str) @@ -3706,6 +3846,7 @@ void register_console(struct console *newcon) } else { have_legacy_console =3D true; newcon->seq =3D init_seq; + nbcon_legacy_kthread_create(); } =20 if (newcon->flags & CON_BOOT) @@ -3873,6 +4014,13 @@ static int unregister_console_locked(struct console = *console) nbcon_kthread_create(c); } =20 +#ifdef CONFIG_PRINTK + if (!printing_via_unlock && nbcon_legacy_kthread) { + kthread_stop(nbcon_legacy_kthread); + nbcon_legacy_kthread =3D NULL; + } +#endif + return res; } =20 @@ -4031,7 +4179,11 @@ static bool __pr_flush(struct console *con, int time= out_ms, bool reset_on_progre =20 seq =3D prb_next_reserve_seq(prb); =20 - /* Flush the consoles so that records up to @seq are printed. */ + /* + * Flush the consoles so that records up to @seq are printed. + * Otherwise this function will just wait for the threaded printers + * to print up to @seq. + */ if (printing_via_unlock) { console_lock(); console_unlock(); @@ -4146,9 +4298,16 @@ static void wake_up_klogd_work_func(struct irq_work = *irq_work) int pending =3D this_cpu_xchg(printk_pending, 0); =20 if (pending & PRINTK_PENDING_OUTPUT) { - /* If trylock fails, someone else is doing the printing */ - if (console_trylock()) - console_unlock(); + if (force_printkthreads()) { + wake_up_legacy_kthread(); + } else { + /* + * If trylock fails, some other context + * will do the printing. + */ + if (console_trylock()) + console_unlock(); + } } =20 if (pending & PRINTK_PENDING_WAKEUP) --=20 2.39.2 From nobody Fri Feb 13 01:43:51 2026 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 2274013D60F; Mon, 3 Jun 2024 23:25:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457103; cv=none; b=QPmsv+Vbi/iLM1h646CdbZN9e62WoguK2tR6zFyeKVmb1HPRd4ZRvaKnSjtrh6gkWRQMoSWboiGhvHR0tjCugm0RXKzdYukzlhCEpcITTnbUJGz6hOCkHIflskLnsilSD/eQAPzURdzY0bWE8WVxqe8QqGtwi3YZI/MhjX1YbVU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457103; c=relaxed/simple; bh=pchBdNX+BmV4rvRNTuOxcexxXxAppL6xw8kp2sflklw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=hB3ZWn0hI9MCbYBi6fQXwUPFtWB7jar1RI2Jxf3vx5WTRALop37acmsUMRGkL7+suUhEpcJH3yUJE4iq4cx9jyqvw3oJ3q2gc7RrEz2+WFYxQskfpwqXZzkCZNEydlzCIZYmKFZ/IOIBZT+cI5mM4QQjGhSzjS2ysptDftlJuoI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=p3b0apQe; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=i+49gCML; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="p3b0apQe"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="i+49gCML" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1717457099; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=zafvitEOgF5mld5sjHSWRZF0NYguns43RcruL3VlP+g=; b=p3b0apQet3+byj/c+ay4whwYOricKXpiRJt8AoHBquQEtVv7lnlGii6YVC9+3X3xFPGY+U xkXYpnVt6bOIEN9EgkDTB5k785x6l9+L3HrKUK0j00+1AQnRyd8OGLIEzoGqaSu8ekzeSm cnCZ+Sc/Y3MhvGc12IRWfnmPXY3rXi/0JMdcxksDht+QLiON0jn0cDSLJ1CUcLUJol3t7f 6z4kN5sl/GliKR8fpHjCeE/RKe2XEJj0lKGkv1tCPPoK0uIeSNCLG7jAoOnVU5Yrn/Pl+y SKhAo3L2/6XmeJqC39yeerAkUjBkHDbr1NSHnibzqQJuM7tnPYZCF7ZP0/GL9g== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1717457099; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=zafvitEOgF5mld5sjHSWRZF0NYguns43RcruL3VlP+g=; b=i+49gCMLWrGQ2olf0QT+rdl1809ipl0Wqh/rhwHcdXXic75ST1Bx25axeY228r7T3a3WGb qGRjEMT3CvTm9OCA== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH printk v2 13/18] proc: consoles: Add notation to c_start/c_stop Date: Tue, 4 Jun 2024 01:30:48 +0206 Message-Id: <20240603232453.33992-14-john.ogness@linutronix.de> In-Reply-To: <20240603232453.33992-1-john.ogness@linutronix.de> References: <20240603232453.33992-1-john.ogness@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" fs/proc/consoles.c:78:13: warning: context imbalance in 'c_start' - wrong count at exit fs/proc/consoles.c:104:13: warning: context imbalance in 'c_stop' - unexpected unlock Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- fs/proc/consoles.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/proc/consoles.c b/fs/proc/consoles.c index e0758fe7936d..7036fdfa0bec 100644 --- a/fs/proc/consoles.c +++ b/fs/proc/consoles.c @@ -68,6 +68,7 @@ static int show_console_dev(struct seq_file *m, void *v) } =20 static void *c_start(struct seq_file *m, loff_t *pos) + __acquires(&console_mutex) { struct console *con; loff_t off =3D 0; @@ -94,6 +95,7 @@ static void *c_next(struct seq_file *m, void *v, loff_t *= pos) } =20 static void c_stop(struct seq_file *m, void *v) + __releases(&console_mutex) { console_list_unlock(); } --=20 2.39.2 From nobody Fri Feb 13 01:43:51 2026 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 7E74513D62C; Mon, 3 Jun 2024 23:25:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457103; cv=none; b=LG0fAq/r+s9zvHZWDiHYccjE+zuDbNyDMYifxcoY6qgqiIG4FRUGKTYcH2DWunmC7eZpFWzTekpMU2XYOrrKKBEfp0QKrPAh1ZMWncgvt6MYLs3zPiYX8CQz7aU8Hh7Gz2Pi0O8hbgP7oi16AkBhWlzXwXdGiwgQuvhfuMgLRok= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457103; c=relaxed/simple; bh=y/8/D5lsvEkXT9odzpG9/skVj8B2WhjdY/3Pwb613Oc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=dtPXxs2gO/e48Bt2VwFaUllGqwW/nhqV0WNkxGNqOWQc1rLXz/G15TC6q/3LrGaFMp+ji6pT5/mEWATLls9aWIQ2Oc2uch9K75yZ172+3FUB+huCAPp/jDJIXgteU/wGt8YySR+t6xnBGa7aq0oFcbLEA7lwXSxQIgJtNXaxeH8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=Knm8ZSQX; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=O1KZyvD1; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="Knm8ZSQX"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="O1KZyvD1" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1717457099; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=IscutLuG042H8NAY0r6UeOoPwuGyiJXascNGHAe7SFU=; b=Knm8ZSQXG50rKc0ym0n8q5eWNbowd5+U6leS1YNRc3IcWa9at7lDz4Ebe34xrKgAkdpuhO psPTIMCbufR+xCayk5DgtYqDGIPGV/jJ/uBJH1eL5qL87Uu+ExU9Eae0cvSlK1PI1/xLId MKloKy2XIs+hrq9O7BYj+AmeeoUt0Ugps1L0yvtW/V7qAksEsoVt19a/TFNmao+4awW6jI Yz4I3V+CQv+WVD8HyAwq6sxX74iT/mgAHsidlhZAcs9ngo0k5HO0gomDOBLLsEUK8ke6EV +6aSusu4JiFjR166/LKiQSltT7UynuvsfIRA/LeOBsast3o1KuAaA9KnNFTQ1Q== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1717457099; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=IscutLuG042H8NAY0r6UeOoPwuGyiJXascNGHAe7SFU=; b=O1KZyvD1W3n12Nu49nRKux3bZH/acg+7k9G3b8E8sGV3aVZ4J/lXjB3lfJxyvKSORASpO+ m6L+kP00tRrCGHAQ== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH printk v2 14/18] proc: Add nbcon support for /proc/consoles Date: Tue, 4 Jun 2024 01:30:49 +0206 Message-Id: <20240603232453.33992-15-john.ogness@linutronix.de> In-Reply-To: <20240603232453.33992-1-john.ogness@linutronix.de> References: <20240603232453.33992-1-john.ogness@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Update /proc/consoles output to show 'W' if an nbcon write callback is implemented (write_atomic or write_thread). Also update /proc/consoles output to show 'N' if it is an nbcon console. Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- fs/proc/consoles.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/fs/proc/consoles.c b/fs/proc/consoles.c index 7036fdfa0bec..c3c01ec2273c 100644 --- a/fs/proc/consoles.c +++ b/fs/proc/consoles.c @@ -21,12 +21,14 @@ static int show_console_dev(struct seq_file *m, void *v) { CON_ENABLED, 'E' }, { CON_CONSDEV, 'C' }, { CON_BOOT, 'B' }, + { CON_NBCON, 'N' }, { CON_PRINTBUFFER, 'p' }, { CON_BRL, 'b' }, { CON_ANYTIME, 'a' }, }; char flags[ARRAY_SIZE(con_flags) + 1]; struct console *con =3D v; + char con_write =3D '-'; unsigned int a; dev_t dev =3D 0; =20 @@ -57,9 +59,15 @@ static int show_console_dev(struct seq_file *m, void *v) seq_setwidth(m, 21 - 1); seq_printf(m, "%s%d", con->name, con->index); seq_pad(m, ' '); - seq_printf(m, "%c%c%c (%s)", con->read ? 'R' : '-', - con->write ? 'W' : '-', con->unblank ? 'U' : '-', - flags); + if (con->flags & CON_NBCON) { + if (con->write_atomic || con->write_thread) + con_write =3D 'W'; + } else { + if (con->write) + con_write =3D 'W'; + } + seq_printf(m, "%c%c%c (%s)", con->read ? 'R' : '-', con_write, + con->unblank ? 'U' : '-', flags); if (dev) seq_printf(m, " %4d:%d", MAJOR(dev), MINOR(dev)); =20 --=20 2.39.2 From nobody Fri Feb 13 01:43:51 2026 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 4014083CD8; Mon, 3 Jun 2024 23:25:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457104; cv=none; b=Xmk6eTV/uHGJkIQp/I2Zx0KpB/OFRzpf1tnZl5HOIMzZiQVV3WpHLrqLoXv5ERHfQbNDLr2RI5sKh2CNmKD3NkJl97cWL3kNCFD6dh14EVIjSARY2ATAeBFPBwlqZfO+nfvBpIS2tLVCUjbMnW/2ozbHool9HMIBnmLlaZ2DHvA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457104; c=relaxed/simple; bh=iFe7QTOJaIZ96iBr5IJNXeHec/OczXjluE+9uE64m5U=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=lJrVoRFOsFVWhsqvTwKcg9zQvN/GrFgKlahjsLlomwns1YticUBjJqPFyFQQ3jD7ciFpFbXvSGM0ohhGdTQdR7VadiSp8gPjd41Q0sXmuKpBiPoaacdvORy+Hwl1P0Dd22f2sRhrIGjuZj62/jwAUGuHVnX6J5FDSqxEZDhju1A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=RubfaJ21; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=3VHXF6oe; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="RubfaJ21"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="3VHXF6oe" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1717457100; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=AVOojb4+PpMY1V+1K9x0e9ZnUQCXKs719BnreW8cqRo=; b=RubfaJ21CaXktnflUH7lDlQT0oDJ4xfHIFVQvMDtT+1w44RUsTKBxRViXeoUKY/zceV1bU HeKeZJZCjUGlxY6yPU4wsaIvbr4iZmKHEwbTRtw3obLvtsaflGd5f8UboRPVqulLAKb8in L1Fn5CZ4HvOwhDwxxfm9OwL084/7aHPe3BhdwoxV3kXlPmPB/8dYsgcy8TLx7PERR92b67 FmijEEwoF3KWX+M5aSlP8VQpUd9jwzHKEHGThEDGmE9pAYI3umf7dUSf2IUm6pOLDJ4Szi wh/xDjw+FjX72Owum1j34Q4tAjE63HMzH5daPzimwddr9eoqSOFcntGa9UqVgA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1717457100; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=AVOojb4+PpMY1V+1K9x0e9ZnUQCXKs719BnreW8cqRo=; b=3VHXF6oejKzbZBE03RCA1YmIECu7IUwL9FS6L0OkNOAerzWOodexOCtM1ODvmzCfeJRKkM j4oOnwZIuGB5DFDg== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Greg Kroah-Hartman , Jiri Slaby , linux-serial@vger.kernel.org Subject: [PATCH printk v2 15/18] tty: sysfs: Add nbcon support for 'active' Date: Tue, 4 Jun 2024 01:30:50 +0206 Message-Id: <20240603232453.33992-16-john.ogness@linutronix.de> In-Reply-To: <20240603232453.33992-1-john.ogness@linutronix.de> References: <20240603232453.33992-1-john.ogness@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Allow the 'active' attribute to list nbcon consoles. Signed-off-by: John Ogness Acked-by: Greg Kroah-Hartman Reviewed-by: Petr Mladek --- drivers/tty/tty_io.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 407b0d87b7c1..c9c914bc033c 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -3567,8 +3567,13 @@ static ssize_t show_cons_active(struct device *dev, for_each_console(c) { if (!c->device) continue; - if (!c->write) - continue; + if (c->flags & CON_NBCON) { + if (!c->write_atomic && !c->write_thread) + continue; + } else { + if (!c->write) + continue; + } if ((c->flags & CON_ENABLED) =3D=3D 0) continue; cs[i++] =3D c; --=20 2.39.2 From nobody Fri Feb 13 01:43:51 2026 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 82A7A83CD6; Mon, 3 Jun 2024 23:25:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457104; cv=none; b=duDPlXUZ06oOKIQsCKTvh2rKzH06JkIZfPq0eJW1apnSvfgceb9iRm2g7Oc1/GagUTcz2k/wEZDwTISIqTvUuk3/HGuP1OdcXvHOJ0IfbjTTUbwBtB66uK/sgcET0g2DfEU9WM6Ul/T53IcWbe1Hor3VMC93a8aDi2LdVChCXkQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457104; c=relaxed/simple; bh=bcxSj8Z9J7RmjktPYNIzMOPv60DtDpqqHz/KdcZ02yA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=rx55/JZzPvg1zk/jKsnMaNhOI84ULGZyv0oRFRu3PiSnHD+V1pcq5aF/yTOZdwdr1I2jqhQ5wAIrshrDfYScXJM/7nWVQxMdQOxJggoIssXgtTqg6ZBxCehamIHVvdi6DMA2WXiE05rtn5zTcPLAI8LBTHKnPvdLOcB4YDFrhhQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=ky2BsJyO; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=zAsX5JrJ; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="ky2BsJyO"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="zAsX5JrJ" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1717457100; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7wwQIXYMP7sQGXrKm7reS+lNLiSQvf56nu+6ghCbaPM=; b=ky2BsJyOWTW4ECgcrsvSmWLnUuYxVlhQ+1oRAjl+tjYaSaOh8ukRpiHlAuM0/D4B6Vb5St JKxQj/MejhjrKoH5qAzGJBsPBl9DcLWniFPJgxVvPcQ82OL/RbI7lA6p64K50B8r1pBlKe 9cvZSaJP2uHGNiPfq/iWt9Av9Hlp53uwgh243lhEvZ7WoC3GbUoG4AgMigvIB81nEovH2o 8SPDIazcfijqohs7ZpRkdayi2UPMwpOQnu+FRaralEEUNUbtY0fwM186GKDG6tClv6kkcD J5M23o1Iur+hFgT47yba+Etdouf6y5yzeoEue40mAR4+sI9JQGdEQ83axpHhLA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1717457100; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7wwQIXYMP7sQGXrKm7reS+lNLiSQvf56nu+6ghCbaPM=; b=zAsX5JrJWtbhPiqDA7nRFKV+o2E3nQHOqXddS44mXB16BTP0VwYTpdHV/x1c10ZiKyJVe2 lMDKAajg8wmpMiCQ== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Jonathan Corbet , "Paul E. McKenney" , Josh Poimboeuf , "Borislav Petkov (AMD)" , Xiongwei Song , linux-doc@vger.kernel.org Subject: [PATCH printk v2 16/18] printk: Provide threadprintk boot argument Date: Tue, 4 Jun 2024 01:30:51 +0206 Message-Id: <20240603232453.33992-17-john.ogness@linutronix.de> In-Reply-To: <20240603232453.33992-1-john.ogness@linutronix.de> References: <20240603232453.33992-1-john.ogness@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" For PREEMPT_RT, legacy console printing is performed in a dedicated kthread. However, this behavior can also be interesting for other preemption models as it minimizes the duration of printk() calls by deferring all printing. Provide a new boot argument "threadprintk" that will create the dedicated kthread for legacy console printing for !PREEMPT_RT systems. The implementation is the same as the "threadirqs" boot argument. Users should be aware that if this option is enabled, the shutdown, reboot, and panic messages probably will not be visible on the legacy consoles. Non-legacy consoles (NBCON) already have their own dedicated kernel threads for printing and reliable shutdown, reboot, and panic printing. This option really only applies to legacy consoles. Users can view /proc/consoles to see if their console driver is legacy or not. NBCON console drivers are shown with 'N'. Signed-off-by: John Ogness --- Documentation/admin-guide/kernel-parameters.txt | 12 ++++++++++++ kernel/printk/internal.h | 4 +++- kernel/printk/printk.c | 11 +++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentatio= n/admin-guide/kernel-parameters.txt index 45d95614ec44..17977dd4fafa 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -6572,6 +6572,18 @@ Force threading of all interrupt handlers except those marked explicitly IRQF_NO_THREAD. =20 + threadprintk [KNL] + Force threaded printing of all legacy consoles. Be + aware that with this option, the shutdown, reboot, and + panic messages may not be printed on the legacy + consoles. Also, earlycon/earlyprintk printing will be + delayed until a regular console or the kthread is + available. + + Users can view /proc/consoles to see if their console + driver is legacy or not. Non-legacy (NBCON) console + drivers are already threaded and are shown with 'N'. + topology=3D [S390,EARLY] Format: {off | on} Specify if the kernel should make use of the cpu diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h index b66dfa865591..48c3564f95eb 100644 --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h @@ -3,6 +3,7 @@ * internal.h - printk internal definitions */ #include +#include #include #include =20 @@ -24,7 +25,8 @@ int devkmsg_sysctl_set_loglvl(struct ctl_table *table, in= t write, #ifdef CONFIG_PREEMPT_RT # define force_printkthreads() (true) #else -# define force_printkthreads() (false) +DECLARE_STATIC_KEY_FALSE(force_printkthreads_key); +# define force_printkthreads() (static_branch_unlikely(&force_printkthrea= ds_key)) #endif =20 #ifdef CONFIG_PRINTK diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 1c63fd0c1166..ea2d66152256 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -195,6 +195,17 @@ static int __init control_devkmsg(char *str) } __setup("printk.devkmsg=3D", control_devkmsg); =20 +#if !defined(CONFIG_PREEMPT_RT) +DEFINE_STATIC_KEY_FALSE(force_printkthreads_key); + +static int __init setup_forced_printkthreads(char *arg) +{ + static_branch_enable(&force_printkthreads_key); + return 0; +} +early_param("threadprintk", setup_forced_printkthreads); +#endif + char devkmsg_log_str[DEVKMSG_STR_MAX_SIZE] =3D "ratelimit"; #if defined(CONFIG_PRINTK) && defined(CONFIG_SYSCTL) int devkmsg_sysctl_set_loglvl(struct ctl_table *table, int write, --=20 2.39.2 From nobody Fri Feb 13 01:43:51 2026 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 C6F8F13DBAC for ; Mon, 3 Jun 2024 23:25:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457104; cv=none; b=M3d6sNYhssDJhCKCyyYu9pnZj3pq92MzJi4/js5IOeY7Fy066S0028ocIlZUeu/SwP37ErGzSFW0TllfiwqBMBOI3JQAcdhd42QnMJrfOSJkouGTGDftU89hwouoibdPEXjq5x1Qth/zepE9ItcO2iIpw+kFBbRcAT8urOcGeLU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457104; c=relaxed/simple; bh=C1k4nrK1iq4FjzW78Pvi6zuZX9GDxOVMSJk36U/8Zes=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=sQCl2LA+nMgqpkez5THlqYpX3od8X6WhYctCZJvZOVYa3yeZQ5SNeSkHP3c64lXbuNBnizQ6uFFIMJ0upzSMqfqslWnCRKOgJkP901Vqa5B43Msfi61u2x7mGQ6SdIQQsglEubU6ed6CIbr3XuTYjpqDj9HaUpeVBVkA6kK6+Tw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=e6gwfjl+; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=04ih2jog; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="e6gwfjl+"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="04ih2jog" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1717457101; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Z/pSuGQVGxMFZfKH/E+GtrVGnqXqVv7X9AWkemvHQKk=; b=e6gwfjl+AQxvQFqUY15qKWXJbRzYRogpvkE20qtFNxeIszR4xKA60jCPoR9oiHgrC8cOUt QDXuBFpnGB1rDlUTJw4puKC91/e7K23Xj6xydqwUrrvPQORuH2fXKkDt1haI4qRDmrv2LX LO/DlWu6DRIj0Gsji9yuLQaDI2fgVLc014e96NwSZjdlSXC6ymt/LxxEJ7be0PbTFHIVWf gDhj97MB7KMi5ohN8q7PeWa/a4ACAFXXgAiyywpI0rPNBvC7TmtbnOlGgSBbh4jcdv7lvv TsmqIeH3sQ4zNY1KYAOVO4QxIpa2DzyiqMzTPWSey58iGyA86dZpuK3yj/uQiQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1717457101; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Z/pSuGQVGxMFZfKH/E+GtrVGnqXqVv7X9AWkemvHQKk=; b=04ih2jogpo2jd8gP+ByGzyWb1xIsroVU3p4E9ly6g5W4Da1VRPWgacUZAqjkYvro6Xc7Jb ryDTTLpnoEn4F6CA== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v2 17/18] printk: Avoid false positive lockdep report for legacy printing Date: Tue, 4 Jun 2024 01:30:52 +0206 Message-Id: <20240603232453.33992-18-john.ogness@linutronix.de> In-Reply-To: <20240603232453.33992-1-john.ogness@linutronix.de> References: <20240603232453.33992-1-john.ogness@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Legacy console printing from printk() caller context may invoke the console driver from atomic context. This leads to a lockdep splat because the console driver will acquire a sleeping lock and the caller may already hold a spinning lock. This is noticed by lockdep on !PREEMPT_RT configurations because it will lead to a problem on PREEMPT_RT. However, on PREEMPT_RT the printing path from atomic context is always avoided and the console driver is always invoked from a dedicated thread. Thus the lockdep splat on !PREEMPT_RT is a false positive. For !PREEMPT_RT override the lock-context before invoking the console driver to avoid the false positive. Do not override the lock-context for PREEMPT_RT in order to allow lockdep to catch any real locking context issues related to the write callback usage. Signed-off-by: John Ogness --- kernel/printk/printk.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index ea2d66152256..5e9778f69206 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -2980,6 +2980,33 @@ bool printk_get_next_message(struct printk_message *= pmsg, u64 seq, return true; } =20 +/* + * Legacy console printing from printk() caller context does not respect + * raw_spinlock/spinlock nesting. For !PREEMPT_RT the lockdep warning is a + * false positive. For PREEMPT_RT the false positive condition does not + * occur. + * + * This map is used to establish LD_WAIT_SLEEP context for the console wri= te + * callbacks when legacy printing to avoid false positive lockdep complain= ts, + * thus allowing lockdep to continue to function for real issues. + */ +#ifdef CONFIG_PREEMPT_RT +static inline void printk_legacy_lock_map_acquire_try(void) { } +static inline void printk_legacy_lock_map_release(void) { } +#else +static DEFINE_WAIT_OVERRIDE_MAP(printk_legacy_map, LD_WAIT_SLEEP); + +static inline void printk_legacy_lock_map_acquire_try(void) +{ + lock_map_acquire_try(&printk_legacy_map); +} + +static inline void printk_legacy_lock_map_release(void) +{ + lock_map_release(&printk_legacy_map); +} +#endif /* CONFIG_PREEMPT_RT */ + /* * Used as the printk buffers for non-panic, serialized console printing. * This is for legacy (!CON_NBCON) as well as all boot (CON_BOOT) consoles. @@ -3035,7 +3062,7 @@ static bool console_emit_next_record(struct console *= con, bool *handover, int co /* * With forced threading this function is either in a thread * or panic context. So there is no need for concern about - * printk reentrance or handovers. + * printk reentrance, handovers, or lockdep complaints. */ =20 con->write(con, outbuf, pmsg.outbuf_len); @@ -3057,7 +3084,9 @@ static bool console_emit_next_record(struct console *= con, bool *handover, int co /* Do not trace print latency. */ stop_critical_timings(); =20 + printk_legacy_lock_map_acquire_try(); con->write(con, outbuf, pmsg.outbuf_len); + printk_legacy_lock_map_release(); =20 start_critical_timings(); =20 --=20 2.39.2 From nobody Fri Feb 13 01:43:51 2026 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 BF1E613DB99 for ; Mon, 3 Jun 2024 23:25:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457105; cv=none; b=PkazDtERN2zTXJDSQkrO2JNdw/4lCryLrkv9uD5mTzHFVydn0a1oLDfnXVIq2MNvGy9VH5neah4XZ97EmyzZW/qvVY4zq+QH66mRoTSO9wBbj6lXat2cIU5RmNHy37o4Pc0eTVKp/cDMH5+DKVS5AEveSQu0ja2Igg5cXIIX6cw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717457105; c=relaxed/simple; bh=mw7cQ+FxaYowLEMZlVrUFi9i+grzxHJlJgNLS1vc3NE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=QIsj1U1qoCEV4N5vqV+QpINOE16wS+H5z/FPLzib5pDDk+qzM5UrKiN7HPMTGgC7u+OqWjV+KS+CvwDt0Ka9qIgUKXsWOloR04sPS8Xb7p3yIfl1pSsJNCgVaRTOTI9Owlnkr4djysdgSa2+Epi9YHoJ31w7j0/VUyksKEDaGpA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=i8jFjHw+; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=VhR94kBB; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="i8jFjHw+"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="VhR94kBB" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1717457101; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Ic2rSbk+60U0wta2R3AH4a6suWFhXIL12Fm/tXauPlI=; b=i8jFjHw+saIi0bOZ80VAukv7aDi98Lfx4hiUjv9uqdqcFm4+jjEBzEzo83leDrb25bOikV p6CpMpq5kWNZa9nEv+U1raT9z6CZKxMk+OnHOWyQ4r/shbr0mun+7T48puGb9KuRAy03tr gqv/jQfeNL8uDs77RqVYSN+mJ8hyI1y594tsFW/pfZ5pVqSSJa17K9r+597aKGpK7QntBq c5EEnWySetR25WN61CrJg1ap5rTQnrzkX/DewLqaWoJAI9korZSC9q7RHkswwVKT1v4Qbh 2aF8suuGPlir5WandgKcoRQlweo0iM16KAtsxxbshEToZ6WCQdIaYoLyMk0K7w== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1717457101; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Ic2rSbk+60U0wta2R3AH4a6suWFhXIL12Fm/tXauPlI=; b=VhR94kBBQojOusNbQnESARW2oY7H6lF7un9C1awKKgs8E3f9dKZVCdP/eRaPgbSffhCwfm ZhKB7bruNHpNukDw== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Greg Kroah-Hartman Subject: [PATCH printk v2 18/18] printk: nbcon: Add function for printers to reacquire ownership Date: Tue, 4 Jun 2024 01:30:53 +0206 Message-Id: <20240603232453.33992-19-john.ogness@linutronix.de> In-Reply-To: <20240603232453.33992-1-john.ogness@linutronix.de> References: <20240603232453.33992-1-john.ogness@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Since ownership can be lost at any time due to handover or takeover, a printing context _must_ be prepared to back out immediately and carefully. However, there are scenarios where the printing context must reacquire ownership in order to finalize or revert hardware changes. One such example is when interrupts are disabled during printing. No other context will automagically re-enable the interrupts. For this case, the disabling context _must_ reacquire nbcon ownership so that it can re-enable the interrupts. Provide nbcon_reacquire() for exactly this purpose. It allows a printing context to reacquire ownership using the same priority as its previous ownership. Note that after a successful reacquire the printing context will have no output buffer because that has been lost. This function cannot be used to resume printing. Signed-off-by: John Ogness --- include/linux/console.h | 6 ++++++ kernel/printk/nbcon.c | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/include/linux/console.h b/include/linux/console.h index 9927f08ac054..96c0923d023b 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -372,6 +372,10 @@ struct console { * * The callback should allow the takeover whenever it is safe. It * increases the chance to see messages when the system is in trouble. + * If the driver must reacquire ownership in order to finalize or + * revert hardware changes, nbcon_reacquire() can be used. However, + * on reacquire the buffer content is no longer available. A + * reacquire cannot be used to resume printing. * * The callback can be called from any context (including NMI). * Therefore it must avoid usage of any locking and instead rely @@ -591,6 +595,7 @@ extern void nbcon_cpu_emergency_flush(void); extern bool nbcon_can_proceed(struct nbcon_write_context *wctxt); extern bool nbcon_enter_unsafe(struct nbcon_write_context *wctxt); extern bool nbcon_exit_unsafe(struct nbcon_write_context *wctxt); +extern void nbcon_reacquire(struct nbcon_write_context *wctxt); #else static inline void nbcon_cpu_emergency_enter(void) { } static inline void nbcon_cpu_emergency_exit(void) { } @@ -598,6 +603,7 @@ static inline void nbcon_cpu_emergency_flush(void) { } static inline bool nbcon_can_proceed(struct nbcon_write_context *wctxt) { = return false; } static inline bool nbcon_enter_unsafe(struct nbcon_write_context *wctxt) {= return false; } static inline bool nbcon_exit_unsafe(struct nbcon_write_context *wctxt) { = return false; } +static inline void nbcon_reacquire(struct nbcon_write_context *wctxt) { } #endif =20 extern int console_set_on_cmdline; diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c index e8060b5abdf8..4b9645e7ed70 100644 --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c @@ -838,6 +838,38 @@ bool nbcon_exit_unsafe(struct nbcon_write_context *wct= xt) } EXPORT_SYMBOL_GPL(nbcon_exit_unsafe); =20 +/** + * nbcon_reacquire - Reacquire a console after losing ownership while prin= ting + * @wctxt: The write context that was handed to the write callback + * + * Since ownership can be lost at any time due to handover or takeover, a + * printing context _must_ be prepared to back out immediately and + * carefully. However, there are scenarios where the printing context must + * reacquire ownership in order to finalize or revert hardware changes. + * + * This function allows a printing context to reacquire ownership using the + * same priority as its previous ownership. + * + * Note that after a successful reacquire the printing context will have no + * output buffer because that has been lost. This function cannot be used = to + * resume printing. + */ +void nbcon_reacquire(struct nbcon_write_context *wctxt) +{ + struct nbcon_context *ctxt =3D &ACCESS_PRIVATE(wctxt, ctxt); + struct console *con =3D ctxt->console; + struct nbcon_state cur; + + while (!nbcon_context_try_acquire(ctxt)) + cpu_relax(); + + wctxt->outbuf =3D NULL; + wctxt->len =3D 0; + nbcon_state_read(con, &cur); + wctxt->unsafe_takeover =3D cur.unsafe_takeover; +} +EXPORT_SYMBOL_GPL(nbcon_reacquire); + /** * nbcon_emit_next_record - Emit a record in the acquired context * @wctxt: The write context that will be handed to the write function @@ -945,6 +977,15 @@ static bool nbcon_emit_next_record(struct nbcon_write_= context *wctxt, bool use_a return false; } =20 + if (!wctxt->outbuf) { + /* + * Ownership was lost and reacquired by the driver. + * Handle it as if ownership was lost. + */ + nbcon_context_release(ctxt); + return false; + } + /* * Since any dropped message was successfully output, reset the * dropped count for the console. --=20 2.39.2