From nobody Sun Feb 8 00:38:59 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D9816EB64DA for ; Mon, 10 Jul 2023 13:45:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232986AbjGJNpf (ORCPT ); Mon, 10 Jul 2023 09:45:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50466 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229907AbjGJNpb (ORCPT ); Mon, 10 Jul 2023 09:45:31 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 97E31FB for ; Mon, 10 Jul 2023 06:45:29 -0700 (PDT) From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1688996727; 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=B9NLpZDV0rDJscklMexuqubYAOrVOVFP5G0SfhKaC40=; b=mPH34seK6EKd96789117404thhQ8iF13OLpNr8Rr4KlkQwNJABW99gTYK+7HnIjltRHnN+ 2yJBLZcArEG9Xrwkd0d3MiWAydDpHP2tGyam99KieBiEmInY5CgsIn9vHkwsUk48Ee7eTR zNXJ3sN2/CVr6hYmUfI8t+JcrOZTuJDijmKzFRqMq5CrrEl6NacvXqO8OgPDyAx+LvFEt1 ubf3eSzQxZ1WFEW5moucTAYNP/I+xcORGxd3pkhprECltFA9rFynae9SUdxlVFYQRNtgXP 7eZX3/eMHsZSZlnvQUf8ctTN32aOL3r+d9aTnkOWLj0gjRn2yIF/TpORQgS1FA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1688996727; 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=B9NLpZDV0rDJscklMexuqubYAOrVOVFP5G0SfhKaC40=; b=MimllhStnyB8UVIm3i7qxoahyZlF7eOmcJSKU+Xf2Frp7wMCiRdG+vr3tcFXyKXVdnFhAQ reR+NH86j4GeIbDw== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Jason Wessel , Daniel Thompson , Douglas Anderson , Aaron Tomlin , kgdb-bugreport@lists.sourceforge.net Subject: [PATCH printk v2 1/5] kdb: do not assume write() callback available Date: Mon, 10 Jul 2023 15:51:20 +0206 Message-Id: <20230710134524.25232-2-john.ogness@linutronix.de> In-Reply-To: <20230710134524.25232-1-john.ogness@linutronix.de> References: <20230710134524.25232-1-john.ogness@linutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" It is allowed for consoles to provide no write() callback. For example ttynull does this. Check if a write() callback is available before using it. Signed-off-by: John Ogness Reviewed-by: Petr Mladek Reviewed-by: Douglas Anderson Reviewed-by: Daniel Thompson Acked-by: Daniel Thompson Reviewed-by: Sergey Senozhatsky --- kernel/debug/kdb/kdb_io.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/debug/kdb/kdb_io.c b/kernel/debug/kdb/kdb_io.c index 5c7e9ba7cd6b..e9139dfc1f0a 100644 --- a/kernel/debug/kdb/kdb_io.c +++ b/kernel/debug/kdb/kdb_io.c @@ -576,6 +576,8 @@ static void kdb_msg_write(const char *msg, int msg_len) continue; if (c =3D=3D dbg_io_ops->cons) continue; + if (!c->write) + continue; /* * Set oops_in_progress to encourage the console drivers to * disregard their internal spin locks: in the current calling --=20 2.30.2 From nobody Sun Feb 8 00:38:59 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 172C0EB64DA for ; Mon, 10 Jul 2023 13:45:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233039AbjGJNpl (ORCPT ); Mon, 10 Jul 2023 09:45:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50482 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232058AbjGJNpb (ORCPT ); Mon, 10 Jul 2023 09:45:31 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 97D9CEB for ; Mon, 10 Jul 2023 06:45:29 -0700 (PDT) From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1688996728; 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=XsZWA8451BPr7/Ud83/6VPIROKIK25FqP0KDzoKAhWM=; b=Mw3dc/a9jAPsfBXa5qx/sQ5RoWbHUyxm3PcE/jk9l4Jo81VrtkX8XspuI6hcpszFAEY5IT uWaMvEh8eMn+5FyYnmuWegEPDM0S1yEO72QKpIg68GB5/MpCav+/158g+K8s4LCqh71bYm BM+8Xzl+2M/ir2jlCOGc1nCwz/YvZOT73up0J2r7Opkeloi4xQJn/AYMBzKyaA3z3ycdXg JiI0uQftmXA3T79fPU3qrC4zpi/2GOjsfc4ckoFXbfCKUkQq8fWj5ZJheGPmCM2zQK25wB Z8GzftlQYR46pfqzfPYmvChFata0f8Kmq0ccCZMYUUUGhIxWfktCuuZwJGneaw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1688996728; 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=XsZWA8451BPr7/Ud83/6VPIROKIK25FqP0KDzoKAhWM=; b=V0iW5iYy+XU5xZIBorpzPgtN6zAAFRNG4EASSrDUuRkWb1hfOTqfOQfkfXGyvTCLM8mU9h RriOhxkUWRIefXDQ== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v2 2/5] printk: Add NMI safety to console_flush_on_panic() and console_unblank() Date: Mon, 10 Jul 2023 15:51:21 +0206 Message-Id: <20230710134524.25232-3-john.ogness@linutronix.de> In-Reply-To: <20230710134524.25232-1-john.ogness@linutronix.de> References: <20230710134524.25232-1-john.ogness@linutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The printk path is NMI safe because it only adds content to the buffer and then triggers the delayed output via irq_work. If the console is flushed or unblanked on panic (from NMI context) then it can deadlock in down_trylock_console_sem() because the semaphore is not NMI safe. Avoid taking the console lock when flushing in panic. To prevent other CPUs from taking the console lock while flushing, have console_lock() block and console_trylock() fail for non-panic CPUs during panic. Skip unblanking in panic if the current context is NMI. Signed-off-by: John Ogness --- kernel/printk/printk.c | 77 +++++++++++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 28 deletions(-) diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 9644f6e5bf15..8a6c917dc081 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -2583,6 +2583,25 @@ static int console_cpu_notify(unsigned int cpu) return 0; } =20 +/* + * Return true when this CPU should unlock console_sem without pushing all + * messages to the console. This reduces the chance that the console is + * locked when the panic CPU tries to use it. + */ +static bool abandon_console_lock_in_panic(void) +{ + if (!panic_in_progress()) + return false; + + /* + * We can use raw_smp_processor_id() here because it is impossible for + * the task to be migrated to the panic_cpu, or away from it. If + * panic_cpu has already been set, and we're not currently executing on + * that CPU, then we never will be. + */ + return atomic_read(&panic_cpu) !=3D raw_smp_processor_id(); +} + /** * console_lock - block the console subsystem from printing * @@ -2595,6 +2614,10 @@ void console_lock(void) { might_sleep(); =20 + /* On panic, the console_lock must be left to the panic cpu. */ + while (abandon_console_lock_in_panic()) + msleep(1000); + down_console_sem(); if (console_suspended) return; @@ -2613,6 +2636,9 @@ EXPORT_SYMBOL(console_lock); */ int console_trylock(void) { + /* On panic, the console_lock must be left to the panic cpu. */ + if (abandon_console_lock_in_panic()) + return 0; if (down_trylock_console_sem()) return 0; if (console_suspended) { @@ -2631,25 +2657,6 @@ int is_console_locked(void) } EXPORT_SYMBOL(is_console_locked); =20 -/* - * Return true when this CPU should unlock console_sem without pushing all - * messages to the console. This reduces the chance that the console is - * locked when the panic CPU tries to use it. - */ -static bool abandon_console_lock_in_panic(void) -{ - if (!panic_in_progress()) - return false; - - /* - * We can use raw_smp_processor_id() here because it is impossible for - * the task to be migrated to the panic_cpu, or away from it. If - * panic_cpu has already been set, and we're not currently executing on - * that CPU, then we never will be. - */ - return atomic_read(&panic_cpu) !=3D raw_smp_processor_id(); -} - /* * Check if the given console is currently capable and allowed to print * records. @@ -3054,6 +3061,10 @@ void console_unblank(void) * In that case, attempt a trylock as best-effort. */ if (oops_in_progress) { + /* Semaphores are not NMI-safe. */ + if (in_nmi()) + return; + if (down_trylock_console_sem() !=3D 0) return; } else @@ -3083,14 +3094,24 @@ void console_unblank(void) */ void console_flush_on_panic(enum con_flush_mode mode) { + bool handover; + u64 next_seq; + /* - * If someone else is holding the console lock, trylock will fail - * and may_schedule may be set. Ignore and proceed to unlock so - * that messages are flushed out. As this can be called from any - * context and we don't want to get preempted while flushing, - * ensure may_schedule is cleared. + * Ignore the console lock and flush out the messages. Attempting a + * trylock would not be useful because: + * + * - if it is contended, it must be ignored anyway + * - console_lock() and console_trylock() block and fail + * respectively in panic for non-panic CPUs + * - semaphores are not NMI-safe + */ + + /* + * If another context is holding the console lock, + * @console_may_schedule might be set. Clear it so that + * this context does not call cond_resched() while flushing. */ - console_trylock(); console_may_schedule =3D 0; =20 if (mode =3D=3D CONSOLE_REPLAY_ALL) { @@ -3103,15 +3124,15 @@ void console_flush_on_panic(enum con_flush_mode mod= e) cookie =3D console_srcu_read_lock(); for_each_console_srcu(c) { /* - * If the above console_trylock() failed, this is an - * unsynchronized assignment. But in that case, the + * This is an unsynchronized assignment, but the * kernel is in "hope and pray" mode anyway. */ c->seq =3D seq; } console_srcu_read_unlock(cookie); } - console_unlock(); + + console_flush_all(false, &next_seq, &handover); } =20 /* --=20 2.30.2 From nobody Sun Feb 8 00:38:59 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 71CF7EB64DC for ; Mon, 10 Jul 2023 13:45:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233025AbjGJNph (ORCPT ); Mon, 10 Jul 2023 09:45:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50474 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231382AbjGJNpb (ORCPT ); Mon, 10 Jul 2023 09:45:31 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9CEF3FE for ; Mon, 10 Jul 2023 06:45:29 -0700 (PDT) From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1688996728; 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=gNoZRjtYvz+muzS7qSrxZkmQzTEAXcTSx4NPxxauFRc=; b=dmXuNtNql6F9emsQAi7+TV8RVDFsgs/MSWxH3vWrxR75nEc4ecMk3zgTO2CrhNzZEuwxeY 4xLtw9hxiqEjuxvOoNKLHl8ni1PIqh+tOv8g26LLOXl3CvkNk2KIZb0tBVfICSxz6TXR0I +xChvwdiuLZ8QGO+8VsCk7NbpB/YWqPhosAcBQlM8Z4Qojn40eIjiuUzz1dudqj39JEz2t q4npg8Scp2qOU+3tu24rQhIcOUP1B3ZG5Ldu+O3A1l5VfAr1qeQs104Gjsh4rh0o30htIk rnazfhrVUD2rQUgZrk1eYtFgRK8/VKp6tNC1GHduecHy/TOjqVSqWZeh6EFTmg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1688996728; 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=gNoZRjtYvz+muzS7qSrxZkmQzTEAXcTSx4NPxxauFRc=; b=MkXNNujyGh+shQ0/nLVDn/7Uxr5/7KEvPHgmKG2qVky0opg0FfV/QtypgOp4ZX6npSJzKH vacKBcLg34H2F7Cw== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v2 3/5] printk: Consolidate console deferred printing Date: Mon, 10 Jul 2023 15:51:22 +0206 Message-Id: <20230710134524.25232-4-john.ogness@linutronix.de> In-Reply-To: <20230710134524.25232-1-john.ogness@linutronix.de> References: <20230710134524.25232-1-john.ogness@linutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Printing to consoles can be deferred for several reasons: - explicitly with printk_deferred() - printk() in NMI context - recursive printk() calls The current implementation is not consistent. For printk_deferred(), irq work is scheduled twice. For NMI und recursive, panic CPU suppression and caller delays are not properly enforced. Correct these inconsistencies by consolidating the deferred printing code so that vprintk_deferred() is the top-level function for deferred printing and vprintk_emit() will perform whichever irq_work queueing is appropriate. Also add kerneldoc for wake_up_klogd() and defer_console_output() to clarify their differences and appropriate usage. Signed-off-by: John Ogness --- kernel/printk/printk.c | 35 ++++++++++++++++++++++++++++------- kernel/printk/printk_safe.c | 9 ++------- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 8a6c917dc081..e7632ed3b6fd 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -2306,7 +2306,11 @@ asmlinkage int vprintk_emit(int facility, int level, preempt_enable(); } =20 - wake_up_klogd(); + if (in_sched) + defer_console_output(); + else + wake_up_klogd(); + return printed_len; } EXPORT_SYMBOL(vprintk_emit); @@ -3817,11 +3821,33 @@ static void __wake_up_klogd(int val) preempt_enable(); } =20 +/** + * wake_up_klogd - Wake kernel logging daemon + * + * Use this function when new records have been added to the ringbuffer + * and the console printing of those records has already occurred or is + * known to be handled by some other context. This function will only + * wake the logging daemon. + * + * Context: Any context. + */ void wake_up_klogd(void) { __wake_up_klogd(PRINTK_PENDING_WAKEUP); } =20 +/** + * defer_console_output - Wake kernel logging daemon and trigger + * console printing in a deferred context + * + * Use this function when new records have been added to the ringbuffer, + * this context is responsible for console printing those records, but + * the current context is not allowed to perform the console printing. + * Trigger an irq_work context to perform the console printing. This + * function also wakes the logging daemon. + * + * Context: Any context. + */ void defer_console_output(void) { /* @@ -3838,12 +3864,7 @@ void printk_trigger_flush(void) =20 int vprintk_deferred(const char *fmt, va_list args) { - int r; - - r =3D vprintk_emit(0, LOGLEVEL_SCHED, NULL, fmt, args); - defer_console_output(); - - return r; + return vprintk_emit(0, LOGLEVEL_SCHED, NULL, fmt, args); } =20 int _printk_deferred(const char *fmt, ...) diff --git a/kernel/printk/printk_safe.c b/kernel/printk/printk_safe.c index ef0f9a2044da..6d10927a07d8 100644 --- a/kernel/printk/printk_safe.c +++ b/kernel/printk/printk_safe.c @@ -38,13 +38,8 @@ asmlinkage int vprintk(const char *fmt, va_list args) * Use the main logbuf even in NMI. But avoid calling console * drivers that might have their own locks. */ - if (this_cpu_read(printk_context) || in_nmi()) { - int len; - - len =3D vprintk_store(0, LOGLEVEL_DEFAULT, NULL, fmt, args); - defer_console_output(); - return len; - } + if (this_cpu_read(printk_context) || in_nmi()) + return vprintk_deferred(fmt, args); =20 /* No obstacles. */ return vprintk_default(fmt, args); --=20 2.30.2 From nobody Sun Feb 8 00:38:59 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 27C71EB64D9 for ; Mon, 10 Jul 2023 13:45:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232984AbjGJNpp (ORCPT ); Mon, 10 Jul 2023 09:45:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50488 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232814AbjGJNpc (ORCPT ); Mon, 10 Jul 2023 09:45:32 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5C220D2 for ; Mon, 10 Jul 2023 06:45:30 -0700 (PDT) From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1688996728; 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=GgzMpaka03nOC0RkiorRFWglOjfyG1gZscYLSfQH6GY=; b=Nsws1/z0h3MmFN9DTdi5BKGmy8Ha6ipy7aXoHrr4QSn0xsLwqM4qlb9UUzgyJfPYIsIygP qnb0FIkhu9c2TKTAiVVgzneEelkd0nIpcQluJ0EcZeucs0cYg1+Hl4XDxpi+1oxpqUc0VK iykqxiU0pyaJ7ieP6MrkME/2Faxm1ySQzJ/jJ0bOFYEVonLsW5Bc03NFE5B0RnkF9ByzOP Lf9Mu7TtnMTk3osRnIfB6/IVbzFCuzS1K9LxaOdT7qEIDJnSFsH8XeicL922g1L+tzis1K 2TrdIVCHAiIkMXaOjiI2UPQZeFzRYCtrTH6juZTfTftlt6aHy8oUiqfhIRf4ag== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1688996728; 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=GgzMpaka03nOC0RkiorRFWglOjfyG1gZscYLSfQH6GY=; b=/gmNMNbLltxNbfZ38zdL2+rsf17Gp0HvlWp6UNIaj6ykfvY8DcV8ih2K3LfuEZMrhnPuP/ enD9fplczXk4oABA== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Greg Kroah-Hartman Subject: [PATCH printk v2 4/5] printk: Add per-console suspended state Date: Mon, 10 Jul 2023 15:51:23 +0206 Message-Id: <20230710134524.25232-5-john.ogness@linutronix.de> In-Reply-To: <20230710134524.25232-1-john.ogness@linutronix.de> References: <20230710134524.25232-1-john.ogness@linutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Currently the global @console_suspended is used to determine if consoles are in a suspended state. Its primary purpose is to allow usage of the console_lock when suspended without causing console printing. It is synchronized by the console_lock. Rather than relying on the console_lock to determine suspended state, make it an official per-console state that is set within console->flags. This allows the state to be queried via SRCU. Remove @console_suspended. Console printing will still be avoided when suspended because console_is_usable() returns false when the new suspended flag is set for that console. Signed-off-by: John Ogness --- include/linux/console.h | 3 ++ kernel/printk/printk.c | 74 ++++++++++++++++++++++++----------------- 2 files changed, 47 insertions(+), 30 deletions(-) diff --git a/include/linux/console.h b/include/linux/console.h index d3195664baa5..7de11c763eb3 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -154,6 +154,8 @@ static inline int con_debug_leave(void) * receiving the printk spam for obvious reasons. * @CON_EXTENDED: The console supports the extended output format of * /dev/kmesg which requires a larger output buffer. + * @CON_SUSPENDED: Indicates if a console is suspended. If true, the + * printing callbacks must not be called. */ enum cons_flags { CON_PRINTBUFFER =3D BIT(0), @@ -163,6 +165,7 @@ enum cons_flags { CON_ANYTIME =3D BIT(4), CON_BRL =3D BIT(5), CON_EXTENDED =3D BIT(6), + CON_SUSPENDED =3D BIT(7), }; =20 /** diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index e7632ed3b6fd..701908d389f4 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -86,7 +86,7 @@ EXPORT_SYMBOL(oops_in_progress); static DEFINE_MUTEX(console_mutex); =20 /* - * console_sem protects updates to console->seq and console_suspended, + * console_sem protects updates to console->seq * and also provides serialization for console printing. */ static DEFINE_SEMAPHORE(console_sem); @@ -359,7 +359,7 @@ static bool panic_in_progress(void) * paths in the console code where we end up in places I want * locked without the console semaphore held). */ -static int console_locked, console_suspended; +static int console_locked; =20 /* * Array of consoles built from command line options (console=3D) @@ -2549,22 +2549,46 @@ MODULE_PARM_DESC(console_no_auto_verbose, "Disable = console loglevel raise to hig */ void suspend_console(void) { + struct console *con; + if (!console_suspend_enabled) return; pr_info("Suspending console(s) (use no_console_suspend to debug)\n"); pr_flush(1000, true); - console_lock(); - console_suspended =3D 1; - up_console_sem(); + + console_list_lock(); + for_each_console(con) + console_srcu_write_flags(con, con->flags | CON_SUSPENDED); + console_list_unlock(); + + /* + * Ensure that all SRCU list walks have completed. All printing + * contexts must be able to see that they are suspended so that it + * is guaranteed that all printing has stopped when this function + * completes. + */ + synchronize_srcu(&console_srcu); } =20 void resume_console(void) { + struct console *con; + if (!console_suspend_enabled) return; - down_console_sem(); - console_suspended =3D 0; - console_unlock(); + + console_list_lock(); + for_each_console(con) + console_srcu_write_flags(con, con->flags & ~CON_SUSPENDED); + console_list_unlock(); + + /* + * Ensure that all SRCU list walks have completed. All printing + * contexts must be able to see they are no longer suspended so + * that they are guaranteed to wake up and resume printing. + */ + synchronize_srcu(&console_srcu); + pr_flush(1000, true); } =20 @@ -2623,8 +2647,6 @@ void console_lock(void) msleep(1000); =20 down_console_sem(); - if (console_suspended) - return; console_locked =3D 1; console_may_schedule =3D 1; } @@ -2645,10 +2667,6 @@ int console_trylock(void) return 0; if (down_trylock_console_sem()) return 0; - if (console_suspended) { - up_console_sem(); - return 0; - } console_locked =3D 1; console_may_schedule =3D 0; return 1; @@ -2674,6 +2692,9 @@ static inline bool console_is_usable(struct console *= con) if (!(flags & CON_ENABLED)) return false; =20 + if ((flags & CON_SUSPENDED)) + return false; + if (!con->write) return false; =20 @@ -2992,11 +3013,6 @@ void console_unlock(void) bool flushed; u64 next_seq; =20 - if (console_suspended) { - up_console_sem(); - return; - } - /* * Console drivers are called with interrupts disabled, so * @console_may_schedule should be cleared before; however, we may @@ -3702,8 +3718,7 @@ static bool __pr_flush(struct console *con, int timeo= ut_ms, bool reset_on_progre =20 /* * Hold the console_lock to guarantee safe access to - * console->seq and to prevent changes to @console_suspended - * until all consoles have been processed. + * console->seq. */ console_lock(); =20 @@ -3711,6 +3726,11 @@ static bool __pr_flush(struct console *con, int time= out_ms, bool reset_on_progre for_each_console_srcu(c) { if (con && con !=3D c) continue; + /* + * If consoles are not usable, it cannot be expected + * that they make forward progress, so only increment + * @diff for usable consoles. + */ if (!console_is_usable(c)) continue; printk_seq =3D c->seq; @@ -3719,18 +3739,12 @@ static bool __pr_flush(struct console *con, int tim= eout_ms, bool reset_on_progre } console_srcu_read_unlock(cookie); =20 - /* - * If consoles are suspended, it cannot be expected that they - * make forward progress, so timeout immediately. @diff is - * still used to return a valid flush status. - */ - if (console_suspended) - remaining =3D 0; - else if (diff !=3D last_diff && reset_on_progress) + if (diff !=3D last_diff && reset_on_progress) remaining =3D timeout_ms; =20 console_unlock(); =20 + /* Note: @diff is 0 if there are no usable consoles. */ if (diff =3D=3D 0 || remaining =3D=3D 0) break; =20 @@ -3764,7 +3778,7 @@ static bool __pr_flush(struct console *con, int timeo= ut_ms, bool reset_on_progre * printer has been seen to make some forward progress. * * Context: Process context. May sleep while acquiring console lock. - * Return: true if all enabled printers are caught up. + * Return: true if all usable printers are caught up. */ static bool pr_flush(int timeout_ms, bool reset_on_progress) { --=20 2.30.2 From nobody Sun Feb 8 00:38:59 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EAC0AEB64DA for ; Mon, 10 Jul 2023 13:45:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233089AbjGJNpr (ORCPT ); Mon, 10 Jul 2023 09:45:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50560 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233003AbjGJNpf (ORCPT ); Mon, 10 Jul 2023 09:45:35 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6710B11B for ; Mon, 10 Jul 2023 06:45:32 -0700 (PDT) From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1688996728; 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=2mOd9Z/Y7bd7pNGaxo//Z18/44l8G9zcu4FfGzkB3p4=; b=XS44BxOgMF+ntJ4i3SNvH+Xz4wYQeLdVjA9CMnPz4O56If1F5PDyBEoKsE+abaGraJ5NbP d+bf/knkAxY4xfhZbvcYUJ481mkTg0gzYped90BDsXO9J7OlyZCtcZ1hVe6X/P++hqIabm B1FaDt3A1UqFowdj00k/SyRhMuk5KLfSC/sLUoiIZ0yIVYus9SWAbaaHDwa3Y7vrpKrnak lBWpq2utIO/k+FPY2zLsBgoKf1jFo39flgPqYbjiJ2RK74aLWcGFlMBhjNyGDCBLsfIOd3 InX/xK5ZgtheFn5D4MM19iebg1LRKKz9VAToAFcLkmGNUsPsQTesvcrbuMpBgw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1688996728; 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=2mOd9Z/Y7bd7pNGaxo//Z18/44l8G9zcu4FfGzkB3p4=; b=SMgsQ96fW5dYutuP4iuvwQR9qSF+1IhBHPkLwxDrfLAyP/GKrGQvk9Af5UfpmjtW/U7aOv 63AnFfL8kKXxPVBg== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v2 5/5] printk: Rename abandon_console_lock_in_panic() to other_cpu_in_panic() Date: Mon, 10 Jul 2023 15:51:24 +0206 Message-Id: <20230710134524.25232-6-john.ogness@linutronix.de> In-Reply-To: <20230710134524.25232-1-john.ogness@linutronix.de> References: <20230710134524.25232-1-john.ogness@linutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Currently abandon_console_lock_in_panic() is only used to determine if the current CPU should immediately release the console lock because another CPU is in panic. However, later this function will be used by the CPU to immediately release other resources in this situation. Rename the function to other_cpu_in_panic(), which is a better description and does not assume it is related to the console lock. Signed-off-by: John Ogness --- kernel/printk/internal.h | 2 ++ kernel/printk/printk.c | 15 ++++++++------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h index 2a17704136f1..7d4979d5c3ce 100644 --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h @@ -103,3 +103,5 @@ struct printk_message { u64 seq; unsigned long dropped; }; + +bool other_cpu_in_panic(void); diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 701908d389f4..529671aaec2d 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -2612,11 +2612,12 @@ static int console_cpu_notify(unsigned int cpu) } =20 /* - * Return true when this CPU should unlock console_sem without pushing all - * messages to the console. This reduces the chance that the console is - * locked when the panic CPU tries to use it. + * Return true if a panic is in progress on a remote CPU. + * + * On true, the local CPU should immediately release any printing resources + * that may be needed by the panic CPU. */ -static bool abandon_console_lock_in_panic(void) +bool other_cpu_in_panic(void) { if (!panic_in_progress()) return false; @@ -2643,7 +2644,7 @@ void console_lock(void) might_sleep(); =20 /* On panic, the console_lock must be left to the panic cpu. */ - while (abandon_console_lock_in_panic()) + while (other_cpu_in_panic()) msleep(1000); =20 down_console_sem(); @@ -2663,7 +2664,7 @@ EXPORT_SYMBOL(console_lock); int console_trylock(void) { /* On panic, the console_lock must be left to the panic cpu. */ - if (abandon_console_lock_in_panic()) + if (other_cpu_in_panic()) return 0; if (down_trylock_console_sem()) return 0; @@ -2978,7 +2979,7 @@ static bool console_flush_all(bool do_cond_resched, u= 64 *next_seq, bool *handove any_progress =3D true; =20 /* Allow panic_cpu to take over the consoles safely. */ - if (abandon_console_lock_in_panic()) + if (other_cpu_in_panic()) goto abandon; =20 if (do_cond_resched) --=20 2.30.2