From nobody Fri Feb 13 13:25:47 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 C602C208D1 for ; Mon, 27 May 2024 06:38:18 +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=1716791900; cv=none; b=PcOjPWHIckVyCpQkdkqe8SEKTxPAw7k2FpBLIWwTnEN7gHBbvXlizjeogf0Gau85F91X5+3EjGGkVzoTXSjaX3PPzMv9pZ7S51cHXD+SW9mlR9HTtJUZhjQ2uFGPvh/yDuyVidTg0oPET7IpiBte3oXx5yPELNhDB04rqGoQiTs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716791900; c=relaxed/simple; bh=+dn/emmEEkcbSG39cIwrkA2wVajPNCrfmui1Y4Bjb98=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=BJ6Fa51zR2Bpf/HATl7WIT3BWqF5YT5FVydlMKi/FbmQcpHmhJdDA0BORgrwkFqkPTp5x+N+C2hACyNEgyTMDlifrwJcwdURTh+u4kol11Fp1RtrGl8v+TRcJZjVu2pGC452g0DNfr3P4OG1I2Dk2wPN05bDEDWhvfHCHrR+s88= 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=AoNGwTjf; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=Q8opQKl9; 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="AoNGwTjf"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="Q8opQKl9" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1716791896; 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=6ivuBM37dQqLptpOvVQ5pDKTeLxrWvfxf7hXSdzp6yc=; b=AoNGwTjfxYrNKExIOJhnh8w80Pp6zrVg/HR1fZKPmXjcSGGu+skf9UJ/sQaxjYnkofAm/z pIledchn374Bqei75B9bG0eMVSKbfo085gEehJEZxnBl3oQ+pB/51N5qjnN5bCEuk7Esgu TX+z9bADX8/A+5eASDPZjZ109kkfsF9PX6IACZkCAe6yMObkJP5p4S8y2kYPvVSaxrGYOW xhj7bg1T0x6+eZhuALV5PbkQ/0/ZttAxKkvMQOwBeqjXtJsjcf19w5WrwwxSCmKrtPGScr iq4wNvjmMv4o+qLBBHSL0QQkzcWvjwM34haaNs9GuE6HMBEByHeh4i09cIzjRw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1716791896; 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=6ivuBM37dQqLptpOvVQ5pDKTeLxrWvfxf7hXSdzp6yc=; b=Q8opQKl96KesAmk8O7lXPZlE+Nen47I57u/aKpdAoSqq7eUSbNEjZerbZkeSM4uXInJ966 dU1g4noQMaeJPcCw== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, "Paul E. McKenney" , Miguel Ojeda Subject: [PATCH printk v6 01/30] printk: Add notation to console_srcu locking Date: Mon, 27 May 2024 08:43:20 +0206 Message-Id: <20240527063749.391035-2-john.ogness@linutronix.de> In-Reply-To: <20240527063749.391035-1-john.ogness@linutronix.de> References: <20240527063749.391035-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" kernel/printk/printk.c:284:5: sparse: sparse: context imbalance in 'console_srcu_read_lock' - wrong count at exit include/linux/srcu.h:301:9: sparse: sparse: context imbalance in 'console_srcu_read_unlock' - unexpected unlock Fixes: 6c4afa79147e ("printk: Prepare for SRCU console list protection") Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- kernel/printk/printk.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 8de6a46a056c..6efb629fd976 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -282,6 +282,7 @@ EXPORT_SYMBOL(console_list_unlock); * Return: A cookie to pass to console_srcu_read_unlock(). */ int console_srcu_read_lock(void) + __acquires(&console_srcu) { return srcu_read_lock_nmisafe(&console_srcu); } @@ -295,6 +296,7 @@ EXPORT_SYMBOL(console_srcu_read_lock); * Counterpart to console_srcu_read_lock() */ void console_srcu_read_unlock(int cookie) + __releases(&console_srcu) { srcu_read_unlock_nmisafe(&console_srcu, cookie); } --=20 2.39.2 From nobody Fri Feb 13 13:25:47 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 C5FF12032A for ; Mon, 27 May 2024 06:38:18 +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=1716791900; cv=none; b=BM8rlMm72zARf1V/lgi63YlgJC95AEFHUASGdCFAljPQW4tHl/FHHIzZYXh2MDcNDRmZEbVVBbKwtEux/3gyATzOu/0vko/s6fp+uHAkyoa9rpW09NxgHloCkxrc2JS8YLR6HlbReaNjxpIr7RAzkitSMjl2Z/c/i03Y0bpyQ3s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716791900; c=relaxed/simple; bh=uJo1oELvyDQOhiRu2SO/n1grPBTW50wUxfvcqcbXfEE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=h9smRKgxfMwAIKdUzfHXyEAWr0UpR2Vp37GOBwAfVhnpgFUir85mrV8asM0iUh2eRctMtbjzzUbPGb3b7KWTgLQyFDRNDU6ai2ElBZs05l3ja7HWU75uh/wBe9qvbHCN9DraKIWikWC5c+9zzXYdsS2q83EGx2pJDI/vRANI0VM= 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=qjZCHn5U; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=0KYfIqMw; 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="qjZCHn5U"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="0KYfIqMw" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1716791897; 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=vvvXcgZvXxemT9kjJC+HVcrx0f7yfYMwgbRbPkHz9+k=; b=qjZCHn5U7M1e/aS5MXcWPWaLga2DddaMPm5v2wAL53N2CSM0NHGOc8ptV/MstuzjR3q1MV 2EPpHBIKbHgN3DVAQ5dIPT1IQzD289wV15dHHfKh1bM19GmTzYFRZOVdVwnTGw/wZb0F4w u0Mu2qUlHMEzQyh7BxtsNc4k1UG3Em/I5y4fKzh9m8tMnLtWnerbyWmX5Vfe3CJihIU+nS XGI99yVXYN9L417Edk3Peq63BjzNEBSY35uvDR1o7OZs7WSC+P0JcUMT4O+sPoGexaBgTS CEkQ8r+PgjQQO8dfDvIaW1X8Q0JEnj0QJPKrTvkYbx9eKvvCeX2SJ0DnOTsRsQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1716791897; 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=vvvXcgZvXxemT9kjJC+HVcrx0f7yfYMwgbRbPkHz9+k=; b=0KYfIqMwqM1NEMGyZWAG/39WznOWARAFCcBbQper6Q+xOgOXXOlMPy882iwk3TYtbf5m4/ Oz1GhITWHsjINgCQ== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v6 02/30] printk: Properly deal with nbcon consoles on seq init Date: Mon, 27 May 2024 08:43:21 +0206 Message-Id: <20240527063749.391035-3-john.ogness@linutronix.de> In-Reply-To: <20240527063749.391035-1-john.ogness@linutronix.de> References: <20240527063749.391035-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: Petr Mladek If a non-boot console is registering and boot consoles exist, the consoles are flushed before being unregistered. This allows the non-boot console to continue where the boot console left off. If for whatever reason flushing fails, the lowest seq found from any of the enabled boot consoles is used. Until now con->seq was checked. However, if it is an nbcon boot console, the function nbcon_seq_read() must be used to read seq because con->seq is not updated for nbcon consoles. Check if it is an nbcon boot console and if so call nbcon_seq_read() to read seq. Also, avoid usage of con->seq as temporary storage of the starting record. Instead, rename console_init_seq() to get_init_console_seq() and just return the value. For nbcon consoles set the sequence via nbcon_init(), for legacy consoles set con->seq. The cleaned design should make sure that the value stays and is set before the printing kthread is created. Signed-off-by: Petr Mladek Reviewed-by: John Ogness --- kernel/printk/internal.h | 4 ++-- kernel/printk/nbcon.c | 10 +++------- kernel/printk/printk.c | 41 ++++++++++++++++++++++++++++------------ 3 files changed, 34 insertions(+), 21 deletions(-) diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h index 6c2afee5ef62..739b82adc383 100644 --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h @@ -75,7 +75,7 @@ u16 printk_parse_prefix(const char *text, int *level, u64 nbcon_seq_read(struct console *con); void nbcon_seq_force(struct console *con, u64 seq); bool nbcon_alloc(struct console *con); -void nbcon_init(struct console *con); +void nbcon_init(struct console *con, u64 init_seq); void nbcon_free(struct console *con); =20 #else @@ -96,7 +96,7 @@ static inline bool printk_percpu_data_ready(void) { retur= n false; } static inline u64 nbcon_seq_read(struct console *con) { return 0; } static inline void nbcon_seq_force(struct console *con, u64 seq) { } static inline bool nbcon_alloc(struct console *con) { return false; } -static inline void nbcon_init(struct console *con) { } +static inline void nbcon_init(struct console *con, u64 init_seq) { } static inline void nbcon_free(struct console *con) { } =20 #endif /* CONFIG_PRINTK */ diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c index c8093bcc01fe..de260531b0da 100644 --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c @@ -172,9 +172,6 @@ void nbcon_seq_force(struct console *con, u64 seq) u64 valid_seq =3D max_t(u64, seq, prb_first_valid_seq(prb)); =20 atomic_long_set(&ACCESS_PRIVATE(con, nbcon_seq), __u64seq_to_ulseq(valid_= seq)); - - /* Clear con->seq since nbcon consoles use con->nbcon_seq instead. */ - con->seq =3D 0; } =20 /** @@ -961,20 +958,19 @@ bool nbcon_alloc(struct console *con) /** * nbcon_init - Initialize the nbcon console specific data * @con: Console to initialize + * @init_seq: Sequence number of the first record to be emitted * * nbcon_alloc() *must* be called and succeed before this function * is called. - * - * This function expects that the legacy @con->seq has been set. */ -void nbcon_init(struct console *con) +void nbcon_init(struct console *con, u64 init_seq) { struct nbcon_state state =3D { }; =20 /* nbcon_alloc() must have been called and successful! */ BUG_ON(!con->pbufs); =20 - nbcon_seq_force(con, con->seq); + nbcon_seq_force(con, init_seq); nbcon_state_set(con, &state); } =20 diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 6efb629fd976..4480ad2f198e 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -3348,19 +3348,21 @@ static void try_enable_default_console(struct conso= le *newcon) newcon->flags |=3D CON_CONSDEV; } =20 -static void console_init_seq(struct console *newcon, bool bootcon_register= ed) +/* Return the starting sequence number for a newly registered console. */ +static u64 get_init_console_seq(struct console *newcon, bool bootcon_regis= tered) { struct console *con; bool handover; + u64 init_seq; =20 if (newcon->flags & (CON_PRINTBUFFER | CON_BOOT)) { /* Get a consistent copy of @syslog_seq. */ mutex_lock(&syslog_lock); - newcon->seq =3D syslog_seq; + init_seq =3D syslog_seq; mutex_unlock(&syslog_lock); } else { /* Begin with next message added to ringbuffer. */ - newcon->seq =3D prb_next_seq(prb); + init_seq =3D prb_next_seq(prb); =20 /* * If any enabled boot consoles are due to be unregistered @@ -3381,7 +3383,7 @@ static void console_init_seq(struct console *newcon, = bool bootcon_registered) * Flush all consoles and set the console to start at * the next unprinted sequence number. */ - if (!console_flush_all(true, &newcon->seq, &handover)) { + if (!console_flush_all(true, &init_seq, &handover)) { /* * Flushing failed. Just choose the lowest * sequence of the enabled boot consoles. @@ -3394,19 +3396,30 @@ static void console_init_seq(struct console *newcon= , bool bootcon_registered) if (handover) console_lock(); =20 - newcon->seq =3D prb_next_seq(prb); + init_seq =3D prb_next_seq(prb); for_each_console(con) { - if ((con->flags & CON_BOOT) && - (con->flags & CON_ENABLED) && - con->seq < newcon->seq) { - newcon->seq =3D con->seq; + u64 seq; + + if (!(con->flags & CON_BOOT) || + !(con->flags & CON_ENABLED)) { + continue; } + + if (con->flags & CON_NBCON) + seq =3D nbcon_seq_read(con); + else + seq =3D con->seq; + + if (seq < init_seq) + init_seq =3D seq; } } =20 console_unlock(); } } + + return init_seq; } =20 #define console_first() \ @@ -3438,6 +3451,7 @@ void register_console(struct console *newcon) struct console *con; bool bootcon_registered =3D false; bool realcon_registered =3D false; + u64 init_seq; int err; =20 console_list_lock(); @@ -3515,10 +3529,13 @@ void register_console(struct console *newcon) } =20 newcon->dropped =3D 0; - console_init_seq(newcon, bootcon_registered); + init_seq =3D get_init_console_seq(newcon, bootcon_registered); =20 - if (newcon->flags & CON_NBCON) - nbcon_init(newcon); + if (newcon->flags & CON_NBCON) { + nbcon_init(newcon, init_seq); + } else { + newcon->seq =3D init_seq; + } =20 /* * Put this console in the list - keep the --=20 2.39.2 From nobody Fri Feb 13 13:25:47 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 96F55210E9 for ; Mon, 27 May 2024 06:38:19 +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=1716791901; cv=none; b=oWACucCgX+WOPJQcwlrU7EPjBE6mVAQY51Cb9zrnyFWKiePZL+6+WkMOGrM/rq+nl1EvHunOh4BpvrySNVEjdDnTEqnZCp8mbltLX08NGe0Dti2mnFrW0DQOXOeIhhGe1LymB65llDzV1T0oe7N2SgPnkEHKyeTu3c9pXV9OI78= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716791901; c=relaxed/simple; bh=y85BCsAtj/oIZY53Aq9gsvAF7SkfMiwPpUsNnn9BKuo=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=u1Um8Dm1Y3rkjF1fryst1NRvErPx6ze1EZAgAhCEpi6lqhXetY/8KOQLgDkUVBa9KEI9t09GFNccJWFVhKeGuH2EnSjWUR3jiLaCS5FiSrKVLSI24SC+QGICJYxEG4tu7DqD+5upoUxN4ZJCiU8+nY/d8eASL6wVCWm1ImHKFCM= 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=dWOUjRmo; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=S1RhTRWs; 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="dWOUjRmo"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="S1RhTRWs" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1716791897; 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=FGxVNv6QbVc1S9vlUzY53XnVo+kA+8x3wI8r9c33MRA=; b=dWOUjRmoFz0vqKOuNqU4vTCqMqqFeIft1NSjqP9XbcC7r6JJL6VTpHVvMZoyKU0E0eeTs6 jSMptwZCizR/sF6WzJEVHkS7EYsm+rXA3pbMYaH88/eO9/GhGKP2lAZVcdJsYHLXFCOdm7 4lnLEPGTQGNFrDndjTJQu1PWoZEBnnia1WQ4pZJHsH8tNpdedpQ6r+gGmouD3wYJlQWgvo +DaGnZ+hJ7uzy61LL46Q1HqpGA65ZWtJsS9V1YYtmi4cBrU/WAOOUJFpL9LtfPl5L6Zxrs D75qU36AqoFawOhcDwXPPR9Zcjp/OFzM/4ygOYzzQ9sANPLiDPrVIGmTxHMEeg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1716791897; 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=FGxVNv6QbVc1S9vlUzY53XnVo+kA+8x3wI8r9c33MRA=; b=S1RhTRWsxV+VMOG3+pqEzwlx8BzT+wsruKwrYJxue90DfQ8LKM01V+MkpXnvu4D52bkHN5 zqmLS73z95mntHCA== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Greg Kroah-Hartman Subject: [PATCH printk v6 03/30] printk: nbcon: Remove return value for write_atomic() Date: Mon, 27 May 2024 08:43:22 +0206 Message-Id: <20240527063749.391035-4-john.ogness@linutronix.de> In-Reply-To: <20240527063749.391035-1-john.ogness@linutronix.de> References: <20240527063749.391035-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 return value of write_atomic() does not provide any useful information. On the contrary, it makes things more complicated for the caller to appropriately deal with the information. Change write_atomic() to not have a return value. If the message did not get printed due to loss of ownership, the caller will notice this on its own. If ownership was not lost, it will be assumed that the driver successfully printed the message and the sequence number for that console will be incremented. Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- include/linux/console.h | 2 +- kernel/printk/nbcon.c | 15 +++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/include/linux/console.h b/include/linux/console.h index 779d388af8a0..54b98e4f0544 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -327,7 +327,7 @@ struct console { struct hlist_node node; =20 /* nbcon console specific members */ - bool (*write_atomic)(struct console *con, + void (*write_atomic)(struct console *con, struct nbcon_write_context *wctxt); atomic_t __private nbcon_state; atomic_long_t __private nbcon_seq; diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c index de260531b0da..dd7c3180b335 100644 --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c @@ -849,7 +849,6 @@ static bool nbcon_emit_next_record(struct nbcon_write_c= ontext *wctxt) unsigned long con_dropped; struct nbcon_state cur; unsigned long dropped; - bool done; =20 /* * The printk buffers are filled within an unsafe section. This @@ -889,16 +888,16 @@ static bool nbcon_emit_next_record(struct nbcon_write= _context *wctxt) wctxt->unsafe_takeover =3D cur.unsafe_takeover; =20 if (con->write_atomic) { - done =3D con->write_atomic(con, wctxt); + con->write_atomic(con, wctxt); } else { - nbcon_context_release(ctxt); + /* + * This function should never be called for legacy consoles. + * Handle it as if ownership was lost and try to continue. + */ WARN_ON_ONCE(1); - done =3D false; - } - - /* If not done, the emit was aborted. */ - if (!done) + nbcon_context_release(ctxt); return false; + } =20 /* * Since any dropped message was successfully output, reset the --=20 2.39.2 From nobody Fri Feb 13 13:25:47 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 948B620DC5 for ; Mon, 27 May 2024 06:38:19 +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=1716791901; cv=none; b=jJFLUIgm8tvYX0PdEEfOMCzJllYTrqlaHZ+hbpAzvJIsZZljly8mgRFlP0daBT+hC5K/O/4VQkCaBIWuDyRKc4o+RZirlFcbatdt3zxHxMdkJjbTqQnp5NpYexjDoFS1Tr1qZjVOEASWCSJu7U8TZ7c0xUNZK681DEyCsbbdv3o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716791901; c=relaxed/simple; bh=F5yMd/Q52Xd1F+9PcUxxTx8TRVI/tWIKRAO76Ya7FwA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=bztvnmqSxNSpobZoxdjk7XTbSXewT/GQ+PxVQ+AE7OW+IEQwvydtJiWordbcSYrYk3kcUL54yF6avjkJzfkHIHu+dSicXBpMJQ83WSDT9CerpSVebD36nZ5o5vq3zEdGByOH6S1Px3iCIKgv3I4VrDblfVSCwZg62t+BPb7Sp6w= 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=fnA+IPe/; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=vr52uL51; 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="fnA+IPe/"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="vr52uL51" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1716791898; 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=VsgKp/Om0/JiwS4Uevm5ldbUKWaIwX/fMexuAWRWLGk=; b=fnA+IPe/lpYa287E7ZsW7l10DvrTTXSfg+TWp7ojrCR2athlPwGKd2hzt1Xhk/WzQ3VoMo Ll15ZgMmOmDjPC9RTAm/4quZCq2T9nB4hmnrVqyn4mf129auIcrCktr7+KawmSkJfQZ6kO KnDT1embVlmIvGt1i0hPAW1dFczHV5dX2NqcUa2FhpwmYDun678uXAD68iuLrDauUhR605 BMAQV0aJYrpfGuho/eVvdVq2oRh9C1GSlb5CgWxfDyGKapPAs434Fg+rHSEJ/jlnwn5YQQ lYINC5XSrQSUqxGw9GS4WjbJ70CTTcQPb34q4OLIbAq5/ZLNPuhGnw9bWdGxaQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1716791898; 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=VsgKp/Om0/JiwS4Uevm5ldbUKWaIwX/fMexuAWRWLGk=; b=vr52uL51GA4DNZfZpMUSY6Qb/GQiQ8FL9v0Qat5w1oWY6pje7KAy/A8hEeMi+6XgwUutes aRbddOa3hXL3XRAA== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Sebastian Andrzej Siewior Subject: [PATCH printk v6 04/30] printk: Check printk_deferred_enter()/_exit() usage Date: Mon, 27 May 2024 08:43:23 +0206 Message-Id: <20240527063749.391035-5-john.ogness@linutronix.de> In-Reply-To: <20240527063749.391035-1-john.ogness@linutronix.de> References: <20240527063749.391035-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: Sebastian Andrzej Siewior Add validation that printk_deferred_enter()/_exit() are called in non-migration contexts. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- include/linux/printk.h | 9 +++++---- kernel/printk/internal.h | 3 +++ kernel/printk/printk_safe.c | 12 ++++++++++++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/include/linux/printk.h b/include/linux/printk.h index dbbd202b1cb3..6e1f055afef6 100644 --- a/include/linux/printk.h +++ b/include/linux/printk.h @@ -157,15 +157,16 @@ int _printk(const char *fmt, ...); */ __printf(1, 2) __cold int _printk_deferred(const char *fmt, ...); =20 -extern void __printk_safe_enter(void); -extern void __printk_safe_exit(void); +extern void __printk_deferred_enter(void); +extern void __printk_deferred_exit(void); + /* * The printk_deferred_enter/exit macros are available only as a hack for * some code paths that need to defer all printk console printing. Interru= pts * must be disabled for the deferred duration. */ -#define printk_deferred_enter __printk_safe_enter -#define printk_deferred_exit __printk_safe_exit +#define printk_deferred_enter() __printk_deferred_enter() +#define printk_deferred_exit() __printk_deferred_exit() =20 /* * Please don't use printk_ratelimit(), because it shares ratelimiting sta= te diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h index 739b82adc383..831f95f26d48 100644 --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h @@ -53,6 +53,9 @@ int vprintk_store(int facility, int level, __printf(1, 0) int vprintk_default(const char *fmt, va_list args); __printf(1, 0) int vprintk_deferred(const char *fmt, va_list args); =20 +void __printk_safe_enter(void); +void __printk_safe_exit(void); + bool printk_percpu_data_ready(void); =20 #define printk_safe_enter_irqsave(flags) \ diff --git a/kernel/printk/printk_safe.c b/kernel/printk/printk_safe.c index 6d10927a07d8..4421ccac3113 100644 --- a/kernel/printk/printk_safe.c +++ b/kernel/printk/printk_safe.c @@ -26,6 +26,18 @@ void __printk_safe_exit(void) this_cpu_dec(printk_context); } =20 +void __printk_deferred_enter(void) +{ + cant_migrate(); + __printk_safe_enter(); +} + +void __printk_deferred_exit(void) +{ + cant_migrate(); + __printk_safe_exit(); +} + asmlinkage int vprintk(const char *fmt, va_list args) { #ifdef CONFIG_KGDB_KDB --=20 2.39.2 From nobody Fri Feb 13 13:25:47 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 E69001C280 for ; Mon, 27 May 2024 06:38:21 +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=1716791903; cv=none; b=VJO4KZg6AgWthaTs1WDM3TAd+cUcJ0afrA+Wdw8/tddwpfajX3qZ1ft5uHJeX2vn5Pv1UDK+QRTGY3cxPOyDJFWMIlJ2ptc/PgQOlL7br/zoX5fQaqbIWblQKW7wWLgE/Z5k1fWg1bD78lftPeKPuVvVJPTNpZxEok9HDijI/GI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716791903; c=relaxed/simple; bh=2oQpWTGgHoIvmlUI0T2VUPsPGRoIQcWGzo9lRoqvLO0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=XKsOWaRfJNQ0psrPlpDU2j+gVkZS3H0QaKpbpGEvuUUpn3N0er0FV64IzlTViwaQN/kqQyZCynQfnHLVv5+K6/HyNECywElCAc6kT8oFEZjYwcT6m8x1pcxAFyl/kgf5JjgeXVc2xwgX9OAu2tnx7dib4TtDbsDWN3NnBF8eAwc= 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=CXInjNls; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=2jDLPap9; 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="CXInjNls"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="2jDLPap9" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1716791898; 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=faZjTsv+SGR99qiNy2FGhpUimYqF+o8TpUza4h+et4E=; b=CXInjNlstcc74giVMtUIAFkGOIr/rwb12FGVEPVkah0V5U0zzsYR1ug5cwCn5aV/8abLKR C8NGw9PrR1DQrpipmy1yPaEf8H2qXheQ7cLvqaB4WXdbVIJsJQSktjL1e2ahiLG/35cjYi AM6wa4qOR+pbS1Ba+6PbtQyQGfeRHvNX85VH4YQYzVvRBldw3l2ClErVptR1D7lj4faWik y6IbH6TxHrCvnTQX83fyCbWFer1bt3+p3ehd+1vrlwmQRykYsOXo56/NPY+e3Xg/jHOtL8 WFW3eu0F1BfdDIhf9BspcuhSXNRBNJUmEHjHKm6Qo0lvhVYa0kR5x9G58TH2rA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1716791898; 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=faZjTsv+SGR99qiNy2FGhpUimYqF+o8TpUza4h+et4E=; b=2jDLPap9QvTZ+rVZTHJUOWoWDd6mM4BBmQR69Ykti1UHBGhYs1PCmGdSy12sBpoXEAvpw6 ICMFSFzZ0YDvirCw== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Greg Kroah-Hartman Subject: [PATCH printk v6 05/30] printk: nbcon: Add detailed doc for write_atomic() Date: Mon, 27 May 2024 08:43:24 +0206 Message-Id: <20240527063749.391035-6-john.ogness@linutronix.de> In-Reply-To: <20240527063749.391035-1-john.ogness@linutronix.de> References: <20240527063749.391035-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_atomic() callback has special requirements and is allowed to use special helper functions. Provide detailed documentation of the callback so that a developer has a chance of implementing it correctly. Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- include/linux/console.h | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/include/linux/console.h b/include/linux/console.h index 54b98e4f0544..3291cc340f1a 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -285,7 +285,7 @@ struct nbcon_write_context { /** * struct console - The console descriptor structure * @name: The name of the console driver - * @write: Write callback to output messages (Optional) + * @write: Legacy write callback to output messages (Optional) * @read: Read callback for console input (Optional) * @device: The underlying TTY device driver (Optional) * @unblank: Callback to unblank the console (Optional) @@ -302,7 +302,6 @@ struct nbcon_write_context { * @data: Driver private data * @node: hlist node for the console list * - * @write_atomic: Write callback for atomic context * @nbcon_state: State for nbcon consoles * @nbcon_seq: Sequence number of the next record for nbcon to print * @pbufs: Pointer to nbcon private buffer @@ -327,8 +326,34 @@ struct console { struct hlist_node node; =20 /* nbcon console specific members */ - void (*write_atomic)(struct console *con, - struct nbcon_write_context *wctxt); + + /** + * @write_atomic: + * + * NBCON callback to write out text in any context. + * + * This callback is called with the console already acquired. However, + * a higher priority context is allowed to take it over by default. + * + * The callback must call nbcon_enter_unsafe() and nbcon_exit_unsafe() + * around any code where the takeover is not safe, for example, when + * manipulating the serial port registers. + * + * nbcon_enter_unsafe() will fail if the context has lost the console + * ownership in the meantime. In this case, the callback is no longer + * allowed to go forward. It must back out immediately and carefully. + * The buffer content is also no longer trusted since it no longer + * belongs to the context. + * + * The callback should allow the takeover whenever it is safe. It + * increases the chance to see messages when the system is in trouble. + * + * The callback can be called from any context (including NMI). + * Therefore it must avoid usage of any locking and instead rely + * on the console ownership for synchronization. + */ + void (*write_atomic)(struct console *con, struct nbcon_write_context *wct= xt); + atomic_t __private nbcon_state; atomic_long_t __private nbcon_seq; struct printk_buffers *pbufs; --=20 2.39.2 From nobody Fri Feb 13 13:25:47 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 2E56A2207A for ; Mon, 27 May 2024 06:38:21 +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=1716791904; cv=none; b=ShmFq2hNhFSs0SG6HR8VGoierBJtBaORH7gL1KMKAOF5RQde6R093XbzyTH1BEPIjIkXE5DFnAYfPWxzrSh8GOzUG/wCDOGhHKDljuYiFt1EzHo4MocjTj97sAb29hU/XWtLMEJqCJCWVmF/GV3lIpKLGJjVNetOjW9+WCw0jJU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716791904; c=relaxed/simple; bh=Cp5rG2YqPtZnpO861UnOvSpwJyI1madSjKWclzZ6Pcw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=EcKLU6OerpQ8PcNt9JWkQgVzScn/GmO3r0UTx/Bvnv2XFydp8rkR/TNwQC7Kwl2ouc9O72Xv32DSX7Frh0aQnDHFlVHSH3TirQ2lhZjYKbB2jYg5APWaCToRUooLf4kSzLBnpskxwMTdLpzYubwL01Xt8Q734JV+vjHPk+if5dI= 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=agGKEwd/; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=m/ZUIGyO; 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="agGKEwd/"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="m/ZUIGyO" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1716791898; 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=Wlf6KcDO+RSt0m5hbX6TLMb9vXVt0E3+gB/34zgqmT0=; b=agGKEwd/5fTzX1tubGtH+Jy8oH9yozoGwAv8td9G594TX6uoVFJAr7uczrJsJrdUOMRiqC waK+FscwvHvw2HQ5y1L0CEsIeYWlSiXv4Xa/G29tPO8N8/GQR6XmQ+2j72Wx5pcI+GyHz0 fo+g0DykcgZRqbHW2iN2SyQo9POlo+1CGAdd+3/TzSnrSQHQOyUFdJaLAYhECcaR9BCNwF D40qm+sH8WsmrC/dPgUxSjhgaxjHwIRgAaGciJNw/b/9RsAYjd7148ZYv3GPOdqlB770GF mErv7SAANhT6La5KnazQn3bC+H/NjmFO9HUT6GE3dExLdp9l2yMhN6wdWnIypA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1716791898; 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=Wlf6KcDO+RSt0m5hbX6TLMb9vXVt0E3+gB/34zgqmT0=; b=m/ZUIGyOEL3+DYWkTlxmJaeWLcE2Y/e4gAgBK7pXnEs41qlDYHmlV1v0M/0kPymyeOlGl/ SOPfMt7tfcWGTIBA== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Greg Kroah-Hartman Subject: [PATCH printk v6 06/30] printk: nbcon: Add callbacks to synchronize with driver Date: Mon, 27 May 2024 08:43:25 +0206 Message-Id: <20240527063749.391035-7-john.ogness@linutronix.de> In-Reply-To: <20240527063749.391035-1-john.ogness@linutronix.de> References: <20240527063749.391035-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" Console drivers typically must deal with access to the hardware via user input/output (such as an interactive login shell) and output of kernel messages via printk() calls. To provide the necessary synchronization, usually some driver-specific locking mechanism is used (for example, the port spinlock for uart serial consoles). Until now, usage of this driver-specific locking has been hidden from the printk-subsystem and implemented within the various console callbacks. However, nbcon consoles would need to use it even in the generic code. Add device_lock() and device_unlock() callback which will need to get implemented by nbcon consoles. The callbacks will use whatever synchronization mechanism the driver is using for itself. The minimum requirement is to prevent CPU migration. It would allow a context friendly acquiring of nbcon console ownership in non-emergency and non-panic context. Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- include/linux/console.h | 43 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/include/linux/console.h b/include/linux/console.h index 3291cc340f1a..33a029d976c3 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -354,6 +354,49 @@ struct console { */ void (*write_atomic)(struct console *con, struct nbcon_write_context *wct= xt); =20 + /** + * @device_lock: + * + * NBCON callback to begin synchronization with driver code. + * + * Console drivers typically must deal with access to the hardware + * via user input/output (such as an interactive login shell) and + * output of kernel messages via printk() calls. This callback is + * called by the printk-subsystem whenever it needs to synchronize + * with hardware access by the driver. It should be implemented to + * use whatever synchronization mechanism the driver is using for + * itself (for example, the port lock for uart serial consoles). + * + * The callback is always called from task context. It may use any + * synchronization method required by the driver. + * + * IMPORTANT: The callback MUST disable migration. The console driver + * may be using a synchronization mechanism that already takes + * care of this (such as spinlocks). Otherwise this function must + * explicitly call migrate_disable(). + * + * The flags argument is provided as a convenience to the driver. It + * will be passed again to device_unlock(). It can be ignored if the + * driver does not need it. + */ + void (*device_lock)(struct console *con, unsigned long *flags); + + /** + * @device_unlock: + * + * NBCON callback to finish synchronization with driver code. + * + * It is the counterpart to device_lock(). + * + * This callback is always called from task context. It must + * appropriately re-enable migration (depending on how device_lock() + * disabled migration). + * + * The flags argument is the value of the same variable that was + * passed to device_lock(). + */ + void (*device_unlock)(struct console *con, unsigned long flags); + atomic_t __private nbcon_state; atomic_long_t __private nbcon_seq; struct printk_buffers *pbufs; --=20 2.39.2 From nobody Fri Feb 13 13:25:47 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 00BAF1CF96 for ; Mon, 27 May 2024 06:38:21 +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=1716791905; cv=none; b=kplCDCB5zCvzkYiAoq6YyuKIXDZuZMz9se6e/7/oHHg82vDnyFqVXTB2sgzw+O+BH6wD3YqAnqy8zXP6Gp7XVxUsw2NkTtfBOkrMuqv8jw9LyMolea8zAWfZrY9R0yt8x0jNoYnP54r8duMb5XBRBqnlpuIJc6rG6eLwoFHv5QI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716791905; c=relaxed/simple; bh=9IRHpvinAh1d0SKWvTSQyp/656+eUEtvBM0k7wl+q4g=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=bFpR7mUnFKVeYJ77Ag7Va8LLcaP21Q6LNfnLO5As9GDxOi2LBVtsssL3ng9GLHqjT/W2RpVjROsaddd3+jGzxYb283dc4QWj2IkzzEr/OjdGdrCizozaxHnccwRa3PMpmG1tUiDl+zyanF1OMdNALriUEujpMBWEQZQINzJuews= 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=UVvJlZf1; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=JXD5w1ZA; 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="UVvJlZf1"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="JXD5w1ZA" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1716791899; 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=JYsgzUBKNSoyIJpFAn5k23z+tzPLez2hQ3LL73VvEsw=; b=UVvJlZf1Ix8GJCGVepNmNnQnqR3cqAgUx2uCMG2nxritVkBYYHMEWYCmHl/Y5YyO8koK5M qpR7wHuiuf873zUhpoQwt3T77PlpN8+LUqmP89gEqbB3oqgST/VQMwsRvhA+gPtO06cgeh Hy44BzrEijnpBcVQXHe/5Tp1WO0Oj2Bvti5T7A31+LCjy9mnzYUuVrJbPLA7MSGxpPhGi+ o8oSZ297+aJXF9vIQ3slR6FRsT9cEEoskRhAfeAGneFXyzk2iV/9g8EM4TBaGmT7TE1B1+ 4T+DnEbp2k8CEGr5c2CnyLEjX5QR4gxtnx7eTBimhz5uqXAocIsFwaBvfvrTKw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1716791899; 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=JYsgzUBKNSoyIJpFAn5k23z+tzPLez2hQ3LL73VvEsw=; b=JXD5w1ZAkRnO0p7taARGBF8OaMOl86njRlkDLZIJT2RfWPtAgcvPgxVu6Sv7vJbg4vwX5B vMcwAelSVBxjvsDQ== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v6 07/30] printk: nbcon: Use driver synchronization while (un)registering Date: Mon, 27 May 2024 08:43:26 +0206 Message-Id: <20240527063749.391035-8-john.ogness@linutronix.de> In-Reply-To: <20240527063749.391035-1-john.ogness@linutronix.de> References: <20240527063749.391035-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" Console drivers typically have to deal with access to the hardware via user input/output (such as an interactive login shell) and output of kernel messages via printk() calls. They use some classic driver-specific locking mechanism in most situations. But console->write_atomic() callbacks, used by nbcon consoles, are synchronized only by acquiring the console context. The synchronization via the console context ownership is possible only when the console driver is registered. It is when a particular device driver is connected with a particular console driver. The two synchronization mechanisms must be synchronized between each other. It is tricky because the console context ownership is quite special. It might be taken over by a higher priority context. Also CPU migration must be disabled. The most tricky part is to (dis)connect these two mechanisms during the console (un)registration. Use the driver-specific locking callbacks: device_lock(), device_unlock(). They allow taking the device-specific lock while the device is being (un)registered by the related console driver. For example, these callbacks lock/unlock the port lock for serial port drivers. Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- kernel/printk/printk.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 4480ad2f198e..75f64efaa53c 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -3448,9 +3448,11 @@ static int unregister_console_locked(struct console = *console); */ void register_console(struct console *newcon) { - struct console *con; + bool use_device_lock =3D (newcon->flags & CON_NBCON) && newcon->write_ato= mic; bool bootcon_registered =3D false; bool realcon_registered =3D false; + struct console *con; + unsigned long flags; u64 init_seq; int err; =20 @@ -3537,6 +3539,19 @@ void register_console(struct console *newcon) newcon->seq =3D init_seq; } =20 + /* + * If another context is actively using the hardware of this new + * console, it will not be aware of the nbcon synchronization. This + * is a risk that two contexts could access the hardware + * simultaneously if this new console is used for atomic printing + * and the other context is still using the hardware. + * + * Use the driver synchronization to ensure that the hardware is not + * in use while this new console transitions to being registered. + */ + if (use_device_lock) + newcon->device_lock(newcon, &flags); + /* * Put this console in the list - keep the * preferred driver at the head of the list. @@ -3561,6 +3576,10 @@ void register_console(struct console *newcon) * register_console() completes. */ =20 + /* This new console is now registered. */ + if (use_device_lock) + newcon->device_unlock(newcon, flags); + console_sysfs_notify(); =20 /* @@ -3589,6 +3608,8 @@ EXPORT_SYMBOL(register_console); /* Must be called under console_list_lock(). */ static int unregister_console_locked(struct console *console) { + bool use_device_lock =3D (console->flags & CON_NBCON) && console->write_a= tomic; + unsigned long flags; int res; =20 lockdep_assert_console_list_lock_held(); @@ -3607,8 +3628,18 @@ static int unregister_console_locked(struct console = *console) if (!console_is_registered_locked(console)) return -ENODEV; =20 + /* + * Use the driver synchronization to ensure that the hardware is not + * in use while this console transitions to being unregistered. + */ + if (use_device_lock) + console->device_lock(console, &flags); + hlist_del_init_rcu(&console->node); =20 + if (use_device_lock) + console->device_unlock(console, flags); + /* * * If this isn't the last console and it has CON_CONSDEV set, we --=20 2.39.2 From nobody Fri Feb 13 13:25:47 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 EB0BB1C686; Mon, 27 May 2024 06:38:21 +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=1716791905; cv=none; b=cAfby1CcgxzP3nD4E/B9yqrNSMuQjSPgfxQFhkPYM7hyEIK+vUzaUmOe2sm5lOivfKgfjtsHlr+gWPbhoktctuG2CKLu540dNLbBoh8Nb9DDdXuBhy0MJq24qKf0ORI90kz9t8znh4Btw82VH7G9h6HgTnkeN7um9i1iVPHFu2E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716791905; c=relaxed/simple; bh=AiH8EnN6GRzi8B2qcObkU/HEqg04wntd+nSfmS7tVhM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=lf2IHOinTeNJW7o3QSgHm1xLWAoSZhia96Nl4NQTui93IwRvAVvtFA59e4SHOkf2Uy9syHwB2n2DE2HJRnLj8Vd1LyPKxx6Al/ihTgVQrBzdtSrg5t5QVNobdsIXDZRTRWhNUH7j+AXZ6STEcOzE4o4OLujqm8zkhBq62FON3i0= 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=MWfm1v/S; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=mtJG7MYi; 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="MWfm1v/S"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="mtJG7MYi" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1716791899; 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=TkEmSH+TeCzW4mgc3Qx6oM4UTLT7owCiQ5MwVZZnUf0=; b=MWfm1v/SDq5UBs2uYn8xLpTUBfAUg6ebL8WM55kFJWkV7h2WuzJwfQ6sgmqQnn8fSy1SPK Rm7aGRiSkufQn6TiKr9IzTkSdChmnAFZECXuFb9Dnda+stuzrxGw7JI8pJ84zHxDe6jH5C fM1UShVvGDBI23d3RFshfkf1e936Rx7Lkr9L0C7YdhIcZVZZtOEXo30FYEWgpmBEkd5t0V EVSrWhW9rExqdc5qVmVgY0uEEZskuGTukTSO29YUpeMq3DEU21ItQS8BUROysuEKJ6uqev ddCH6o5QW0AaOPvxoF1xsZPg3uJ/sUKqacDDo8UCnEy6VfqPZ01zlMpOS0fgjQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1716791899; 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=TkEmSH+TeCzW4mgc3Qx6oM4UTLT7owCiQ5MwVZZnUf0=; b=mtJG7MYiy42HnHVpBuzvx+qMo0svogSYJ75Tg/hZgZsaUKanxZKF0fBDT0V/WWRBhJ6b8M GjR5PN9ws9T84yCg== 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 v6 08/30] serial: core: Provide low-level functions to lock port Date: Mon, 27 May 2024 08:43:27 +0206 Message-Id: <20240527063749.391035-9-john.ogness@linutronix.de> In-Reply-To: <20240527063749.391035-1-john.ogness@linutronix.de> References: <20240527063749.391035-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" It will be necessary at times for the uart nbcon console drivers to acquire the port lock directly (without the additional nbcon functionality of the port lock wrappers). These are special cases such as the implementation of the device_lock()/device_unlock() callbacks or for internal port lock wrapper synchronization. Provide low-level variants __uart_port_lock_irqsave() and __uart_port_unlock_irqrestore() for this purpose. Signed-off-by: John Ogness Reviewed-by: Petr Mladek Acked-by: Greg Kroah-Hartman --- include/linux/serial_core.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 55b1f3ba48ac..bb3324d49453 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -588,6 +588,24 @@ struct uart_port { void *private_data; /* generic platform data pointer */ }; =20 +/* + * Only for console->device_lock()/_unlock() callbacks and internal + * port lock wrapper synchronization. + */ +static inline void __uart_port_lock_irqsave(struct uart_port *up, unsigned= long *flags) +{ + spin_lock_irqsave(&up->lock, *flags); +} + +/* + * Only for console->device_lock()/_unlock() callbacks and internal + * port lock wrapper synchronization. + */ +static inline void __uart_port_unlock_irqrestore(struct uart_port *up, uns= igned long flags) +{ + spin_unlock_irqrestore(&up->lock, flags); +} + /** * uart_port_lock - Lock the UART port * @up: Pointer to UART port structure --=20 2.39.2 From nobody Fri Feb 13 13:25:47 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 2E52B200A9; Mon, 27 May 2024 06:38:21 +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=1716791904; cv=none; b=JqTVGaeofWEfsZ4sxiXX2nHX4EbtQaGMGbnLt1gOTRnC4XuBgtImQ1n/G1jnOQI+fT3/q7Sykevfw0qtGZaHLPdQa47id5o0nRvX4pzFVZP5IHjZt+7MVJ6f4HJL0XIODMRDg7Nl0CLJYUeJT5bNW6E+NbWQj2KqEwl9aCA9jbo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716791904; c=relaxed/simple; bh=cFwc6eXZwJgEsJEy8i2WPFC0zBMSmXI8t49qE0YAxa8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=XYBK6Qho6NegaAb33nqifYa4MVyVU78cDfAh6sHCw5Fvt3gQyD9hIIaht4Rxww+HhWk2Jb8YvSaP/gSw8RbSlRjPDcZM53TCYZ2h9GHnLpuu6SBeDALRd88IJVVHmFoY7/ytjN2oOZ6dFEoTA5LWtgKza/jD4YB9aYE8BEikqSc= 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=alK1KWjc; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=NHgWJcuS; 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="alK1KWjc"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="NHgWJcuS" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1716791900; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=zWt1+yEDsP6qOdCR9l91mhS5ulhADY7ilusdjp03eQI=; b=alK1KWjcHbZGtwKO5rEHuvhQN+AFvXZTR2VcpjaRXXmHSJqrk9eX/rhVBhybSQfoqHDuCc 7BALICZJbIv1oXDy33GHvvuDEQ3lzNzd3hxfn3JbzplGji24L+K9tICF43zR0nld85t025 9dCd47lIiU350Crod3RGlZrFhjMMXgMznAb+zFL2JcIBMn0Y3vwKqBY0cuXvyLMkCVRZR/ fvUATcVHV54RAYu2GMSXKn1vivJ+WFU4AVjbn9gvdBLy647Un5fBq91UTkT+bAlUqlflco NzeOJCARYpGP843XGPXlgV4LFlw0fTuYaJ9kpQAlNgElOXeEUrKSMj4UGs1Xzg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1716791900; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=zWt1+yEDsP6qOdCR9l91mhS5ulhADY7ilusdjp03eQI=; b=NHgWJcuS3yBBDume6ZAX5icDc5ue9u6aySYB5XIb+jN5Kcf56ppxj0jzVp2bujVbzXMeTu b3Rwbfht6ZVBVjDg== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Greg Kroah-Hartman , Jiri Slaby , Russell King , Tony Lindgren , Andy Shevchenko , Florian Fainelli , =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= , =?UTF-8?q?Th=C3=A9o=20Lebrun?= , Linus Walleij , =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= , Fabio Estevam , Lino Sanfilippo , Christophe JAILLET , Arnd Bergmann , linux-serial@vger.kernel.org Subject: [PATCH printk v6 09/30] serial: core: Introduce wrapper to set @uart_port->cons Date: Mon, 27 May 2024 08:43:28 +0206 Message-Id: <20240527063749.391035-10-john.ogness@linutronix.de> In-Reply-To: <20240527063749.391035-1-john.ogness@linutronix.de> References: <20240527063749.391035-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-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Introduce uart_port_set_cons() as a wrapper to set @cons of a uart_port. The wrapper sets @cons under the port lock in order to prevent @cons from disappearing while another context is holding the port lock. This is necessary for a follow-up commit relating to the port lock wrappers, which rely on @cons not changing between lock and unlock. Signed-off-by: John Ogness Tested-by: Th=C3=A9o Lebrun # EyeQ5, AMBA-PL011 Acked-by: Greg Kroah-Hartman Reviewed-by: Petr Mladek --- drivers/tty/serial/8250/8250_core.c | 6 +++--- drivers/tty/serial/amba-pl011.c | 2 +- drivers/tty/serial/serial_core.c | 16 ++++++++-------- include/linux/serial_core.h | 17 +++++++++++++++++ 4 files changed, 29 insertions(+), 12 deletions(-) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/= 8250_core.c index b62ad9006780..41d74ee3d95a 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -627,11 +627,11 @@ static int univ8250_console_setup(struct console *co,= char *options) =20 port =3D &serial8250_ports[co->index].port; /* link port to console */ - port->cons =3D co; + uart_port_set_cons(port, co); =20 retval =3D serial8250_console_setup(port, options, false); if (retval !=3D 0) - port->cons =3D NULL; + uart_port_set_cons(port, NULL); return retval; } =20 @@ -689,7 +689,7 @@ static int univ8250_console_match(struct console *co, c= har *name, int idx, continue; =20 co->index =3D i; - port->cons =3D co; + uart_port_set_cons(port, co); return serial8250_console_setup(port, options, true); } =20 diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl01= 1.c index cf2c890a560f..347aacf8400f 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -2496,7 +2496,7 @@ static int pl011_console_match(struct console *co, ch= ar *name, int idx, continue; =20 co->index =3D i; - port->cons =3D co; + uart_port_set_cons(port, co); return pl011_console_setup(co, options); } =20 diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_c= ore.c index d6a58a9e072a..0c13ea6a3afa 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -3145,8 +3145,15 @@ static int serial_core_add_one_port(struct uart_driv= er *drv, struct uart_port *u state->uart_port =3D uport; uport->state =3D state; =20 + /* + * If this port is in use as a console then the spinlock is already + * initialised. + */ + if (!uart_console_registered(uport)) + uart_port_spin_lock_init(uport); + state->pm_state =3D UART_PM_STATE_UNDEFINED; - uport->cons =3D drv->cons; + uart_port_set_cons(uport, drv->cons); uport->minor =3D drv->tty_driver->minor_start + uport->line; uport->name =3D kasprintf(GFP_KERNEL, "%s%d", drv->dev_name, drv->tty_driver->name_base + uport->line); @@ -3155,13 +3162,6 @@ static int serial_core_add_one_port(struct uart_driv= er *drv, struct uart_port *u goto out; } =20 - /* - * If this port is in use as a console then the spinlock is already - * initialised. - */ - if (!uart_console_registered(uport)) - uart_port_spin_lock_init(uport); - if (uport->cons && uport->dev) of_console_check(uport->dev->of_node, uport->cons->name, uport->line); =20 diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index bb3324d49453..038693774f21 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -606,6 +606,23 @@ static inline void __uart_port_unlock_irqrestore(struc= t uart_port *up, unsigned spin_unlock_irqrestore(&up->lock, flags); } =20 +/** + * uart_port_set_cons - Safely set the @cons field for a uart + * @up: The uart port to set + * @con: The new console to set to + * + * This function must be used to set @up->cons. It uses the port lock to + * synchronize with the port lock wrappers in order to ensure that the con= sole + * cannot change or disappear while another context is holding the port lo= ck. + */ +static inline void uart_port_set_cons(struct uart_port *up, struct console= *con) +{ + unsigned long flags; + + __uart_port_lock_irqsave(up, &flags); + up->cons =3D con; + __uart_port_unlock_irqrestore(up, flags); +} /** * uart_port_lock - Lock the UART port * @up: Pointer to UART port structure --=20 2.39.2 From nobody Fri Feb 13 13:25:47 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 38032224D1 for ; Mon, 27 May 2024 06:38:22 +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=1716791903; cv=none; b=E5gwVujxe8byuPT8KWASbF3qb0Z6gZEKJVt3e7ps2z3QVrScZY/UfBReHLOqKnSojrSviS3GdLFiIS4NSMQIqeUbQjR7g0UcnYUSXJlOhjtb2tlM+WbzVxoZNtMFivaS4A8USneXg7ZeP+TCNLzJtTURbqr4/sDWZ/+241I4WIo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716791903; c=relaxed/simple; bh=axuNSOvCefXcmGgJa7oB4htrGdCQVV47smWqzTggUFE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=dYOk6FqmHQQttRMdo24gErITJz5QLqvoEgm5NPG9oBGCV0Uv6SuT9g9LYGz4KpQg+Ay5Y8qmP0bVyvSkvsK4jVkuRX6fLLnDPu4S09wp6WvwQVkJPetiPXxxfUOJ5KMr9GP+q+FpLG51l1BXzlyuaFZCZ5pJEv/LcEPc8k9da8E= 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=sWqQnTrc; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=L2NgUy/X; 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="sWqQnTrc"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="L2NgUy/X" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1716791900; 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=6LjCfsdgyf7GkeZyIQRXWJVLAkjljpAa6X7oN+BZvyM=; b=sWqQnTrceODO+INDu27A0Twd5g9PL6uCSqYw7uIqk7lqjflRUYy8aeZThDHJi8bvok6r1w pxC5kWIcZh9S2fGSRTlD87PdomHuDPTZWjUjRiPuzRJVoXNE/dsjE3ofF58Z2KqY7VoCMK HuPf9klnpD6Pt/4bvYBeRVOA4ZA3E9dV6MMxdZlM82ShSe7Xm7R0Mbe9F2fzb2aMktDoOp UM1Nv+G+7inulNUican3Szs332LZDbsEPGgzVzI/zkBI1v2gY53ftSxC6G2OHjVDCMX1kp 1spA1wHmqSutZQsrtpWsX50uUIUhfg8NAXpAEM73ERIxjDdWwdDbUddk4hHLeA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1716791900; 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=6LjCfsdgyf7GkeZyIQRXWJVLAkjljpAa6X7oN+BZvyM=; b=L2NgUy/XBJuRceM8c2cC4vVv9ZgRuTSnQG1gnLXL93wthMHAzsivf0k7e9T1rAlRIdpwhm 4KvWkuPvufCmlpAg== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Greg Kroah-Hartman Subject: [PATCH printk v6 10/30] console: Improve console_srcu_read_flags() comments Date: Mon, 27 May 2024 08:43:29 +0206 Message-Id: <20240527063749.391035-11-john.ogness@linutronix.de> In-Reply-To: <20240527063749.391035-1-john.ogness@linutronix.de> References: <20240527063749.391035-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" It was not clear when exactly console_srcu_read_flags() must be used vs. directly reading @console->flags. Refactor and clarify that console_srcu_read_flags() is only needed if the console is registered or the caller is in a context where the registration status of the console may change (due to another context). The function requires the caller holds @console_srcu, which will ensure that the caller sees an appropriate @flags value for the registered console and that exit/cleanup routines will not run if the console is in the process of unregistration. Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- include/linux/console.h | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/include/linux/console.h b/include/linux/console.h index 33a029d976c3..aea4f5aa4a45 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -428,28 +428,34 @@ extern void console_list_unlock(void) __releases(cons= ole_mutex); extern struct hlist_head console_list; =20 /** - * console_srcu_read_flags - Locklessly read the console flags + * console_srcu_read_flags - Locklessly read flags of a possibly registered + * console * @con: struct console pointer of console to read flags from * - * This function provides the necessary READ_ONCE() and data_race() - * notation for locklessly reading the console flags. The READ_ONCE() - * in this function matches the WRITE_ONCE() when @flags are modified - * for registered consoles with console_srcu_write_flags(). + * Locklessly reading @con->flags provides a consistent read value because + * there is at most one CPU modifying @con->flags and that CPU is using on= ly + * read-modify-write operations to do so. * - * Only use this function to read console flags when locklessly - * iterating the console list via srcu. + * Requires console_srcu_read_lock to be held, which implies that @con mig= ht + * be a registered console. The purpose of holding console_srcu_read_lock = is + * to guarantee that the console state is valid (CON_SUSPENDED/CON_ENABLED) + * and that no exit/cleanup routines will run if the console is currently + * undergoing unregistration. + * + * If the caller is holding the console_list_lock or it is _certain_ that + * @con is not and will not become registered, the caller may read + * @con->flags directly instead. * * Context: Any context. + * Return: The current value of the @con->flags field. */ static inline short console_srcu_read_flags(const struct console *con) { WARN_ON_ONCE(!console_srcu_read_lock_is_held()); =20 /* - * Locklessly reading console->flags provides a consistent - * read value because there is at most one CPU modifying - * console->flags and that CPU is using only read-modify-write - * operations to do so. + * The READ_ONCE() matches the WRITE_ONCE() when @flags are modified + * for registered consoles with console_srcu_write_flags(). */ return data_race(READ_ONCE(con->flags)); } --=20 2.39.2 From nobody Fri Feb 13 13:25:47 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 94B9025774 for ; Mon, 27 May 2024 06:38:22 +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=1716791904; cv=none; b=iBqmBPNYOq6NWmvLNOMtYIRWUZNaESM55WO9TDp8vNjRTnOpLSKvblpGjn4QaMyEFP1lCPt+alv7Uu9MY2c6uJ+pffLiRhi34VDupkn+UXdrTQf5XWZe01//wADEgQEblAxAk7d57gMa6PaVLq6IME/R6ld9NYgMJMih1GvRdSA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716791904; c=relaxed/simple; bh=zB+R6jhg2BE6ADHCpzR6mMsmJtTlMFnZXzIpx7pfX40=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=JBDcrFB6cEyUgbkBTfnuqGFj7fb0WDJSZM9TQ0OuVslKCntGtPNdoPXpsyDdXOno9i4cJX7SYPvbSm7mEGmfkIn1kFYe7diARQK2PVrpn0ZU8+Go0RPZDTFlP5KquM+u1rDDitXpGOXwZbuVMuuAvYEJxwbKVj8BntmqMsvr5yA= 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=IFXFLCuO; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=n55C7AG/; 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="IFXFLCuO"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="n55C7AG/" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1716791901; 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=GoAnFoEDBtUewczef8goHn9wNNbG58iWoQEY2ToK04k=; b=IFXFLCuO9PvXtfNHNA0n3oP+uHMJIFeVM1fpRWQElecn6BnzcoIBUxI9aHeJilUXnIQ2M8 EusljbidYDwiyd31vZMel0W3MugopB0WMHB19UCTH9ETEVMi4mg60jKagmOv47avuida7e bjAp8V8UHJuO8DhnA7KeLkobS/FcvFyQ/vU2D91Exrp2m1vs+lcSrflGY2GEornKInOvlp AyQepP3dsUmjzTn6p0pjnSStsiBUwdgD7nn5KTXNAaFyw3LapXi/WvsGFKQE5jxIMZ0FHy xuugRHlA3jkDMojqWK7XrfaBr+Hx04qjompiVilcU1ppnmALosqMALJAYzJHAw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1716791901; 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=GoAnFoEDBtUewczef8goHn9wNNbG58iWoQEY2ToK04k=; b=n55C7AG/uJkfQLYGvY709d/WmgZSFNur/U83H1HlprzxNNrOxzO4/Td6va71SCXYVD8GUA ghlwFbKFxaL/emBQ== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Greg Kroah-Hartman Subject: [PATCH printk v6 11/30] nbcon: Add API to acquire context for non-printing operations Date: Mon, 27 May 2024 08:43:30 +0206 Message-Id: <20240527063749.391035-12-john.ogness@linutronix.de> In-Reply-To: <20240527063749.391035-1-john.ogness@linutronix.de> References: <20240527063749.391035-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" Provide functions nbcon_device_try_acquire() and nbcon_device_release() which will try to acquire the nbcon console ownership with NBCON_PRIO_NORMAL and mark it unsafe for handover/takeover. These functions are to be used together with the device-specific locking when performing non-printing activities on the console device. They will allow synchronization against the atomic_write() callback which will be serialized, for higher priority contexts, only by acquiring the console context ownership. Pitfalls: The API requires to be called in a context with migration disabled because it uses per-CPU variables internally. The context is set unsafe for a takeover all the time. It guarantees full serialization against any atomic_write() caller except for the final flush in panic() which might try an unsafe takeover. Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- include/linux/console.h | 2 ++ include/linux/printk.h | 14 +++++++++++ kernel/printk/nbcon.c | 56 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/include/linux/console.h b/include/linux/console.h index aea4f5aa4a45..dd3d4b5d3737 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -304,6 +304,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 * @pbufs: Pointer to nbcon private buffer */ struct console { @@ -399,6 +400,7 @@ struct console { =20 atomic_t __private nbcon_state; atomic_long_t __private nbcon_seq; + struct nbcon_context __private nbcon_device_ctxt; struct printk_buffers *pbufs; }; =20 diff --git a/include/linux/printk.h b/include/linux/printk.h index 6e1f055afef6..31f72df29da5 100644 --- a/include/linux/printk.h +++ b/include/linux/printk.h @@ -9,6 +9,8 @@ #include #include =20 +struct console; + extern const char linux_banner[]; extern const char linux_proc_banner[]; =20 @@ -193,6 +195,8 @@ 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); +extern bool nbcon_device_try_acquire(struct console *con); +extern void nbcon_device_release(struct console *con); #else static inline __printf(1, 0) int vprintk(const char *s, va_list args) @@ -272,6 +276,16 @@ static inline void dump_stack(void) static inline void printk_trigger_flush(void) { } + +static inline bool nbcon_device_try_acquire(struct console *con) +{ + return false; +} + +static inline void nbcon_device_release(struct console *con) +{ +} + #endif =20 bool this_cpu_in_panic(void); diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c index dd7c3180b335..1c03508b90f2 100644 --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c @@ -5,7 +5,9 @@ #include #include #include +#include #include +#include #include "internal.h" /* * Printk console printing implementation for consoles which does not depe= nd @@ -528,6 +530,7 @@ static struct printk_buffers panic_nbcon_pbufs; * nbcon_context_try_acquire - Try to acquire nbcon console * @ctxt: The context of the caller * + * Context: Under @ctxt->con->device_lock() or local_irq_save(). * Return: True if the console was acquired. False otherwise. * * If the caller allowed an unsafe hostile takeover, on success the @@ -535,7 +538,6 @@ static struct printk_buffers panic_nbcon_pbufs; * in an unsafe state. Otherwise, on success the caller may assume * the console is not in an unsafe state. */ -__maybe_unused static bool nbcon_context_try_acquire(struct nbcon_context *ctxt) { unsigned int cpu =3D smp_processor_id(); @@ -989,3 +991,55 @@ void nbcon_free(struct console *con) =20 con->pbufs =3D NULL; } + +/** + * nbcon_device_try_acquire - Try to acquire nbcon console and enter unsafe + * section + * @con: The nbcon console to acquire + * + * Context: Under the locking mechanism implemented in + * @con->device_lock() including disabling migration. + * Return: True if the console was acquired. False otherwise. + * + * Console drivers will usually use their own internal synchronization + * mechasism to synchronize between console printing and non-printing + * activities (such as setting baud rates). However, nbcon console drivers + * supporting atomic consoles may also want to mark unsafe sections when + * performing non-printing activities in order to synchronize against their + * atomic_write() callback. + * + * This function acquires the nbcon console using priority NBCON_PRIO_NORM= AL + * and marks it unsafe for handover/takeover. + */ +bool nbcon_device_try_acquire(struct console *con) +{ + struct nbcon_context *ctxt =3D &ACCESS_PRIVATE(con, nbcon_device_ctxt); + + cant_migrate(); + + memset(ctxt, 0, sizeof(*ctxt)); + ctxt->console =3D con; + ctxt->prio =3D NBCON_PRIO_NORMAL; + + if (!nbcon_context_try_acquire(ctxt)) + return false; + + if (!nbcon_context_enter_unsafe(ctxt)) + return false; + + return true; +} +EXPORT_SYMBOL_GPL(nbcon_device_try_acquire); + +/** + * nbcon_device_release - Exit unsafe section and release the nbcon console + * @con: The nbcon console acquired in nbcon_device_try_acquire() + */ +void nbcon_device_release(struct console *con) +{ + struct nbcon_context *ctxt =3D &ACCESS_PRIVATE(con, nbcon_device_ctxt); + + if (nbcon_context_exit_unsafe(ctxt)) + nbcon_context_release(ctxt); +} +EXPORT_SYMBOL_GPL(nbcon_device_release); --=20 2.39.2 From nobody Fri Feb 13 13:25:47 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 C9B5828379; Mon, 27 May 2024 06:38:22 +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=1716791904; cv=none; b=p6i5SPYZhAQN/+zJA1W+c84ewQYTwWt6+uwOB//YeNcH3wuF/87g4jB4cMQr6qUrdorJyiF7nETwSt+i4Vt7rWmJU4uMBkPYzF6TjtvEOSerivXEPe4dteAvEt6F6epRzlatpHqUpfHGIYTrxNIrTXPP7VINgo/Xlmt5wC0xyVM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716791904; c=relaxed/simple; bh=xfgoJJ7KYGaA0v4WSAop29ufu9YiwR5LBEtcGuCDyLc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=tDje0KQRkJEnmDq8m2nzbJ8CRwrQxqNVJcnW4gkVUbs3WVP9IK4R5cVGW4fln95JeCtOIf7EEw9XeDCZMfdsYtPY8vOSj5q//2BTezdlxV1VzkrzevMZxOMjT0bipo0C9Bm4669rlBTAmTd69/UbXE+elz0F4OalxquCFWf8Q/w= 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=ds8wXT7+; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=dLwu4cib; 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="ds8wXT7+"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="dLwu4cib" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1716791901; 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=vj8sIG4y4mzFTOtfWKSK0xfleOpjXWWwflzt4OFWNas=; b=ds8wXT7+BHCRbh6sXCSzlY+F4nTB+P8TDXEFFTpJf0ghwePsljsa9VpIRWgQPP0Fe9VH0W rDEruO7zFdApsMEX7C+EbFy/6RdZcJv4lONTg+qlK9CH+6EO1o2ifSTNjIeJZujDAmPsQF ZGeinMHcfZferb5P0jlPKWJg2UvAUs2cfUlL3203RnyrK2FLPtMGsepWM2QuMmQ80H6k0B Sl0ZMBhXt+mDhl4pLXKJ7Au1cnBL/h6E9ZU5oTSqwkaDaKpxt9cuUSzPC1ymGavxS2Tr9S rYJ2O1m5glnjAoRQlr7jUDBWikUh9LtHOpsQgMiQey6yIW+ip36pWcOg90kQ2w== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1716791901; 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=vj8sIG4y4mzFTOtfWKSK0xfleOpjXWWwflzt4OFWNas=; b=dLwu4cibfzNTYdijo75FkvCEfkAbFquOBa9+4oPuBtzzhpQU6Ww1jvrN+l66ZAUOhn50M6 cfqhtWFjUZYwd2Cg== 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 v6 12/30] serial: core: Implement processing in port->lock wrapper Date: Mon, 27 May 2024 08:43:31 +0206 Message-Id: <20240527063749.391035-13-john.ogness@linutronix.de> In-Reply-To: <20240527063749.391035-1-john.ogness@linutronix.de> References: <20240527063749.391035-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" Currently the port->lock wrappers uart_port_lock(), uart_port_unlock() (and their variants) only lock/unlock the spin_lock. If the port is an nbcon console, the wrappers must also acquire/release the console and mark the region as unsafe. This allows general port->lock synchronization to be synchronized with the nbcon console ownership. Note that __uart_port_using_nbcon() relies on the port->lock being held while a console is added and removed from the console list (i.e. all uart nbcon drivers *must* take the port->lock in their device_lock() callbacks). Signed-off-by: John Ogness Acked-by: Greg Kroah-Hartman Reviewed-by: Petr Mladek --- include/linux/serial_core.h | 82 ++++++++++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 2 deletions(-) diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 038693774f21..14fb5458dafa 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include #include #include @@ -623,6 +625,60 @@ static inline void uart_port_set_cons(struct uart_port= *up, struct console *con) up->cons =3D con; __uart_port_unlock_irqrestore(up, flags); } + +/* Only for internal port lock wrapper usage. */ +static inline bool __uart_port_using_nbcon(struct uart_port *up) +{ + lockdep_assert_held_once(&up->lock); + + if (likely(!uart_console(up))) + return false; + + /* + * @up->cons is only modified under the port lock. Therefore it is + * certain that it cannot disappear here. + * + * @up->cons->node is added/removed from the console list under the + * port lock. Therefore it is certain that the registration status + * cannot change here, thus @up->cons->flags can be read directly. + */ + if (hlist_unhashed_lockless(&up->cons->node) || + !(up->cons->flags & CON_NBCON) || + !up->cons->write_atomic) { + return false; + } + + return true; +} + +/* Only for internal port lock wrapper usage. */ +static inline bool __uart_port_nbcon_try_acquire(struct uart_port *up) +{ + if (!__uart_port_using_nbcon(up)) + return true; + + return nbcon_device_try_acquire(up->cons); +} + +/* Only for internal port lock wrapper usage. */ +static inline void __uart_port_nbcon_acquire(struct uart_port *up) +{ + if (!__uart_port_using_nbcon(up)) + return; + + while (!nbcon_device_try_acquire(up->cons)) + cpu_relax(); +} + +/* Only for internal port lock wrapper usage. */ +static inline void __uart_port_nbcon_release(struct uart_port *up) +{ + if (!__uart_port_using_nbcon(up)) + return; + + nbcon_device_release(up->cons); +} + /** * uart_port_lock - Lock the UART port * @up: Pointer to UART port structure @@ -630,6 +686,7 @@ static inline void uart_port_set_cons(struct uart_port = *up, struct console *con) static inline void uart_port_lock(struct uart_port *up) { spin_lock(&up->lock); + __uart_port_nbcon_acquire(up); } =20 /** @@ -639,6 +696,7 @@ static inline void uart_port_lock(struct uart_port *up) static inline void uart_port_lock_irq(struct uart_port *up) { spin_lock_irq(&up->lock); + __uart_port_nbcon_acquire(up); } =20 /** @@ -649,6 +707,7 @@ static inline void uart_port_lock_irq(struct uart_port = *up) static inline void uart_port_lock_irqsave(struct uart_port *up, unsigned l= ong *flags) { spin_lock_irqsave(&up->lock, *flags); + __uart_port_nbcon_acquire(up); } =20 /** @@ -659,7 +718,15 @@ static inline void uart_port_lock_irqsave(struct uart_= port *up, unsigned long *f */ static inline bool uart_port_trylock(struct uart_port *up) { - return spin_trylock(&up->lock); + if (!spin_trylock(&up->lock)) + return false; + + if (!__uart_port_nbcon_try_acquire(up)) { + spin_unlock(&up->lock); + return false; + } + + return true; } =20 /** @@ -671,7 +738,15 @@ static inline bool uart_port_trylock(struct uart_port = *up) */ static inline bool uart_port_trylock_irqsave(struct uart_port *up, unsigne= d long *flags) { - return spin_trylock_irqsave(&up->lock, *flags); + if (!spin_trylock_irqsave(&up->lock, *flags)) + return false; + + if (!__uart_port_nbcon_try_acquire(up)) { + spin_unlock_irqrestore(&up->lock, *flags); + return false; + } + + return true; } =20 /** @@ -680,6 +755,7 @@ static inline bool uart_port_trylock_irqsave(struct uar= t_port *up, unsigned long */ static inline void uart_port_unlock(struct uart_port *up) { + __uart_port_nbcon_release(up); spin_unlock(&up->lock); } =20 @@ -689,6 +765,7 @@ static inline void uart_port_unlock(struct uart_port *u= p) */ static inline void uart_port_unlock_irq(struct uart_port *up) { + __uart_port_nbcon_release(up); spin_unlock_irq(&up->lock); } =20 @@ -699,6 +776,7 @@ static inline void uart_port_unlock_irq(struct uart_por= t *up) */ static inline void uart_port_unlock_irqrestore(struct uart_port *up, unsig= ned long flags) { + __uart_port_nbcon_release(up); spin_unlock_irqrestore(&up->lock, flags); } =20 --=20 2.39.2 From nobody Fri Feb 13 13:25:47 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 71E26374F1 for ; Mon, 27 May 2024 06:38:23 +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=1716791905; cv=none; b=Z5s5rpjzvhL+OqID/rS6wGJBZ5wQVBbyAed64GnSB9HA3urybjkXxd09XznAUszBEPUClKiiIcOKaOxyn6nwu3Ldm0Galk4kkYSHOMlizJ6mVuv60cM9Xi2nvSwyFDrn1qYTF4tHMSep84Wuh0MNey7lfHq3UPYgfihVDwEN2Ns= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716791905; c=relaxed/simple; bh=E2NKGH/rrfyJNZKSY6nFv6k2pt3uU3cBrXrF7Li/rpw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=c9rR+PlEZKs54pTBTm85NvS7G9cI5V2kDL0+5lE4ejcHyzNH5JD/eFo+j6dR0PSC9eRTJYo/oc3Gt2lkNM/Im7j/9z6yDtE/3TfKCuFYp3t/LVvc6Dv2uGS82tviLSnR5UrIFltdds1YocTxgWLFacTg7++fjoRMKpawJeVpwPs= 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=n6XehCcg; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=Q6itJR44; 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="n6XehCcg"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="Q6itJR44" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1716791901; 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=97ofN7IzRf8lwRnx1TzMt6u0N2QRUJRUSz4BCcorVpk=; b=n6XehCcgHhTwjYPGj0PiorRnBHUVBVBIgma4xQzqxFp3Wm8JsAn0F7j7p3L4NYhAFlzjBc ndNkrMmUcR/5tWwoY1xuW/f8la5KRQPm2InZ823ATSo7IJSB6q5psI1/rpPCWebLei9uex d2kIT+yaDxTh6nDwRxdbYalBapfNI8EugCmSZtgHQDtFPP3l6uIWybGbJ/lqEimZdVj73F w7avOxTHYvm1Yq76zTXTOAcGa7uVDKNRNTsDrMWv1z07nvClw3zY2E5+Lm+dyCuip9abLQ vNmJ8LUF8Xw6COGeXXuzoYgbmmeSVMDCUryJShSbVcazwP64GFpRukpWMxsm2g== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1716791901; 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=97ofN7IzRf8lwRnx1TzMt6u0N2QRUJRUSz4BCcorVpk=; b=Q6itJR44VPnIHYU8OgeS1CY8pCui22eWHBUj3zat0xWfe2BXOq+DFtUaPiQ03KdGCIng94 kdCcgvZA6XE950DQ== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Andy Shevchenko Subject: [PATCH printk v6 13/30] printk: nbcon: Do not rely on proxy headers Date: Mon, 27 May 2024 08:43:32 +0206 Message-Id: <20240527063749.391035-14-john.ogness@linutronix.de> In-Reply-To: <20240527063749.391035-1-john.ogness@linutronix.de> References: <20240527063749.391035-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 headers kernel.h, serial_core.h, and console.h allow for the definitions of many types and functions from other headers. Rather than relying on these as proxy headers, explicitly include all headers providing needed definitions. Also sort the list alphabetically to be able to easily detect duplicates. Suggested-by: Andy Shevchenko Signed-off-by: John Ogness Reviewed-by: Andy Shevchenko Acked-by: Petr Mladek --- kernel/printk/internal.h | 8 ++++++-- kernel/printk/nbcon.c | 13 ++++++++++++- kernel/printk/printk_ringbuffer.h | 2 ++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h index 831f95f26d48..6c1d01eabf3b 100644 --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h @@ -2,11 +2,12 @@ /* * internal.h - printk internal definitions */ -#include #include -#include "printk_ringbuffer.h" +#include +#include =20 #if defined(CONFIG_PRINTK) && defined(CONFIG_SYSCTL) +struct ctl_table; void __init printk_sysctl_init(void); int devkmsg_sysctl_set_loglvl(struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos); @@ -43,6 +44,9 @@ enum printk_info_flags { LOG_CONT =3D 8, /* text is a fragment of a continuation line */ }; =20 +struct printk_ringbuffer; +struct dev_printk_info; + extern struct printk_ringbuffer *prb; =20 __printf(4, 0) diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c index 1c03508b90f2..5c75ba28e80c 100644 --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c @@ -2,13 +2,24 @@ // Copyright (C) 2022 Linutronix GmbH, John Ogness // Copyright (C) 2022 Intel, Thomas Gleixner =20 -#include +#include +#include #include #include +#include #include +#include +#include +#include +#include +#include #include +#include +#include #include +#include #include "internal.h" +#include "printk_ringbuffer.h" /* * Printk console printing implementation for consoles which does not depe= nd * on the legacy style console_lock mechanism. diff --git a/kernel/printk/printk_ringbuffer.h b/kernel/printk/printk_ringb= uffer.h index 52626d0f1fa3..bd2a892deac1 100644 --- a/kernel/printk/printk_ringbuffer.h +++ b/kernel/printk/printk_ringbuffer.h @@ -5,6 +5,8 @@ =20 #include #include +#include +#include =20 /* * Meta information about each stored message. --=20 2.39.2 From nobody Fri Feb 13 13:25:47 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 BD41639AC9 for ; Mon, 27 May 2024 06:38:23 +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=1716791905; cv=none; b=P1+0t+Bn3SPPctq4u88bM7owtk872uPv4XMW2fN8A++6v1sHBCdEIlZHbSQ9vhQFkG6pPynS9pgsnQBPVCeLXyeObvGFhDKJEyawCuVyBoukhii5dlaIfo7lTVCqBdC0SheChQMqpkSkbtfK6VK5zpr/icpRpk+m+qr89gLRwEM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716791905; c=relaxed/simple; bh=e+s5yp9kuOUcSKomNwvNgs7LuhomtVTH2kEePY50ErY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=cPKt40vtaZcgz4+uNBtazTVa6uMTr55nn7qUY2rYsJPv1JlJEHbN0fqs5VZDm5zjJ/+UOxlKc/kItu/z2eRI7tjbTj5e7AObczGDXsZzenYgynzvWUVg6h1c2pUlAkq7RFfVN77nF3A08beMHzzo5VA5g8JJCMAZk2fj6S7rCYw= 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=sMp6+EjY; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=I+bsIqBG; 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="sMp6+EjY"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="I+bsIqBG" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1716791902; 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=KpkOnoEtjNOpdOq64j/1rkP+WasLftMlBbDsyMeeGFk=; b=sMp6+EjYeS6YAY8SgyjF5e5BXoJxOg4s7avGTViMvziV0zJ7G+yUbtCWn4sU/v0vRqCov2 ZKAaEAT7RtL4kLaDAJqQrQdULBaq3Tdi0Oxj3QMBRp/qvcynfBhI3rjlezvV2pzBCupVDj TGrxOuVwDqAsERWrk9Dp4LHpr/6jHWRTOepLEJA8OuB65VhFWC4X2Z/9hhyWo2uxXgku0I ri3omk2qAcp+QO9OkwuwAsjzHm/+lrbyHZSm1LBY0RsRSdeACNq8LpQGO4Ugap+lzf7hxU bhfJEe0EWoJR9gWsOVW4onT3Bgg9Ab0GBJjXAu4wEOf1lHheqd9PtepDAfTH3g== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1716791902; 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=KpkOnoEtjNOpdOq64j/1rkP+WasLftMlBbDsyMeeGFk=; b=I+bsIqBGpA1zIjFTPZZYJf+8xCoHy4GUJF1NxokOLusl4kQi/uAQRjr3mrc6c4+p5gailH DzNeZXV7TnfptnDQ== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Greg Kroah-Hartman , Randy Dunlap Subject: [PATCH printk v6 14/30] printk: nbcon: Fix kerneldoc for enums Date: Mon, 27 May 2024 08:43:33 +0206 Message-Id: <20240527063749.391035-15-john.ogness@linutronix.de> In-Reply-To: <20240527063749.391035-1-john.ogness@linutronix.de> References: <20240527063749.391035-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" Kerneldoc requires enums to be specified as such. Otherwise it is interpreted as function documentation. Signed-off-by: John Ogness Reviewed-by: Randy Dunlap Reviewed-by: Petr Mladek --- include/linux/console.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/console.h b/include/linux/console.h index dd3d4b5d3737..729f7c3b10c1 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -137,7 +137,7 @@ static inline int con_debug_leave(void) */ =20 /** - * cons_flags - General console flags + * enum cons_flags - General console flags * @CON_PRINTBUFFER: Used by newly registered consoles to avoid duplicate * output of messages that were already shown by boot * consoles or read by userspace via syslog() syscall. @@ -218,7 +218,7 @@ struct nbcon_state { static_assert(sizeof(struct nbcon_state) <=3D sizeof(int)); =20 /** - * nbcon_prio - console owner priority for nbcon consoles + * enum nbcon_prio - console owner priority for nbcon consoles * @NBCON_PRIO_NONE: Unused * @NBCON_PRIO_NORMAL: Normal (non-emergency) usage * @NBCON_PRIO_EMERGENCY: Emergency output (WARN/OOPS...) --=20 2.39.2 From nobody Fri Feb 13 13:25:47 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 1676E4594D for ; Mon, 27 May 2024 06:38:24 +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=1716791907; cv=none; b=ues1e2eJWLxFI7abIm6LkQUZCbynKfXfsVdQhw2xyictFrnXtn8xTT+Gi0PqSZPnRbZGMInkX436S+6JhfdRCx3jfpJQ4SSRMTS4FbwSbCAmIkaOQ921s1o/XkFGeU06u4bKrIYnhM5zKncFSEjHiZ4dJ1fPXoZPLVb3i/OfbGE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716791907; c=relaxed/simple; bh=4TqYg9C9M7bVyQVBRTlOYVbfQwj4hBnVKOPQn39lBzI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=KS1kc8RT9Lhfx9ILfIvXhJWvzSbECPHS/6mcYgCmqsBwx5ON2BRFli+B7u2oEqCoLOuBK9OqSuTpRiFwajvb1cSXhq1KprPfhR5DTAXCDBnP7+1Mj/xgBy+6v6PW6XSlP6bZZLuKRgv4RBk4ejiIjA/aQWJwvOQDF/2srs9TmVU= 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=GHuqOGJW; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=NK4ijYFW; 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="GHuqOGJW"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="NK4ijYFW" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1716791902; 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=vAfJ0/ArpyBrKdvlxG2JN5Vl00RCt4dDRQpqktRYYBg=; b=GHuqOGJWM0mKftTjKcJZFWer07OfurTQzkE2xHi9zx93nnmXVS4hW7PfaXl07TmhDxWjXc lMPDWaSCycf9iIbsh3/lZ+NN5cCuUWKXpqBW49osTb3gffPbTNA0aARqoHAPTyvgvZ+Gqr eoVCxn7oQV4xsOszXIT/qQa2HKhILG3YPcM/8xp3aTwzs9CZvVSSV9FM6AQkcZBc7ugqMH FYBOSqhjIspUcyMpmZV3qnEu51WqN3zmNv88SdPN21dhsBxwDrkN/uuYYpFtG1+7QKzZL7 zT+iqgZ9+AAj2icfNMIHX/z8trqf/8D4W7U3uko3qU5UIBwq6zczM9tdwwtRJg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1716791902; 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=vAfJ0/ArpyBrKdvlxG2JN5Vl00RCt4dDRQpqktRYYBg=; b=NK4ijYFWANDnGQrJZ+jdRFOKCqDon2eMqGJl5Vzuj6lF3XPUvJ2r4BvTb7q2eQNhQJK3HF lhCY06fcUasuigAg== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v6 15/30] printk: Make console_is_usable() available to nbcon Date: Mon, 27 May 2024 08:43:34 +0206 Message-Id: <20240527063749.391035-16-john.ogness@linutronix.de> In-Reply-To: <20240527063749.391035-1-john.ogness@linutronix.de> References: <20240527063749.391035-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" Move console_is_usable() as-is into internal.h so that it can be used by nbcon printing functions as well. Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- kernel/printk/internal.h | 32 ++++++++++++++++++++++++++++++++ kernel/printk/printk.c | 30 ------------------------------ 2 files changed, 32 insertions(+), 30 deletions(-) diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h index 6c1d01eabf3b..339563dd60bb 100644 --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h @@ -85,6 +85,36 @@ bool nbcon_alloc(struct console *con); void nbcon_init(struct console *con, u64 init_seq); void nbcon_free(struct console *con); =20 +/* + * Check if the given console is currently capable and allowed to print + * records. + * + * Requires the console_srcu_read_lock. + */ +static inline bool console_is_usable(struct console *con) +{ + short flags =3D console_srcu_read_flags(con); + + if (!(flags & CON_ENABLED)) + return false; + + if ((flags & CON_SUSPENDED)) + return false; + + if (!con->write) + return false; + + /* + * Console drivers may assume that per-cpu resources have been + * allocated. So unless they're explicitly marked as being able to + * cope (CON_ANYTIME) don't call them until this CPU is officially up. + */ + if (!cpu_online(raw_smp_processor_id()) && !(flags & CON_ANYTIME)) + return false; + + return true; +} + #else =20 #define PRINTK_PREFIX_MAX 0 @@ -106,6 +136,8 @@ static inline bool nbcon_alloc(struct console *con) { r= eturn false; } static inline void nbcon_init(struct console *con, u64 init_seq) { } static inline void nbcon_free(struct console *con) { } =20 +static inline bool console_is_usable(struct console *con) { return false; } + #endif /* CONFIG_PRINTK */ =20 extern struct printk_buffers printk_shared_pbufs; diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 75f64efaa53c..3947702b7977 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -2697,36 +2697,6 @@ int is_console_locked(void) } EXPORT_SYMBOL(is_console_locked); =20 -/* - * Check if the given console is currently capable and allowed to print - * records. - * - * Requires the console_srcu_read_lock. - */ -static inline bool console_is_usable(struct console *con) -{ - short flags =3D console_srcu_read_flags(con); - - if (!(flags & CON_ENABLED)) - return false; - - if ((flags & CON_SUSPENDED)) - return false; - - if (!con->write) - return false; - - /* - * Console drivers may assume that per-cpu resources have been - * allocated. So unless they're explicitly marked as being able to - * cope (CON_ANYTIME) don't call them until this CPU is officially up. - */ - if (!cpu_online(raw_smp_processor_id()) && !(flags & CON_ANYTIME)) - return false; - - return true; -} - static void __console_unlock(void) { console_locked =3D 0; --=20 2.39.2 From nobody Fri Feb 13 13:25:47 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 1903C4597F for ; Mon, 27 May 2024 06:38:24 +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=1716791906; cv=none; b=Zs3C6ElnveA3IiK3V+FlVJiCDW4T8TPyzb/OAfZu2LiGh4nOsVaCizB6MOWPYQMA/xWxD7M/NB2HSiC3RlGDlUF7PCG9hAlVPg9K8BJZW0mUnGXkYhyAko4rn9H7qXtHcVybxQ6LUqV/CdsWiWNmoOy8SLvtAAyRmyNzjqdF5U0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716791906; c=relaxed/simple; bh=lwK7GcrDHEjSCVMCl6fH9fAyvwP+TuECoQz0KJrspIs=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=EBYGl4ntQRRvgVilhe451W31T1vIuSGV4+Ag3wrZY9ENLc1On4imuynLOmXQMYsNxzByvf2h7t7waML3aeX8LTdClYFFscXYCvJjnqOMqHknRxoT4epbEHh8zt87a5fRr8EUZr+rULC5xrCKRAhnrBVt/tXqtkSMfxOO7LcGxNI= 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=prLPqaXY; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=lwTrE/7f; 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="prLPqaXY"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="lwTrE/7f" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1716791902; 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=gIB/C0kn4U7fgTEgQsG7CoHVIr2JrRBBOwabsQzPu5A=; b=prLPqaXY/YwLg18ps2ATzjroIHoOJyl8e1ibma8O9cTQJXRP1Cjk7ZMBB35DbQ3cej9yn3 QEYGg8eXC+VR9BWb/xHw/E6fJSLCuiK3ZbbsrOHap1+tWwtHTgptypGdjem+0WVGVOoYjL cjGAVLVl8fmf7PLV9ykK0xNc3a5050fUPSb4TPuJdggKzIP0x3VOHfNF7Vm+9PkXoF86rj Ci9CEUDg7eqa7v8pjgvNHZ8sJ+GvXtrRoBH+70niNlohmEHCzmLet13UysEOhsuuK+65qE I/YOZC1f0tB4LqduIji/xSVfhY550Q+eNjdBCDuIMUnlUlHu0tsWH3MMrhbwJQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1716791902; 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=gIB/C0kn4U7fgTEgQsG7CoHVIr2JrRBBOwabsQzPu5A=; b=lwTrE/7f/XOHeBAl3/9gxDZ0udiSbhCfuTHx0npOCRd/B6GNSbaE9lDbrS1YK53WdAKlXq 6GjO2SQO18TgYlBQ== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v6 16/30] printk: Let console_is_usable() handle nbcon Date: Mon, 27 May 2024 08:43:35 +0206 Message-Id: <20240527063749.391035-17-john.ogness@linutronix.de> In-Reply-To: <20240527063749.391035-1-john.ogness@linutronix.de> References: <20240527063749.391035-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 use a different printing callback. For nbcon consoles, check for the write_atomic() callback instead of write(). Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- kernel/printk/internal.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h index 339563dd60bb..943e8f083609 100644 --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h @@ -87,6 +87,8 @@ void nbcon_free(struct console *con); =20 /* * Check if the given console is currently capable and allowed to print + * records. Note that this function does not consider the current context, + * which can also play a role in deciding if @con can be used to print * records. * * Requires the console_srcu_read_lock. @@ -101,8 +103,13 @@ static inline bool console_is_usable(struct console *c= on) if ((flags & CON_SUSPENDED)) return false; =20 - if (!con->write) - return false; + if (flags & CON_NBCON) { + if (!con->write_atomic) + return false; + } else { + if (!con->write) + return false; + } =20 /* * Console drivers may assume that per-cpu resources have been --=20 2.39.2 From nobody Fri Feb 13 13:25:47 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 505B64779F for ; Mon, 27 May 2024 06:38:25 +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=1716791907; cv=none; b=GB/jyRKHI9iEfMsxH32fVvONLha9VHTRvNiVfFxMmm4FtDTSbu8qKL63enEBbhSJSiZnMAUf4PyvmhpgaY0mdyg+YzV9xfHD3Fm33coF6o//XhMGv29WBkKUV7ej2gm75ejVrExMXdEf1k+EwxVT7761vL1HiyaQ8zhx5WrdXDg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716791907; c=relaxed/simple; bh=Rezx37ZAMeSkcTz4eHSQoA8t3LwCmXbSpMIu1F4cxOY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Rs6zTxkp/xBNijfUccZ7bmHDmRYHEocM6w2ExQHXzwMP1HN+hBKUcUq24pbgfGR7KuEKLTF9sP9GOZfhlX8rJIHpw3nOXsKWivDz+3McCB+9/+eEbURhiYa+cQ86D2VsTa9tcAEhW1wEqhNbk68Smy/8rUCdg/YNbSuJQpilKBE= 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=xh5/Smyz; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=HR2wR2kd; 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="xh5/Smyz"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="HR2wR2kd" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1716791903; 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=dZZq8JTDc/bSa5Wad3zQxrhy3UUWwTzRNl4k7bMmCns=; b=xh5/Smyz66WOa5rKJmPiOQauOT3TqMznaWocfXJyjoTnOn20ZBluKATxijAWx31SM98ecl SqBftizzZ6QfVjfa6YrpqSLEkiJCYu7n72D12QXRkGLiEAeUknFHo10duRE3fQhtzcI2hZ emhdkbex3NHpXkZRYh9rzdyDfvGRlR6xvCJb6Usg4btYPcdY3jBpoga3rOArdX+178gq+j SZLq8QzKe639Cc+yJlqg1MfwCem1gOiBeSYqPIq01wfAaDH2agVTvet1x36yQI1qAUyxLf 95N5N3Nija6xxSCIYBeRhyftoVI8s620shZBpNugFR5eNtc7sY8PlgC3wNTXog== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1716791903; 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=dZZq8JTDc/bSa5Wad3zQxrhy3UUWwTzRNl4k7bMmCns=; b=HR2wR2kdZJdN0Ly+eo6wZ27MD2WRMuHDt8faekNd9Wp5xD3lKzSLuJJyvY0pV6tWHUN587 tJ/FprpFlr0qvrBw== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v6 17/30] printk: Add @flags argument for console_is_usable() Date: Mon, 27 May 2024 08:43:36 +0206 Message-Id: <20240527063749.391035-18-john.ogness@linutronix.de> In-Reply-To: <20240527063749.391035-1-john.ogness@linutronix.de> References: <20240527063749.391035-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 caller of console_is_usable() usually needs @console->flags for its own checks. Rather than having console_is_usable() read its own copy, make the caller pass in the @flags. This also ensures that the caller saw the same @flags value. Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- kernel/printk/internal.h | 8 ++------ kernel/printk/printk.c | 5 +++-- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h index 943e8f083609..e2de2d262db4 100644 --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h @@ -90,13 +90,9 @@ void nbcon_free(struct console *con); * records. Note that this function does not consider the current context, * which can also play a role in deciding if @con can be used to print * records. - * - * Requires the console_srcu_read_lock. */ -static inline bool console_is_usable(struct console *con) +static inline bool console_is_usable(struct console *con, short flags) { - short flags =3D console_srcu_read_flags(con); - if (!(flags & CON_ENABLED)) return false; =20 @@ -143,7 +139,7 @@ static inline bool nbcon_alloc(struct console *con) { r= eturn false; } static inline void nbcon_init(struct console *con, u64 init_seq) { } static inline void nbcon_free(struct console *con) { } =20 -static inline bool console_is_usable(struct console *con) { return false; } +static inline bool console_is_usable(struct console *con, short flags) { r= eturn false; } =20 #endif /* CONFIG_PRINTK */ =20 diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 3947702b7977..2dd7add07b5d 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -2942,9 +2942,10 @@ static bool console_flush_all(bool do_cond_resched, = u64 *next_seq, bool *handove =20 cookie =3D console_srcu_read_lock(); for_each_console_srcu(con) { + short flags =3D console_srcu_read_flags(con); bool progress; =20 - if (!console_is_usable(con)) + if (!console_is_usable(con, flags)) continue; any_usable =3D true; =20 @@ -3825,7 +3826,7 @@ static bool __pr_flush(struct console *con, int timeo= ut_ms, bool reset_on_progre * that they make forward progress, so only increment * @diff for usable consoles. */ - if (!console_is_usable(c)) + if (!console_is_usable(c, flags)) continue; =20 if (flags & CON_NBCON) { --=20 2.39.2 From nobody Fri Feb 13 13:25:47 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 5051E2032A for ; Mon, 27 May 2024 06:38:25 +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=1716791907; cv=none; b=o9uz1DI3IRk26bTfUgsZ6dBqkxdUTNDUkwWQjYHUdEm86rVYSM/qbUUCjVTuyjxHX62YT0md5/EqlcaEmmzO67ivXoUo8+vhOGcRI25wzZrkYSI6QQV7Hh9w+iODzA24z8wt0iXw8CzVZ07+n6Z09IjMFx/erGQ/tuYEni7SY4M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716791907; c=relaxed/simple; bh=zIdDnOXlkpAr4wXXrW1lnomWo/FU9/LQB9BST474AnQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=CnOU06aPI9Jfi+sW/UmYCFDn/C+K9mofQqzq7RFDri9511PWKS7bl801skJXPnNvQTtAGmQeAGpmL5DwdS78zyu2LmvLpeFCGCL/dAvcxMAOjb7en5FrMLRmggIRBPr6pRLTd+LijlqZgz3AnGeby1EQTvP0op7+l/JgWYgOYdk= 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=CeAHKzSW; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=g2+bdbP4; 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="CeAHKzSW"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="g2+bdbP4" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1716791903; 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=OXVGPLDxDMAPJlIbkXd901VLd/8W6fOa0g3BKtOGhG0=; b=CeAHKzSW4cdqmhGzQqDTLKQs3MLS8+yqSD9TyagAHAb48WpOHu7+9d6ylcBV18Y6tAe/cC kZH4LhzGSyJ74JI5qnjizOS7uUi6zJnH3tqO2I9RDXFQSykhvdTUZC5BrZTUnPuhERNVsE W3aNLskrADDwyf5yP9/wT3J7K9MEZiKlAjWkwQQm/Ka3Qu/uCfcCrfB0jW2hLtnemwR6LP 7m1yqNGO47ueqJpL0nOUmc/9GBSEoE2kKivVQwPBmG7rNVAH1k0Rbh60vK0OxX/wzG1JJ2 tA6JCSqYbZNgSIPo5CteWm1bQWr6T2y9wuFg5qGMIqjXcDiLicguHXth2tESQg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1716791903; 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=OXVGPLDxDMAPJlIbkXd901VLd/8W6fOa0g3BKtOGhG0=; b=g2+bdbP45Z9sijA0WWF4y8B8XwyWGIA41osK/rA15KPnTEk1GETSpS5E79cHK9JDLyMSHn iAKyc36TtgC6PACQ== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v6 18/30] printk: nbcon: Add helper to assign priority based on CPU state Date: Mon, 27 May 2024 08:43:37 +0206 Message-Id: <20240527063749.391035-19-john.ogness@linutronix.de> In-Reply-To: <20240527063749.391035-1-john.ogness@linutronix.de> References: <20240527063749.391035-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" Add a helper function to use the current state of the CPU to determine which priority to assign to the printing context. The EMERGENCY priority handling is added in a follow-up commit. It will use a per-CPU variable. Note: nbcon_device_try_acquire(), which is used by console drivers to acquire the nbcon console for non-printing activities, will always use NORMAL priority. Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- kernel/printk/internal.h | 2 ++ kernel/printk/nbcon.c | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h index e2de2d262db4..5826cd4eed58 100644 --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h @@ -84,6 +84,7 @@ void nbcon_seq_force(struct console *con, u64 seq); bool nbcon_alloc(struct console *con); void nbcon_init(struct console *con, u64 init_seq); void nbcon_free(struct console *con); +enum nbcon_prio nbcon_get_default_prio(void); =20 /* * Check if the given console is currently capable and allowed to print @@ -138,6 +139,7 @@ static inline void nbcon_seq_force(struct console *con,= u64 seq) { } static inline bool nbcon_alloc(struct console *con) { return false; } static inline void nbcon_init(struct console *con, u64 init_seq) { } static inline void nbcon_free(struct console *con) { } +static inline enum nbcon_prio nbcon_get_default_prio(void) { return NBCON_= PRIO_NONE; } =20 static inline bool console_is_usable(struct console *con, short flags) { r= eturn false; } =20 diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c index 5c75ba28e80c..85bebea1a326 100644 --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c @@ -937,6 +937,22 @@ static bool nbcon_emit_next_record(struct nbcon_write_= context *wctxt) return nbcon_context_exit_unsafe(ctxt); } =20 +/** + * nbcon_get_default_prio - The appropriate nbcon priority to use for nbcon + * printing on the current CPU + * + * Context: Any context which could not be migrated to another CPU. + * Return: The nbcon_prio to use for acquiring an nbcon console in this + * context for printing. + */ +enum nbcon_prio nbcon_get_default_prio(void) +{ + if (this_cpu_in_panic()) + return NBCON_PRIO_PANIC; + + return NBCON_PRIO_NORMAL; +} + /** * nbcon_alloc - Allocate buffers needed by the nbcon console * @con: Console to allocate buffers for --=20 2.39.2 From nobody Fri Feb 13 13:25:47 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 8ACFF2030B for ; Mon, 27 May 2024 06:38:25 +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=1716791908; cv=none; b=WeXlsg6B5qp8LTbCqX3wu1/JOIhYpsOUq7n1699ltuwsY33sayfekZMiQIVbfpiDC7Ct5nrLB21s2E2e0YUJ7stXUGOvTx9+hvP87RhRpKn06a1VeL5evJJBblQE/mH76XOoLMVi4vBLCoxhGJfmtvSJSnLt1hvse6MLPRchdio= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716791908; c=relaxed/simple; bh=dpzXjOanPnBbd1Ae7HCtcVqYVTtvZJapQQySvGVpBNI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=G67Or5zf7OUWIMbk4jkbK11/cW27x5pLZuDaTxw/o/ZADjFGQDq7s07l9y116l7plSYL3Bg55loc5/Qwa9TB1mDSinauVL2KeJWptvyC/b/mXy+IsgTzHSluwyxkQJ+zUtQ/KgXKCpaj34c3PFLmHMMskQGVsRaN4kBXziN6zLY= 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=Yk0764/h; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=rc5aQReb; 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="Yk0764/h"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="rc5aQReb" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1716791903; 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=tb9xTUaRDo4DonPbcR+009ZjcAxnSNSSkX832/2ms80=; b=Yk0764/h5jLVPEUrCu4bPmQEmfkv0fcmia5VD0FA2wYjtOTeHQtF2huC3Ry6Wtds4m1JC2 CCRIBOZMHmRj2RHjgcsSWfeorECVMLpMEhoKQMUXsrqnq2FlPVycMonmuXtkdJXCsWGHux 3T57CLg+2ASjDZBpIcv1MyZSyoOU47Ar4dsnednEz/RJ+flRHnnHZ38vaWe9RBbM8yLsEm sky3vZHfpd1BzXQaRXRmDOOikeZ1gifzYZtSyWAPUPlNa9yWALdJRftM18LOu5aFp/oFnt FG1Km4kKyjwAimytWU7Tyn5JBRto2zhSERQSKaZOKxjw9wdS73Ile28risLCEA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1716791903; 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=tb9xTUaRDo4DonPbcR+009ZjcAxnSNSSkX832/2ms80=; b=rc5aQRebkmWA2y92KAVbTgq/zQpXVkSYc87HNOhycJ3XMBfMfscrgUmK7w35oet/gnpiUN ErcOyECPro/auuBA== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v6 19/30] printk: nbcon: Provide function to flush using write_atomic() Date: Mon, 27 May 2024 08:43:38 +0206 Message-Id: <20240527063749.391035-20-john.ogness@linutronix.de> In-Reply-To: <20240527063749.391035-1-john.ogness@linutronix.de> References: <20240527063749.391035-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 nbcon_atomic_flush_pending() to perform flushing of all registered nbcon consoles using their write_atomic() callback. Unlike console_flush_all(), nbcon_atomic_flush_pending() will only flush up through the newest record at the time of the call. This prevents a CPU from printing unbounded when other CPUs are adding records. If new records are added while flushing, it is expected that the dedicated printer threads will print those records. If the printer thread is not available (which is always the case at this point in the rework), nbcon_atomic_flush_pending() _will_ flush all records in the ringbuffer. Unlike console_flush_all(), nbcon_atomic_flush_pending() will fully flush one console before flushing the next. This helps to guarantee that a block of pending records (such as a stack trace in an emergency situation) can be printed atomically at once before releasing console ownership. nbcon_atomic_flush_pending() is safe in any context because it uses write_atomic() and acquires with unsafe_takeover disabled. Use it in console_flush_on_panic() before flushing legacy consoles. The legacy write() callbacks are not fully safe when oops_in_progress is set. Also use it in nbcon_device_release() to flush records added while the driver had the console locked to perform non-printing operations. Co-developed-by: John Ogness Signed-off-by: John Ogness Signed-off-by: Thomas Gleixner (Intel) --- kernel/printk/internal.h | 2 + kernel/printk/nbcon.c | 169 ++++++++++++++++++++++++++++++++++++++- kernel/printk/printk.c | 2 + 3 files changed, 170 insertions(+), 3 deletions(-) diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h index 5826cd4eed58..5a93825871de 100644 --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h @@ -85,6 +85,7 @@ bool nbcon_alloc(struct console *con); void nbcon_init(struct console *con, u64 init_seq); void nbcon_free(struct console *con); enum nbcon_prio nbcon_get_default_prio(void); +void nbcon_atomic_flush_pending(void); =20 /* * Check if the given console is currently capable and allowed to print @@ -140,6 +141,7 @@ static inline bool nbcon_alloc(struct console *con) { r= eturn false; } static inline void nbcon_init(struct console *con, u64 init_seq) { } 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) { } =20 static inline bool console_is_usable(struct console *con, short flags) { r= eturn false; } =20 diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c index 85bebea1a326..fc48fcb4da9b 100644 --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c @@ -850,7 +850,6 @@ EXPORT_SYMBOL_GPL(nbcon_exit_unsafe); * When true is returned, @wctxt->ctxt.backlog indicates whether there are * still records pending in the ringbuffer, */ -__maybe_unused static bool nbcon_emit_next_record(struct nbcon_write_context *wctxt) { struct nbcon_context *ctxt =3D &ACCESS_PRIVATE(wctxt, ctxt); @@ -953,6 +952,155 @@ enum nbcon_prio nbcon_get_default_prio(void) return NBCON_PRIO_NORMAL; } =20 +/* + * __nbcon_atomic_flush_pending_con - Flush specified nbcon console using = its + * write_atomic() callback + * @con: The nbcon console to flush + * @stop_seq: Flush up until this record + * + * Return: 0 if @con was flushed up to @stop_seq Otherwise, error code on + * failure. + * + * Errors: + * + * -EPERM: Unable to acquire console ownership. + * + * -EAGAIN: Another context took over ownership while printing. + * + * -ENOENT: A record before @stop_seq is not available. + * + * If flushing up to @stop_seq was not successful, it only makes sense for= the + * caller to try again when -EAGAIN was returned. When -EPERM is returned, + * this context is not allowed to acquire the console. When -ENOENT is + * returned, it cannot be expected that the unfinalized record will become + * available. + */ +static int __nbcon_atomic_flush_pending_con(struct console *con, u64 stop_= seq) +{ + struct nbcon_write_context wctxt =3D { }; + struct nbcon_context *ctxt =3D &ACCESS_PRIVATE(&wctxt, ctxt); + int err =3D 0; + + ctxt->console =3D con; + ctxt->spinwait_max_us =3D 2000; + ctxt->prio =3D nbcon_get_default_prio(); + + if (!nbcon_context_try_acquire(ctxt)) + return -EPERM; + + while (nbcon_seq_read(con) < stop_seq) { + /* + * nbcon_emit_next_record() returns false when the console was + * handed over or taken over. In both cases the context is no + * longer valid. + */ + if (!nbcon_emit_next_record(&wctxt)) + return -EAGAIN; + + if (!ctxt->backlog) { + /* Are there reserved but not yet finalized records? */ + if (nbcon_seq_read(con) < stop_seq) + err =3D -ENOENT; + break; + } + } + + nbcon_context_release(ctxt); + return err; +} + +/** + * nbcon_atomic_flush_pending_con - Flush specified nbcon console using its + * write_atomic() callback + * @con: The nbcon console to flush + * @stop_seq: Flush up until this record + * + * This will stop flushing before @stop_seq if another context has ownersh= ip. + * That context is then responsible for the flushing. Likewise, if new rec= ords + * are added while this context was flushing and there is no other context + * to handle the printing, this context must also flush those records. + */ +static void nbcon_atomic_flush_pending_con(struct console *con, u64 stop_s= eq) +{ + unsigned long flags; + int err; + +again: + /* + * Atomic flushing does not use console driver synchronization (i.e. + * it does not hold the port lock for uart consoles). Therefore IRQs + * must be disabled to avoid being interrupted and then calling into + * a driver that will deadlock trying to acquire console ownership. + */ + local_irq_save(flags); + + err =3D __nbcon_atomic_flush_pending_con(con, stop_seq); + + local_irq_restore(flags); + + /* + * If there was a new owner (-EPERM, -EAGAIN), that context is + * responsible for completing. + * + * Do not wait for records not yet finalized (-ENOENT) to avoid a + * possible deadlock. They will either get flushed by the writer or + * eventually skipped on panic CPU. + */ + if (err) + return; + + /* + * 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. + */ + if (prb_read_valid(prb, nbcon_seq_read(con), NULL)) { + stop_seq =3D prb_next_reserve_seq(prb); + goto again; + } +} + +/** + * __nbcon_atomic_flush_pending - Flush all nbcon consoles using their + * write_atomic() callback + * @stop_seq: Flush up until this record + */ +static void __nbcon_atomic_flush_pending(u64 stop_seq) +{ + struct console *con; + int cookie; + + cookie =3D console_srcu_read_lock(); + for_each_console_srcu(con) { + short flags =3D console_srcu_read_flags(con); + + if (!(flags & CON_NBCON)) + continue; + + if (!console_is_usable(con, flags)) + continue; + + if (nbcon_seq_read(con) >=3D stop_seq) + continue; + + nbcon_atomic_flush_pending_con(con, stop_seq); + } + console_srcu_read_unlock(cookie); +} + +/** + * nbcon_atomic_flush_pending - Flush all nbcon consoles using their + * write_atomic() callback + * + * Flush the backlog up through the currently newest record. Any new + * records added while flushing will not be flushed. This is to avoid + * one CPU printing unbounded because other CPUs continue to add records. + */ +void nbcon_atomic_flush_pending(void) +{ + __nbcon_atomic_flush_pending(prb_next_reserve_seq(prb)); +} + /** * nbcon_alloc - Allocate buffers needed by the nbcon console * @con: Console to allocate buffers for @@ -1065,8 +1213,23 @@ EXPORT_SYMBOL_GPL(nbcon_device_try_acquire); void nbcon_device_release(struct console *con) { struct nbcon_context *ctxt =3D &ACCESS_PRIVATE(con, nbcon_device_ctxt); + int cookie; =20 - if (nbcon_context_exit_unsafe(ctxt)) - nbcon_context_release(ctxt); + if (!nbcon_context_exit_unsafe(ctxt)) + return; + + nbcon_context_release(ctxt); + + /* + * This context must flush any new records added while the console + * was locked. The console_srcu_read_lock must be taken to ensure + * the console is usable throughout flushing. + */ + cookie =3D console_srcu_read_lock(); + if (console_is_usable(con, console_srcu_read_flags(con)) && + prb_read_valid(prb, nbcon_seq_read(con), NULL)) { + __nbcon_atomic_flush_pending_con(con, prb_next_reserve_seq(prb)); + } + console_srcu_read_unlock(cookie); } EXPORT_SYMBOL_GPL(nbcon_device_release); diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 2dd7add07b5d..56d2377fc97f 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -3172,6 +3172,8 @@ void console_flush_on_panic(enum con_flush_mode mode) console_srcu_read_unlock(cookie); } =20 + nbcon_atomic_flush_pending(); + console_flush_all(false, &next_seq, &handover); } =20 --=20 2.39.2 From nobody Fri Feb 13 13:25:47 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 8D18D4D59F for ; Mon, 27 May 2024 06:38:25 +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=1716791907; cv=none; b=pLOJTiBpSCZqnuWtIVlCQtbondFeszO3ejVOD6VkIaHRDqCiBUgSxLw1/Bug8XOGJCssi5KciM5+A9Gl3TXE11Ux6LgPj/IohVTazuzlRAJRUwf+ItgswGQb6Mx+d5Fz+q2YfOPYFEZ9QfongnoEGSa16Am812D7kGAatm9YDuk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716791907; c=relaxed/simple; bh=DV9ePIcY234r7QPwO7jt9B0pkqMHFxrafa8XBXbKkPg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=naYBRB8ro1MXhQThpkIN66NmpKUxh8BB7HGc7YO6klW5qnzid0kwegTQaU6MgNkS5V0TaP08Lqd7IU702GBrqj2d3U3BDnWiPx22IUCm4djfvfW3pncIZ5eA/nXGVC8Qg4Ga5o/RQ00SJEuFhQKTF4nfKT0Weron2GoQGLkefuc= 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=KZNl70bT; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=JNIciXcu; 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="KZNl70bT"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="JNIciXcu" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1716791904; 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=0n6uVNwgqq5puIfDGgLjiBT2iercsin9z76FjHNuAQY=; b=KZNl70bTXp3m5cAe4kEfJH3PCw5hX0Q2wMhL7Zf0gm0JtHOdurXk8hEaou0OLQJpFNpV9O sLfmU5igFuVN2udrqNtgbvXyiSAu0gmKheimHZqfuoXbHy9dzQZRJoYRO8r0CcDLts4twE jefpNob5YvXlBW2aMVQRc4qeMvVI0LJmT2HRQJND+RYnLKd7zKZekcPgKwGcMOxEe1tdmU jUf6qs4B0jIV/SEdvyLskU1+Y9C42bSE9iqC1i74q97MKFIL4udoMjbJsAL4L86019Emeg +3pXeqIPGayKMcaufJjvND+sY+hY3qbLct+QL0KQjYkC7P4bYkGNk55lULNY1A== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1716791904; 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=0n6uVNwgqq5puIfDGgLjiBT2iercsin9z76FjHNuAQY=; b=JNIciXcukcyoUBLMA80RT7SOX69DQH+bX7og5NEQJRhSR3LcOgqb2w+6N7ijbLOcwJ7O0j veNZzIXA3a70DIDQ== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v6 20/30] printk: Track registered boot consoles Date: Mon, 27 May 2024 08:43:39 +0206 Message-Id: <20240527063749.391035-21-john.ogness@linutronix.de> In-Reply-To: <20240527063749.391035-1-john.ogness@linutronix.de> References: <20240527063749.391035-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" Unfortunately it is not known if a boot console and a regular (legacy or nbcon) console use the same hardware. For this reason they must not be allowed to print simultaneously. For legacy consoles this is not an issue because they are already synchronized with the boot consoles using the console lock. However nbcon consoles can be triggered separately. Add a global flag @have_boot_console to identify if any boot consoles are registered. This will be used in follow-up commits to ensure that boot consoles and nbcon consoles cannot print simultaneously. Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- kernel/printk/printk.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 56d2377fc97f..d81d541558fd 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -463,6 +463,14 @@ static int console_msg_format =3D MSG_FORMAT_DEFAULT; /* syslog_lock protects syslog_* variables and write access to clear_seq. = */ static DEFINE_MUTEX(syslog_lock); =20 +/* + * Specifies if a boot console is registered. If boot consoles are present, + * nbcon consoles cannot print simultaneously and must be synchronized by + * the console lock. This is because boot consoles and nbcon consoles may + * have mapped the same hardware. + */ +static bool have_boot_console; + #ifdef CONFIG_PRINTK DECLARE_WAIT_QUEUE_HEAD(log_wait); /* All 3 protected by @syslog_lock. */ @@ -3512,6 +3520,9 @@ void register_console(struct console *newcon) newcon->seq =3D init_seq; } =20 + if (newcon->flags & CON_BOOT) + have_boot_console =3D true; + /* * If another context is actively using the hardware of this new * console, it will not be aware of the nbcon synchronization. This @@ -3582,7 +3593,9 @@ 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 found_boot_con =3D false; unsigned long flags; + struct console *c; int res; =20 lockdep_assert_console_list_lock_held(); @@ -3640,6 +3653,17 @@ static int unregister_console_locked(struct console = *console) if (console->exit) res =3D console->exit(console); =20 + /* + * With this console gone, the global flags tracking registered + * console types may have changed. Update them. + */ + for_each_console(c) { + if (c->flags & CON_BOOT) + found_boot_con =3D true; + } + if (!found_boot_con) + have_boot_console =3D found_boot_con; + return res; } =20 --=20 2.39.2 From nobody Fri Feb 13 13:25:47 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 E543C537F2 for ; Mon, 27 May 2024 06:38:25 +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=1716791908; cv=none; b=mZdQWXrJuuv/EGTc0pwDzW9XDmilrYzv80nk/IPDcufk747FUj9n//1qitebd4/cJDZXepAiH189JygGBrxTKgVTTqPsJlgBPuOGwiG0zxh8DdFsZw03KgRlrW+ucypL8Ltpbqgn3G9lEw4vCnEVPQHF8xc2Ci9AP+KPx4QmeWQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716791908; c=relaxed/simple; bh=Q6b6AVR+OLPi2moRw9nS56wTI2Qvg3VL+I9G/3D9t3s=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=drtt5WdALahA8Ea0RMSas6mq439mNa/d29B5vlgQAA2wYVP5rsmvj2CkzlMxB4SMCXkWio3OwRvX+wPHjFteOGwCeMGD8+j+yk7Rch6DNYXKEgeu2g0ErDPMgMCCKv/N6Wi/RJCwUISo5yHNyxZBwNjy4n0PO0feQH3qZjbI1Ys= 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=IzsJikse; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=1ScfevS/; 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="IzsJikse"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="1ScfevS/" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1716791904; 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=A3In+KGOOeAXG80pN26YZIQE7Yh4V5NoQeSHCFrtsvU=; b=IzsJikseyh7cFQVKhRQZhdxqns8x0P2CGGeKKVYR/hBrGIDKHJ4VKbTebjSVGCxyZLcqkm waDbIAjQxP8MUGUVV0KAOM5b9jCKXBqDIzbKK2wENYWYwI8R/Ce8L2zT0WAdePHy/7Bmjr fJE2ep65pTv/Rj3ZAgNu+Sia4++M8STqwQNLwGgdBsXfaCvqQdFvF6SznXC7Kyt0T3aunr WIpo2Hi8xbl3ia8F5deu15WTJHCo0mXUrZmR20urN/3f5ixwc09GeUdr6nChFO/BTuPCz5 7HBImiCd9a2CyliVeprRt7Ys8C3chwu8+KO1OpNROSjb4VS7x56m0OcP/dfX4A== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1716791904; 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=A3In+KGOOeAXG80pN26YZIQE7Yh4V5NoQeSHCFrtsvU=; b=1ScfevS/Ae6sD8CaeGPDW/93aQoAdCYPhZH7U1QuCYKoBahOJms+/gN3gGXGarEejIaGYX FRnsWuGgbgq5tgBw== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v6 21/30] printk: nbcon: Use nbcon consoles in console_flush_all() Date: Mon, 27 May 2024 08:43:40 +0206 Message-Id: <20240527063749.391035-22-john.ogness@linutronix.de> In-Reply-To: <20240527063749.391035-1-john.ogness@linutronix.de> References: <20240527063749.391035-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 nbcon consoles to print messages in the legacy printk() caller context (printing via unlock) by integrating them into console_flush_all(). The write_atomic() callback is used for printing. Provide nbcon_legacy_emit_next_record(), which acts as the nbcon variant of console_emit_next_record(). Call this variant within console_flush_all() for nbcon consoles. Since nbcon consoles use their own @nbcon_seq variable to track the next record to print, this also must be appropriately handled in console_flush_all(). Note that the legacy printing logic uses @handover to detect handovers for printing all consoles. For nbcon consoles, handovers/takeovers occur on a per-console basis and thus do not cause the console_flush_all() loop to abort. Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- kernel/printk/internal.h | 6 +++ kernel/printk/nbcon.c | 87 ++++++++++++++++++++++++++++++++++++++++ kernel/printk/printk.c | 17 +++++--- 3 files changed, 105 insertions(+), 5 deletions(-) diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h index 5a93825871de..91bc0ee43f8d 100644 --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h @@ -78,6 +78,8 @@ void defer_console_output(void); =20 u16 printk_parse_prefix(const char *text, int *level, enum printk_info_flags *flags); +void console_lock_spinning_enable(void); +int console_lock_spinning_disable_and_check(int cookie); =20 u64 nbcon_seq_read(struct console *con); void nbcon_seq_force(struct console *con, u64 seq); @@ -86,6 +88,8 @@ void nbcon_init(struct console *con, u64 init_seq); 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); =20 /* * Check if the given console is currently capable and allowed to print @@ -142,6 +146,8 @@ static inline void nbcon_init(struct console *con, u64 = init_seq) { } 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; } =20 static inline bool console_is_usable(struct console *con, short flags) { r= eturn false; } =20 diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c index fc48fcb4da9b..f6fbcf6d80fa 100644 --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c @@ -953,6 +953,93 @@ 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 + * @wctxt: An initialized write context struct to use for this context + * + * Return: True, when a record has been printed and there are still + * pending records. The caller might want to continue flushing. + * + * False, when there is no pending record, or when the console + * context cannot be acquired, or the ownership has been lost. + * The caller should give up. Either the job is done, cannot be + * done, or will be handled by the owning context. + * + * 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) +{ + struct nbcon_context *ctxt =3D &ACCESS_PRIVATE(wctxt, ctxt); + + if (!nbcon_context_try_acquire(ctxt)) + return false; + + /* + * nbcon_emit_next_record() returns false when the console was + * handed over or taken over. In both cases the context is no + * longer valid. + * + * The higher priority printing context takes over responsibility + * to print the pending records. + */ + if (!nbcon_emit_next_record(wctxt)) + return false; + + nbcon_context_release(ctxt); + + return ctxt->backlog; +} + +/** + * nbcon_legacy_emit_next_record - Print one record for an nbcon console + * in legacy contexts + * @con: The console to print on + * @handover: Will be set to true if a printk waiter has taken over the + * console_lock, in which case the caller is no longer holding + * both the console_lock and the SRCU read lock. Otherwise it + * is set to false. + * @cookie: The cookie from the SRCU read lock. + * + * Context: Any context except NMI. + * Return: True, when a record has been printed and there are still + * pending records. The caller might want to continue flushing. + * + * False, when there is no pending record, or when the console + * context cannot be acquired, or the ownership has been lost. + * The caller should give up. Either the job is done, cannot be + * done, or will be handled by the owning context. + * + * This function is meant to be called by console_flush_all() to print rec= ords + * on nbcon consoles from legacy context (printing via console unlocking). + * Essentially it is the nbcon version of console_emit_next_record(). + */ +bool nbcon_legacy_emit_next_record(struct console *con, bool *handover, + int cookie) +{ + struct nbcon_write_context wctxt =3D { }; + struct nbcon_context *ctxt =3D &ACCESS_PRIVATE(&wctxt, ctxt); + unsigned long flags; + bool progress; + + /* 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; + ctxt->prio =3D nbcon_get_default_prio(); + + progress =3D nbcon_atomic_emit_one(&wctxt); + + start_critical_timings(); + *handover =3D console_lock_spinning_disable_and_check(cookie); + printk_safe_exit_irqrestore(flags); + + return progress; +} + +/** * __nbcon_atomic_flush_pending_con - Flush specified nbcon console using = its * write_atomic() callback * @con: The nbcon console to flush diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index d81d541558fd..9a7532cff8d2 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -1860,7 +1860,7 @@ static bool console_waiter; * there may be a waiter spinning (like a spinlock). Also it must be * ready to hand over the lock at the end of the section. */ -static void console_lock_spinning_enable(void) +void console_lock_spinning_enable(void) { /* * Do not use spinning in panic(). The panic CPU wants to keep the lock. @@ -1899,7 +1899,7 @@ static void console_lock_spinning_enable(void) * * Return: 1 if the lock rights were passed, 0 otherwise. */ -static int console_lock_spinning_disable_and_check(int cookie) +int console_lock_spinning_disable_and_check(int cookie) { int waiter; =20 @@ -2951,13 +2951,20 @@ static bool console_flush_all(bool do_cond_resched,= u64 *next_seq, bool *handove cookie =3D console_srcu_read_lock(); for_each_console_srcu(con) { short flags =3D console_srcu_read_flags(con); + u64 printk_seq; bool progress; =20 if (!console_is_usable(con, flags)) continue; any_usable =3D true; =20 - progress =3D console_emit_next_record(con, handover, cookie); + if (flags & CON_NBCON) { + progress =3D nbcon_legacy_emit_next_record(con, handover, cookie); + printk_seq =3D nbcon_seq_read(con); + } else { + progress =3D console_emit_next_record(con, handover, cookie); + printk_seq =3D con->seq; + } =20 /* * If a handover has occurred, the SRCU read lock @@ -2967,8 +2974,8 @@ static bool console_flush_all(bool do_cond_resched, u= 64 *next_seq, bool *handove return false; =20 /* Track the next of the highest seq flushed. */ - if (con->seq > *next_seq) - *next_seq =3D con->seq; + if (printk_seq > *next_seq) + *next_seq =3D printk_seq; =20 if (!progress) continue; --=20 2.39.2 From nobody Fri Feb 13 13:25:47 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 A9A306A33A for ; Mon, 27 May 2024 06:38:26 +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=1716791911; cv=none; b=jpxzlXTgUD2r5X9OdWWINF4j6PoJwhBgjg3r1P200m1Y/tShLWlQXEzK4aPSjUwwF0pfe1S1YyQ9jygiYO36woq6dl4Gnzx1h51W3NNE+UKjafvGLQvulYB0oKxEUbAgFzjOnyoRZg5VIS4gy8lNBj6PTXJTVDNFoHOpvQnb4sE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716791911; c=relaxed/simple; bh=5ZX5GBZo/iRQd90pLulxOq02+YtUo8w9tPoeedvPp7U=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=GBoj0J3tuSdovvVuGINJ0NrGJSngQTAQM0WNZhSf8yCv/6DWNkSlysE8t04ecG1bUPYujR3nXkzLqeuTiBSqNLdjH5IgHao4t8Vixc6GbhHYqIpwUyc6W0ALLyd9/AsUiq217/5vBeQsBuK/AKAdbuzPeqSVfvHYl4e5KT3Gz+M= 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=0haZ+Vm7; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=8JGxwTWJ; 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="0haZ+Vm7"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="8JGxwTWJ" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1716791905; 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=+EWJlSqjHDMU4hQIMZyXwjTsHTX5sDc8RBpfT5X64FU=; b=0haZ+Vm7sLZx0HZWIoPtP/zbCnrMMnb+KkjcZ/O0DN9x7RAi9NQ5i3KFxaNtN5AOr/3kQB gUGUTuqJrtqyG6s9HkXkUd6MnV0sjj8OccdNl55r4ntLzcdiq2X9OmRBvT1W2abzFFTr7R cuDIfCPp+yikO3bIuv1VvH3P2GT37vWc2SlemsfzQhjTlkS7aQqlIXpkopelioboLw2Lwu Rs0mI/14W/Rguue49aNsnYn1s4PVC7uHYIjKBOkxURTKvaOUCRAh+S/t3nlcXq+nAbYv2A iNTblZWl6A/GNWOkXqClwPat7fnBviRfkYw+2DBVA1kUH6z1uma4KRrlYKIAqg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1716791905; 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=+EWJlSqjHDMU4hQIMZyXwjTsHTX5sDc8RBpfT5X64FU=; b=8JGxwTWJlX44ee0Iw1lPp76DF1dzKhQMWHEXXbQDpYKgedze/ZEzhPWvL8cUVdW4BHNdW3 gt5LS+BCcMX//UAQ== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Andrew Morton , Uros Bizjak , Lukas Wunner , Kefeng Wang , Arnd Bergmann Subject: [PATCH printk v6 22/30] printk: nbcon: Add unsafe flushing on panic Date: Mon, 27 May 2024 08:43:41 +0206 Message-Id: <20240527063749.391035-23-john.ogness@linutronix.de> In-Reply-To: <20240527063749.391035-1-john.ogness@linutronix.de> References: <20240527063749.391035-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" Add nbcon_atomic_flush_unsafe() to flush all nbcon consoles using the write_atomic() callback and allowing unsafe hostile takeovers. Call this at the end of panic() as a final attempt to flush any pending messages. Note that legacy consoles use unsafe methods for flushing from the beginning of panic (see bust_spinlocks()). Therefore, systems using both legacy and nbcon consoles may still fail to see panic messages due to unsafe legacy console usage. Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- include/linux/printk.h | 5 +++++ kernel/panic.c | 1 + kernel/printk/nbcon.c | 32 +++++++++++++++++++++++++------- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/include/linux/printk.h b/include/linux/printk.h index 31f72df29da5..4d93d95cd5f0 100644 --- a/include/linux/printk.h +++ b/include/linux/printk.h @@ -197,6 +197,7 @@ extern asmlinkage void dump_stack(void) __cold; void printk_trigger_flush(void); extern bool nbcon_device_try_acquire(struct console *con); extern void nbcon_device_release(struct console *con); +void nbcon_atomic_flush_unsafe(void); #else static inline __printf(1, 0) int vprintk(const char *s, va_list args) @@ -286,6 +287,10 @@ static inline void nbcon_device_release(struct console= *con) { } =20 +static inline void nbcon_atomic_flush_unsafe(void) +{ +} + #endif =20 bool this_cpu_in_panic(void); diff --git a/kernel/panic.c b/kernel/panic.c index f22d8f33ea14..c039f8e1ddae 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -453,6 +453,7 @@ void panic(const char *fmt, ...) * Explicitly flush the kernel log buffer one last time. */ console_flush_on_panic(CONSOLE_FLUSH_PENDING); + nbcon_atomic_flush_unsafe(); =20 local_irq_enable(); for (i =3D 0; ; i +=3D PANIC_TIMER_STEP) { diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c index f6fbcf6d80fa..67a2a73a1aaf 100644 --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c @@ -1044,6 +1044,7 @@ bool nbcon_legacy_emit_next_record(struct console *co= n, bool *handover, * write_atomic() callback * @con: The nbcon console to flush * @stop_seq: Flush up until this record + * @allow_unsafe_takeover: True, to allow unsafe hostile takeovers * * Return: 0 if @con was flushed up to @stop_seq Otherwise, error code on * failure. @@ -1062,7 +1063,8 @@ bool nbcon_legacy_emit_next_record(struct console *co= n, bool *handover, * returned, it cannot be expected that the unfinalized record will become * available. */ -static int __nbcon_atomic_flush_pending_con(struct console *con, u64 stop_= seq) +static int __nbcon_atomic_flush_pending_con(struct console *con, u64 stop_= seq, + bool allow_unsafe_takeover) { struct nbcon_write_context wctxt =3D { }; struct nbcon_context *ctxt =3D &ACCESS_PRIVATE(&wctxt, ctxt); @@ -1071,6 +1073,7 @@ static int __nbcon_atomic_flush_pending_con(struct co= nsole *con, u64 stop_seq) ctxt->console =3D con; ctxt->spinwait_max_us =3D 2000; ctxt->prio =3D nbcon_get_default_prio(); + ctxt->allow_unsafe_takeover =3D allow_unsafe_takeover; =20 if (!nbcon_context_try_acquire(ctxt)) return -EPERM; @@ -1101,13 +1104,15 @@ static int __nbcon_atomic_flush_pending_con(struct = console *con, u64 stop_seq) * write_atomic() callback * @con: The nbcon console to flush * @stop_seq: Flush up until this record + * @allow_unsafe_takeover: True, to allow unsafe hostile takeovers * * This will stop flushing before @stop_seq if another context has ownersh= ip. * That context is then responsible for the flushing. Likewise, if new rec= ords * are added while this context was flushing and there is no other context * to handle the printing, this context must also flush those records. */ -static void nbcon_atomic_flush_pending_con(struct console *con, u64 stop_s= eq) +static void nbcon_atomic_flush_pending_con(struct console *con, u64 stop_s= eq, + bool allow_unsafe_takeover) { unsigned long flags; int err; @@ -1121,7 +1126,7 @@ static void nbcon_atomic_flush_pending_con(struct con= sole *con, u64 stop_seq) */ local_irq_save(flags); =20 - err =3D __nbcon_atomic_flush_pending_con(con, stop_seq); + err =3D __nbcon_atomic_flush_pending_con(con, stop_seq, allow_unsafe_take= over); =20 local_irq_restore(flags); =20 @@ -1151,8 +1156,9 @@ static void nbcon_atomic_flush_pending_con(struct con= sole *con, u64 stop_seq) * __nbcon_atomic_flush_pending - Flush all nbcon consoles using their * write_atomic() callback * @stop_seq: Flush up until this record + * @allow_unsafe_takeover: True, to allow unsafe hostile takeovers */ -static void __nbcon_atomic_flush_pending(u64 stop_seq) +static void __nbcon_atomic_flush_pending(u64 stop_seq, bool allow_unsafe_t= akeover) { struct console *con; int cookie; @@ -1170,7 +1176,7 @@ static void __nbcon_atomic_flush_pending(u64 stop_seq) if (nbcon_seq_read(con) >=3D stop_seq) continue; =20 - nbcon_atomic_flush_pending_con(con, stop_seq); + nbcon_atomic_flush_pending_con(con, stop_seq, allow_unsafe_takeover); } console_srcu_read_unlock(cookie); } @@ -1185,7 +1191,19 @@ static void __nbcon_atomic_flush_pending(u64 stop_se= q) */ void nbcon_atomic_flush_pending(void) { - __nbcon_atomic_flush_pending(prb_next_reserve_seq(prb)); + __nbcon_atomic_flush_pending(prb_next_reserve_seq(prb), false); +} + +/** + * nbcon_atomic_flush_unsafe - Flush all nbcon consoles using their + * write_atomic() callback and allowing unsafe hostile takeovers + * + * Flush the backlog up through the currently newest record. Unsafe hostile + * takeovers will be performed, if necessary. + */ +void nbcon_atomic_flush_unsafe(void) +{ + __nbcon_atomic_flush_pending(prb_next_reserve_seq(prb), true); } =20 /** @@ -1315,7 +1333,7 @@ void nbcon_device_release(struct console *con) cookie =3D console_srcu_read_lock(); if (console_is_usable(con, console_srcu_read_flags(con)) && prb_read_valid(prb, nbcon_seq_read(con), NULL)) { - __nbcon_atomic_flush_pending_con(con, prb_next_reserve_seq(prb)); + __nbcon_atomic_flush_pending_con(con, prb_next_reserve_seq(prb), false); } console_srcu_read_unlock(cookie); } --=20 2.39.2 From nobody Fri Feb 13 13:25:47 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 AF1026A347 for ; Mon, 27 May 2024 06:38:26 +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=1716791908; cv=none; b=ZA8pXzV34ObXwYE4zQsxxPGewOQdBwMwcWBVON69ORbHiI59zdKyE9PxgLg0ky6Lpoh0yyc5p7ORMGFUonoxq0DjWAMNxJWmaSOi++YmOrXIYPoI3rhsx+dZPLJItcqNyBRz7frLrjN7aNnsGOIl/o1kaZWKDBOmcN9wuXdCBn4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716791908; c=relaxed/simple; bh=Rd0t6WNNNckIBVkHKjfeD6/vzFKHe00qBLlxBSoqArE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=gl1G/69Ms+uTuOkyzwW9A0gXuziOQ8DgWzGQV/8p9CzjmvJnZBTw+4/pWojfB6/xpHrhBoH4T8XznsgBKkYqiQKqPni3YWdEIVjiSUIyPrQj3jE0198XvmvQ+jWQ3jjeho7ywiE/41hk6INedo6QAenHX1DQqUfKSurP6PwhU5w= 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=i78GElMR; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=1Ue4W54J; 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="i78GElMR"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="1Ue4W54J" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1716791905; 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=1K8de/y+g8Dnqh1KWpBj2+5OXJyql0b3Ov26lWETiB8=; b=i78GElMRqal8B/krWZI7qtrfYERKYX5kbXYLMuGNadiKytQ6BFRxLii+u/ppQxC96ejVrL To8uh5iYbi3iOq6JgpW5n3FCSOmqml80tmpTTKmev87i8vCAxTCj9YDiUYcQMXVFu/7KVM RI9+Pwz9oqRJD864nA+5lnUAufqkbQtaCKEazJu5WNAgC85f1husG+OndCnfUyUrBWBn42 npAK4hcxXtkXH+BFf9XQqV91YpcCaSPcIwciA5neYsQMk+UIhUpiZ3o0jVfiFG7p+mqBIH EUmYi4YRdVjvgy/UmnzxaNjlRBH5HIVhU5fqJWfTQObBQBXdITPtSO7x8CTTAA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1716791905; 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=1K8de/y+g8Dnqh1KWpBj2+5OXJyql0b3Ov26lWETiB8=; b=1Ue4W54JWCzZD4Cyy+i508KQtWOk/KRzTr2CeHrSDvmUo83fTftg9LmyLbCTLvNXckt5ob TEbCSg7GPa+tWmDw== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v6 23/30] printk: Avoid console_lock dance if no legacy or boot consoles Date: Mon, 27 May 2024 08:43:42 +0206 Message-Id: <20240527063749.391035-24-john.ogness@linutronix.de> In-Reply-To: <20240527063749.391035-1-john.ogness@linutronix.de> References: <20240527063749.391035-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" Currently the console lock is used to attempt legacy-type printing even if there are no legacy or boot consoles registered. If no such consoles are registered, the console lock does not need to be taken. Add tracking of legacy console registration and use it with boot console tracking to avoid unnecessary code paths, i.e. do not use the console lock if there are no boot consoles and no legacy consoles. Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- kernel/printk/printk.c | 78 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 63 insertions(+), 15 deletions(-) diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 9a7532cff8d2..f00192df84f0 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -463,6 +463,13 @@ static int console_msg_format =3D MSG_FORMAT_DEFAULT; /* syslog_lock protects syslog_* variables and write access to clear_seq. = */ static DEFINE_MUTEX(syslog_lock); =20 +/* + * Specifies if a legacy console is registered. If legacy consoles are + * present, it is necessary to perform the console lock/unlock dance + * whenever console flushing should occur. + */ +static bool have_legacy_console; + /* * Specifies if a boot console is registered. If boot consoles are present, * nbcon consoles cannot print simultaneously and must be synchronized by @@ -471,6 +478,14 @@ static DEFINE_MUTEX(syslog_lock); */ static bool have_boot_console; =20 +/* + * Specifies if the console lock/unlock dance is needed for console + * printing. If @have_boot_console is true, the nbcon consoles will + * be printed serially along with the legacy consoles because nbcon + * consoles cannot print simultaneously with boot consoles. + */ +#define printing_via_unlock (have_legacy_console || have_boot_console) + #ifdef CONFIG_PRINTK DECLARE_WAIT_QUEUE_HEAD(log_wait); /* All 3 protected by @syslog_lock. */ @@ -2339,7 +2354,7 @@ asmlinkage int vprintk_emit(int facility, int level, printed_len =3D vprintk_store(facility, level, dev_info, fmt, args); =20 /* If called from the scheduler, we can not call up(). */ - if (!in_sched) { + if (!in_sched && printing_via_unlock) { /* * The caller may be holding system-critical or * timing-sensitive locks. Disable preemption during @@ -2648,7 +2663,7 @@ void resume_console(void) */ static int console_cpu_notify(unsigned int cpu) { - if (!cpuhp_tasks_frozen) { + if (!cpuhp_tasks_frozen && printing_via_unlock) { /* If trylock fails, someone else is doing the printing */ if (console_trylock()) console_unlock(); @@ -3189,7 +3204,8 @@ void console_flush_on_panic(enum con_flush_mode mode) =20 nbcon_atomic_flush_pending(); =20 - console_flush_all(false, &next_seq, &handover); + if (printing_via_unlock) + console_flush_all(false, &next_seq, &handover); } =20 /* @@ -3524,6 +3540,7 @@ void register_console(struct console *newcon) if (newcon->flags & CON_NBCON) { nbcon_init(newcon, init_seq); } else { + have_legacy_console =3D true; newcon->seq =3D init_seq; } =20 @@ -3600,6 +3617,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 found_legacy_con =3D false; bool found_boot_con =3D false; unsigned long flags; struct console *c; @@ -3667,9 +3685,13 @@ static int unregister_console_locked(struct console = *console) for_each_console(c) { if (c->flags & CON_BOOT) found_boot_con =3D true; + if (!(c->flags & CON_NBCON)) + found_legacy_con =3D true; } if (!found_boot_con) have_boot_console =3D found_boot_con; + if (!found_legacy_con) + have_legacy_console =3D found_legacy_con; =20 return res; } @@ -3830,22 +3852,34 @@ static bool __pr_flush(struct console *con, int tim= eout_ms, bool reset_on_progre seq =3D prb_next_reserve_seq(prb); =20 /* Flush the consoles so that records up to @seq are printed. */ - console_lock(); - console_unlock(); + if (printing_via_unlock) { + console_lock(); + console_unlock(); + } =20 for (;;) { unsigned long begin_jiffies; unsigned long slept_jiffies; - - diff =3D 0; + bool use_console_lock =3D printing_via_unlock; =20 /* - * Hold the console_lock to guarantee safe access to - * console->seq. Releasing console_lock flushes more - * records in case @seq is still not printed on all - * usable consoles. + * Ensure the compiler does not optimize @use_console_lock to + * be @printing_via_unlock since the latter can change at any + * time. */ - console_lock(); + barrier(); + + diff =3D 0; + + if (use_console_lock) { + /* + * Hold the console_lock to guarantee safe access to + * console->seq. Releasing console_lock flushes more + * records in case @seq is still not printed on all + * usable consoles. + */ + console_lock(); + } =20 cookie =3D console_srcu_read_lock(); for_each_console_srcu(c) { @@ -3865,6 +3899,7 @@ static bool __pr_flush(struct console *con, int timeo= ut_ms, bool reset_on_progre if (flags & CON_NBCON) { printk_seq =3D nbcon_seq_read(c); } else { + WARN_ON_ONCE(!use_console_lock); printk_seq =3D c->seq; } =20 @@ -3876,7 +3911,8 @@ static bool __pr_flush(struct console *con, int timeo= ut_ms, bool reset_on_progre if (diff !=3D last_diff && reset_on_progress) remaining_jiffies =3D timeout_jiffies; =20 - console_unlock(); + if (use_console_lock) + console_unlock(); =20 /* Note: @diff is 0 if there are no usable consoles. */ if (diff =3D=3D 0 || remaining_jiffies =3D=3D 0) @@ -3946,6 +3982,7 @@ static void __wake_up_klogd(int val) return; =20 preempt_disable(); + /* * Guarantee any new records can be seen by tasks preparing to wait * before this context checks if the wait queue is empty. @@ -3957,11 +3994,22 @@ static void __wake_up_klogd(int val) * * This pairs with devkmsg_read:A and syslog_print:A. */ - if (wq_has_sleeper(&log_wait) || /* LMM(__wake_up_klogd:A) */ - (val & PRINTK_PENDING_OUTPUT)) { + if (!wq_has_sleeper(&log_wait)) /* LMM(__wake_up_klogd:A) */ + val &=3D ~PRINTK_PENDING_WAKEUP; + + /* + * Simple read is safe. register_console() would flush a newly + * registered legacy console when writing the message about it + * being enabled. + */ + if (!printing_via_unlock) + val &=3D ~PRINTK_PENDING_OUTPUT; + + if (val) { this_cpu_or(printk_pending, val); irq_work_queue(this_cpu_ptr(&wake_up_klogd_work)); } + preempt_enable(); } =20 --=20 2.39.2 From nobody Fri Feb 13 13:25:47 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 1B00F12AAE6 for ; Mon, 27 May 2024 06:38:27 +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=1716791908; cv=none; b=iwIisfBmw5Mc+tK3VTz5yp6HbJOm8GDgQl9kHYtsZ+Jduli2pRhJIR95Ub0+jUw4QE3UNijfN/QHtmnqlSs1H0abkijkB7Hn1FDa7O11ntL80SnXIkSZ35wihf+RvoF0IudfIxBzMwSWEyGp3zJ7+Mllbyw07eGNeoTrVWhZfLc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716791908; c=relaxed/simple; bh=4RKVEs781vKO0XLRQyJczCVpAjrrp4EbG79nkZ1ZXBE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Q3LFh1htRLhdT3GxlxiWQhzNQNloMBgir6AiapIw05hUiBwZIC5+OJxtf8+Ku6qfqExlFWe0x6csGteMlM1CEMfoez1lNpAnTkYH0mQrBzo05Wz0idbWJ6re71vySa9XD+8JpaiqeZGct5ND2XynA9uEV0Qa1fxnhG2cDUAXaxU= 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=IYnxPmd2; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=B9d0IiLJ; 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="IYnxPmd2"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="B9d0IiLJ" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1716791905; 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=HaCLvchcvldjjGnfBDp+6tSZmLspUlNMwrj30z7kttw=; b=IYnxPmd2VzZl9g1Sy+Tbnx0TEjAnkRUOmm6s7igNYD7p3bC+Ya4frAuiIYIcDQl1IO7+mK EaAPqsRrnn+PdqVV44Ok74KWM7JgabqNxDyFB9irJTqPeg+rRxmSQvwMGJBPbYGjDNa+2T o7XdqVn9n+MQGjDOIJkjhEclJul0l7La1AElPG9aDz9R3ZbtQvAXmdgEdWT3spLd4zr3Fq 4a05ft4Go58BeXoWkV/nb8smlvcVW4Bk3rhMa/UqhZR9ARK0iX2qbqDnV327RZW7OJHR2k vmJQr98L/0LW7tyRujgUQXIfzVChw2C15FJwYKnfFOTmMfZ5GA1UqUQx37k5Qg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1716791905; 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=HaCLvchcvldjjGnfBDp+6tSZmLspUlNMwrj30z7kttw=; b=B9d0IiLJkMQZ2ejaVeCbflIRbOdSV1af2Q46SU963PBGq1EvNiuJrCFhEhaqCsEhJKh77C 3NMwCY1Wl+CzJkDg== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v6 24/30] printk: Track nbcon consoles Date: Mon, 27 May 2024 08:43:43 +0206 Message-Id: <20240527063749.391035-25-john.ogness@linutronix.de> In-Reply-To: <20240527063749.391035-1-john.ogness@linutronix.de> References: <20240527063749.391035-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" Add a global flag @have_nbcon_console to identify if any nbcon consoles are registered. This will be used in follow-up commits to preserve legacy behavior when no nbcon consoles are registered. Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- kernel/printk/printk.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index f00192df84f0..d087711242de 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -470,6 +470,11 @@ static DEFINE_MUTEX(syslog_lock); */ static bool have_legacy_console; =20 +/* + * Specifies if an nbcon console is registered. + */ +static bool have_nbcon_console; + /* * Specifies if a boot console is registered. If boot consoles are present, * nbcon consoles cannot print simultaneously and must be synchronized by @@ -3538,6 +3543,7 @@ void register_console(struct console *newcon) init_seq =3D get_init_console_seq(newcon, bootcon_registered); =20 if (newcon->flags & CON_NBCON) { + have_nbcon_console =3D true; nbcon_init(newcon, init_seq); } else { have_legacy_console =3D true; @@ -3618,6 +3624,7 @@ static int unregister_console_locked(struct console *= console) { bool use_device_lock =3D (console->flags & CON_NBCON) && console->write_a= tomic; bool found_legacy_con =3D false; + bool found_nbcon_con =3D false; bool found_boot_con =3D false; unsigned long flags; struct console *c; @@ -3685,13 +3692,18 @@ static int unregister_console_locked(struct console= *console) for_each_console(c) { if (c->flags & CON_BOOT) found_boot_con =3D true; - if (!(c->flags & CON_NBCON)) + + if (c->flags & CON_NBCON) + found_nbcon_con =3D true; + else found_legacy_con =3D true; } if (!found_boot_con) have_boot_console =3D found_boot_con; if (!found_legacy_con) have_legacy_console =3D found_legacy_con; + if (!found_nbcon_con) + have_nbcon_console =3D found_nbcon_con; =20 return res; } --=20 2.39.2 From nobody Fri Feb 13 13:25:47 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 CDFF013A26F for ; Mon, 27 May 2024 06:38:27 +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=1716791910; cv=none; b=PAGjxy2EExmWML+G7/ugy/05z5kuOhK9TJAmJlX2iNf/7YgWAFvsz8KT1h+vk1nN53MOezoM7VreLwA8Vts8nb4wt34HGJTTYKmLJoEXmwRP+nyHr0pF/+4Td9wwbTtFGXKMY4WKCNjZb9bxuGtGJD02JQLAJrqdjp/dgHaB9d8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716791910; c=relaxed/simple; bh=OFWO2IRbRo8ynzt2DKXpmd6oX4CkmFfn02/npsx3lxQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=o7kNqmPQFEks8cLDRr4aNT2dmWce7oyz57+Q0LtiILBQlBghSfeRrILaRXT6FiZc/jXCc/pGYOT1C49OpjPo10cPFF0WuRkIIttVyHdGKkUs/nmxYO9hpv4cNd996z4k0L6acpnCAzdI7pdBUqgBKPJBso86bUxuPui7uQnKAKg= 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=Pcr/AejG; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=ujFHwQJC; 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="Pcr/AejG"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="ujFHwQJC" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1716791906; 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=VKsa/1j/hsc2hNgT7N6RhGj9XG+uFyRNJKfZ/KePOvo=; b=Pcr/AejGQ7hMb43qAB4NsL/348lGjh3T4gn4T9AVNyXvAxOdd7JTjKU5pKYtClspZzdr/D agZWBP8W8TngvGzeMTkKpy92JS+5m5XKaWuoKVD4keJehwXDhf2icmu4RfpliqgoYGNAwp cNXlEEFJMaZdRmlPiN0GBjcIk0tahAi6RXfPpMlwy60wI1WM66+UdArr+SNEbRhNuXHho1 NvZdyrzTXO5y9GMTRi/cIEEYXBU+eborb/+3g5RT5s8FLLfVkbJXW0j9xHwi5Unkam1+dv jo3q7fMJPdn/NJpGXGm1W44jeQKTulZK5WgqvqkjUHmNoaVM+HqJwjDMIR3XiA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1716791906; 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=VKsa/1j/hsc2hNgT7N6RhGj9XG+uFyRNJKfZ/KePOvo=; b=ujFHwQJCDxGCpxj7jemjrcGwkg3kn+mWScSViB9BLNiXyBUti68EC5RQoqLGrqNSRNIc8S p8G4lv/nosJZolBA== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Andrew Morton , Lukas Wunner , Uros Bizjak , Kefeng Wang , Arnd Bergmann Subject: [PATCH printk v6 25/30] printk: Coordinate direct printing in panic Date: Mon, 27 May 2024 08:43:44 +0206 Message-Id: <20240527063749.391035-26-john.ogness@linutronix.de> In-Reply-To: <20240527063749.391035-1-john.ogness@linutronix.de> References: <20240527063749.391035-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" Perform printing by nbcon consoles on the panic CPU from the printk() caller context in order to get panic messages printed as soon as possible. If legacy and nbcon consoles are registered, the legacy consoles will no longer perform direct printing on the panic CPU until after the backtrace has been stored. This will give the safe nbcon consoles a chance to print the panic messages before allowing the unsafe legacy consoles to print. If no nbcon consoles are registered, there is no change in behavior (i.e. legacy consoles will always attempt to print from the printk() caller context). Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- include/linux/printk.h | 5 ++++ kernel/panic.c | 2 ++ kernel/printk/printk.c | 62 ++++++++++++++++++++++++++++++++++++------ 3 files changed, 61 insertions(+), 8 deletions(-) diff --git a/include/linux/printk.h b/include/linux/printk.h index 4d93d95cd5f0..69f40a71c438 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 printk_legacy_allow_panic_sync(void); extern bool nbcon_device_try_acquire(struct console *con); extern void nbcon_device_release(struct console *con); void nbcon_atomic_flush_unsafe(void); @@ -278,6 +279,10 @@ static inline void printk_trigger_flush(void) { } =20 +static inline void printk_legacy_allow_panic_sync(void) +{ +} + static inline bool nbcon_device_try_acquire(struct console *con) { return false; diff --git a/kernel/panic.c b/kernel/panic.c index c039f8e1ddae..de8115c829cf 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -364,6 +364,8 @@ void panic(const char *fmt, ...) =20 panic_other_cpus_shutdown(_crash_kexec_post_notifiers); =20 + printk_legacy_allow_panic_sync(); + /* * Run any panic handlers, including those that might need to * add information to the kmsg dump output. diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index d087711242de..57e190fbecd7 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -471,7 +471,9 @@ static DEFINE_MUTEX(syslog_lock); static bool have_legacy_console; =20 /* - * Specifies if an nbcon console is registered. + * Specifies if an nbcon console is registered. If nbcon consoles are pres= ent, + * synchronous printing of legacy consoles will not occur during panic unt= il + * the backtrace has been stored to the ringbuffer. */ static bool have_nbcon_console; =20 @@ -2330,12 +2332,29 @@ int vprintk_store(int facility, int level, return ret; } =20 +static bool legacy_allow_panic_sync; + +/* + * This acts as a one-way switch to allow legacy consoles to print from + * the printk() caller context on a panic CPU. It also attempts to flush + * the legacy consoles in this context. + */ +void printk_legacy_allow_panic_sync(void) +{ + legacy_allow_panic_sync =3D true; + + if (printing_via_unlock && !in_nmi()) { + if (console_trylock()) + console_unlock(); + } +} + 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; int printed_len; - bool in_sched =3D false; =20 /* Suppress unimportant messages after panic happens */ if (unlikely(suppress_printk)) @@ -2351,15 +2370,42 @@ asmlinkage int vprintk_emit(int facility, int level, =20 if (level =3D=3D LOGLEVEL_SCHED) { level =3D LOGLEVEL_DEFAULT; - in_sched =3D true; + /* If called from the scheduler, we can not call up(). */ + do_trylock_unlock =3D false; } =20 printk_delay(level); =20 printed_len =3D vprintk_store(facility, level, dev_info, fmt, args); =20 - /* If called from the scheduler, we can not call up(). */ - if (!in_sched && printing_via_unlock) { + if (have_nbcon_console && !have_boot_console) { + bool is_panic_context =3D this_cpu_in_panic(); + + /* + * In panic, the legacy consoles are not allowed to print from + * the printk calling context unless explicitly allowed. This + * gives the safe nbcon consoles a chance to print out all the + * panic messages first. This restriction only applies if + * there are nbcon consoles registered. + */ + if (is_panic_context) + do_trylock_unlock &=3D legacy_allow_panic_sync; + + /* + * There are situations where nbcon atomic printing should + * happen in the printk() caller context: + * + * - When this CPU is in panic. + * + * 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) + nbcon_atomic_flush_pending(); + } + + if (do_trylock_unlock) { /* * The caller may be holding system-critical or * timing-sensitive locks. Disable preemption during @@ -2379,10 +2425,10 @@ asmlinkage int vprintk_emit(int facility, int level, preempt_enable(); } =20 - if (in_sched) - defer_console_output(); - else + if (do_trylock_unlock) wake_up_klogd(); + else + defer_console_output(); =20 return printed_len; } --=20 2.39.2 From nobody Fri Feb 13 13:25:47 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 41AB413A3FE for ; Mon, 27 May 2024 06:38:27 +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=1716791910; cv=none; b=l2y8VGGCiN+Man9ksfihV5mmfQoBwaJcA0NrJS9hTH+V2SyQPL89b4ml3B0FmiogDlAe5vPcmbfKrj6nOfwLx+385bfywGs1OH1+xhAZK/clif3jDatElQgXOCYn7clNM8EReytQZX/MeDvucILvwZwK1rECceiRICUnuGo3GoU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716791910; c=relaxed/simple; bh=AcaXIehwkrC7oSMnVU4pqyFIUrE3I7QOjHEIvDejEww=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=UwGChZO7KN5QbryyIvJKdl1xqyD53D3Xh50GRYMY4Ku/3fK40ePgN+TmTtrFN8I9k+fRU+2mr7YEqE6sq82cvHB+qVxwn5JrxSxln3Y46arVCAaXnmQDfu9x65qrHFVAKs3ojP/ziomjqZKFOXZsS8yf4eTRoSBNXfASvg0izy8= 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=ktm8CYU4; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=VrS+8W/X; 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="ktm8CYU4"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="VrS+8W/X" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1716791906; 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=GC3WEoPfSa5I25Dvpbsqwg+xsmG6i0ZBrHfYfar8GTQ=; b=ktm8CYU4+B/OYB6H08c7lFUKiyScuhcLKOrdd65GJ729nGmdd/3a5X/hXosaejHDq1h4JD e3gCDQbqAlxqz4DI3+OlsB6eJGdQ76g3JVnQ0vrAafr51nCqrhkGDv68C+AP4ZsMR0+A8l NaNrjG0yo4qJzrmkYdyqRGakgoJZWkk++EJgBKp9SHwdOo81Crc2Ftms96xYh9GY9Pnuh5 Nj11hGu38RCXVKJkvNqkzRTPQ3eQXv4Iexq3uvuquO106j+UEVx9migX3TtpF0/TZlBYOW Wz7zWk6YNa3G96rk+EP8Spe8q/PcHm6u7/9varDLfuCac+sHAp0qV2RGunGv1g== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1716791906; 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=GC3WEoPfSa5I25Dvpbsqwg+xsmG6i0ZBrHfYfar8GTQ=; b=VrS+8W/Xu826Qge6TC/fFZuA8Zjqz8IsrN0hrtkJxuN3nGmF5mQr5AWdKDaJDc8aOahrqO cM3i8DXsyD1A4EDA== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Greg Kroah-Hartman Subject: [PATCH printk v6 26/30] printk: nbcon: Implement emergency sections Date: Mon, 27 May 2024 08:43:45 +0206 Message-Id: <20240527063749.391035-27-john.ogness@linutronix.de> In-Reply-To: <20240527063749.391035-1-john.ogness@linutronix.de> References: <20240527063749.391035-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 In emergency situations (something has gone wrong but the system continues to operate), usually important information (such as a backtrace) is generated via printk(). Each individual printk record has little meaning. It is the collection of printk messages that is most often needed by developers and users. In order to help ensure that the collection of printk messages in an emergency situation are all stored to the ringbuffer as quickly as possible, disable console output for that CPU while it is in the emergency situation. The consoles need to be flushed when exiting the emergency situation. Add per-CPU emergency nesting tracking because an emergency can arise while in an emergency situation. Add functions to mark the beginning and end of emergency sections where the urgent messages are generated. Do not print if the current CPU is in an emergency state. When exiting all emergency nesting, flush nbcon consoles directly using their atomic callback. Legacy consoles are flushed directly if safe, otherwise they are triggered for flushing via irq_work. Note that the emergency state is not system-wide. While one CPU is in an emergency state, another CPU may continue to print console messages. Co-developed-by: John Ogness Signed-off-by: John Ogness Signed-off-by: Thomas Gleixner (Intel) --- include/linux/console.h | 6 ++ kernel/printk/internal.h | 13 ++++ kernel/printk/nbcon.c | 126 ++++++++++++++++++++++++++++++++++++ kernel/printk/printk.c | 25 +++---- kernel/printk/printk_safe.c | 11 +++- 5 files changed, 168 insertions(+), 13 deletions(-) diff --git a/include/linux/console.h b/include/linux/console.h index 729f7c3b10c1..f1463c1dd9c1 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -535,10 +535,16 @@ static inline bool console_is_registered(const struct= console *con) hlist_for_each_entry(con, &console_list, node) =20 #ifdef CONFIG_PRINTK +extern void nbcon_cpu_emergency_enter(void); +extern void nbcon_cpu_emergency_exit(void); +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); #else +static inline void nbcon_cpu_emergency_enter(void) { } +static inline void nbcon_cpu_emergency_exit(void) { } +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; } diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h index 91bc0ee43f8d..0439cf2fdc22 100644 --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h @@ -76,6 +76,8 @@ bool printk_percpu_data_ready(void); =20 void defer_console_output(void); =20 +bool is_printk_deferred(void); + u16 printk_parse_prefix(const char *text, int *level, enum printk_info_flags *flags); void console_lock_spinning_enable(void); @@ -153,6 +155,17 @@ static inline bool console_is_usable(struct console *c= on, short flags) { return =20 #endif /* CONFIG_PRINTK */ =20 +extern bool have_boot_console; +extern bool have_legacy_console; + +/* + * Specifies if the console lock/unlock dance is needed for console + * printing. If @have_boot_console is true, the nbcon consoles will + * be printed serially along with the legacy consoles because nbcon + * consoles cannot print simultaneously with boot consoles. + */ +#define printing_via_unlock (have_legacy_console || have_boot_console) + extern struct printk_buffers printk_shared_pbufs; =20 /** diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c index 67a2a73a1aaf..6e9e24aa0a7f 100644 --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c @@ -936,6 +936,29 @@ static bool nbcon_emit_next_record(struct nbcon_write_= context *wctxt) return nbcon_context_exit_unsafe(ctxt); } =20 +/* 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; + +/** + * nbcon_get_cpu_emergency_nesting - Get the per CPU emergency nesting poi= nter + * + * Return: Either a pointer to the per CPU emergency nesting counter of + * the current CPU or to the init data during early boot. + */ +static __ref unsigned int *nbcon_get_cpu_emergency_nesting(void) +{ + /* + * The value of __printk_percpu_data_ready gets set in normal + * context and before SMP initialization. As a result it could + * never change while inside an nbcon emergency section. + */ + if (!printk_percpu_data_ready()) + return &early_nbcon_pcpu_emergency_nesting; + + return this_cpu_ptr(&nbcon_pcpu_emergency_nesting); +} + /** * nbcon_get_default_prio - The appropriate nbcon priority to use for nbcon * printing on the current CPU @@ -946,9 +969,15 @@ static bool nbcon_emit_next_record(struct nbcon_write_= context *wctxt) */ enum nbcon_prio nbcon_get_default_prio(void) { + unsigned int *cpu_emergency_nesting; + if (this_cpu_in_panic()) return NBCON_PRIO_PANIC; =20 + cpu_emergency_nesting =3D nbcon_get_cpu_emergency_nesting(); + if (*cpu_emergency_nesting) + return NBCON_PRIO_EMERGENCY; + return NBCON_PRIO_NORMAL; } =20 @@ -1206,6 +1235,103 @@ void nbcon_atomic_flush_unsafe(void) __nbcon_atomic_flush_pending(prb_next_reserve_seq(prb), true); } =20 +/** + * nbcon_cpu_emergency_enter - Enter an emergency section where printk() + * messages for that CPU are only stored + * + * Upon exiting the emergency section, all stored messages are flushed. + * + * Context: Any context. Disables preemption. + * + * When within an emergency section, no printing occurs on that CPU. This + * is to allow all emergency messages to be dumped into the ringbuffer bef= ore + * flushing the ringbuffer. The actual printing occurs when exiting the + * outermost emergency section. + */ +void nbcon_cpu_emergency_enter(void) +{ + unsigned int *cpu_emergency_nesting; + + preempt_disable(); + + cpu_emergency_nesting =3D nbcon_get_cpu_emergency_nesting(); + (*cpu_emergency_nesting)++; +} + +/** + * nbcon_cpu_emergency_exit - Exit an emergency section and flush the + * stored messages + * + * Flushing only occurs when exiting all nesting for the CPU. + * + * Context: Any context. Enables preemption. + */ +void nbcon_cpu_emergency_exit(void) +{ + unsigned int *cpu_emergency_nesting; + bool do_trigger_flush =3D false; + + cpu_emergency_nesting =3D nbcon_get_cpu_emergency_nesting(); + + /* + * Flush the messages before enabling preemtion to see them ASAP. + * + * Reduce the risk of potential softlockup by using the + * flush_pending() variant which ignores messages added later. It is + * called before decrementing the counter so that the printing context + * for the emergency messages is NBCON_PRIO_EMERGENCY. + */ + if (*cpu_emergency_nesting =3D=3D 1) { + nbcon_atomic_flush_pending(); + + /* + * Safely attempt to flush the legacy consoles in this + * context. Otherwise an irq_work context is triggered + * to handle it. + */ + do_trigger_flush =3D true; + if (printing_via_unlock && !is_printk_deferred()) { + if (console_trylock()) { + do_trigger_flush =3D false; + console_unlock(); + } + } + } + + if (!WARN_ON_ONCE(*cpu_emergency_nesting =3D=3D 0)) + (*cpu_emergency_nesting)--; + + preempt_enable(); + + if (do_trigger_flush) + printk_trigger_flush(); +} + +/** + * nbcon_cpu_emergency_flush - Explicitly flush consoles while + * within emergency context + * + * Both nbcon and legacy consoles are flushed. + * + * It should be used only when there are too many messages printed + * in emergency context, for example, printing backtraces of all + * CPUs or processes. It is typically needed when the watchdogs + * need to be touched as well. + */ +void nbcon_cpu_emergency_flush(void) +{ + /* The explicit flush is needed only in the emergency context. */ + if (*(nbcon_get_cpu_emergency_nesting()) =3D=3D 0) + return; + + nbcon_atomic_flush_pending(); + + if (printing_via_unlock && !is_printk_deferred()) { + if (console_trylock()) + console_unlock(); + } +} + /** * nbcon_alloc - Allocate buffers needed by the nbcon console * @con: Console to allocate buffers for diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 57e190fbecd7..c623f9ce9b7b 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -468,7 +468,7 @@ static DEFINE_MUTEX(syslog_lock); * present, it is necessary to perform the console lock/unlock dance * whenever console flushing should occur. */ -static bool have_legacy_console; +bool have_legacy_console; =20 /* * Specifies if an nbcon console is registered. If nbcon consoles are pres= ent, @@ -483,15 +483,7 @@ static bool have_nbcon_console; * the console lock. This is because boot consoles and nbcon consoles may * have mapped the same hardware. */ -static bool have_boot_console; - -/* - * Specifies if the console lock/unlock dance is needed for console - * printing. If @have_boot_console is true, the nbcon consoles will - * be printed serially along with the legacy consoles because nbcon - * consoles cannot print simultaneously with boot consoles. - */ -#define printing_via_unlock (have_legacy_console || have_boot_console) +bool have_boot_console; =20 #ifdef CONFIG_PRINTK DECLARE_WAIT_QUEUE_HEAD(log_wait); @@ -2412,16 +2404,25 @@ asmlinkage int vprintk_emit(int facility, int level, * printing of all remaining records to all consoles so that * this context can return as soon as possible. Hopefully * another printk() caller will take over the printing. + * + * Also, nbcon_get_default_prio() requires migration disabled. */ preempt_disable(); + /* * Try to acquire and then immediately release the console * semaphore. The release will print out buffers. With the * spinning variant, this context tries to take over the * printing from another printing context. + * + * Skip it in EMERGENCY priority. The console will be + * explicitly flushed when exiting the emergency section. */ - if (console_trylock_spinning()) - console_unlock(); + if (nbcon_get_default_prio() !=3D NBCON_PRIO_EMERGENCY) { + if (console_trylock_spinning()) + console_unlock(); + } + preempt_enable(); } =20 diff --git a/kernel/printk/printk_safe.c b/kernel/printk/printk_safe.c index 4421ccac3113..f47fef701265 100644 --- a/kernel/printk/printk_safe.c +++ b/kernel/printk/printk_safe.c @@ -38,6 +38,15 @@ void __printk_deferred_exit(void) __printk_safe_exit(); } =20 +bool is_printk_deferred(void) +{ + /* + * The per-CPU variable @printk_context can be read safely in any + * context. The CPU migration always disabled when set. + */ + return (this_cpu_read(printk_context) || in_nmi()); +} + asmlinkage int vprintk(const char *fmt, va_list args) { #ifdef CONFIG_KGDB_KDB @@ -50,7 +59,7 @@ 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()) + if (is_printk_deferred()) return vprintk_deferred(fmt, args); =20 /* No obstacles. */ --=20 2.39.2 From nobody Fri Feb 13 13:25:47 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 B9C4313A890 for ; Mon, 27 May 2024 06:38:28 +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=1716791910; cv=none; b=bEXLiC6n6Yuw9IXFwLyAi+SSFshpdAJOGVVCxkXwnFC6USWbDLk01+UuPf1ytofXE135baL0OCUSuiY5vNow6qshpki+wdK9pv1XVC/gQo29lu0OS31vfeziPLzbVDcIAOABOy4jSbzHc4chlp150fMvUzeFk+IsB5/PZot6cQ4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716791910; c=relaxed/simple; bh=sIDwBVtEZ9II9z34FVW/arDvGAYqJE9qC2xSXnoiiY8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=SNHojcFJHH18EWfVvMN2COeK1DJ1aU+Fl6/mqMRILfDKAysSSjw7T3JeOeJHX0VS4VkETGh6OD4zd0f5sHub8hMyFsik59fM2Rk4BweNiSiuuRkM97RPmJ+BeiKv4RtfjJpmRNZzgUJkrqKtxBhwdP6dj7fHVV+7MHey1XKkrvc= 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=aYKL3EDM; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=DoZ/Rjz/; 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="aYKL3EDM"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="DoZ/Rjz/" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1716791907; 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=02mlGKrKUI3gQEB07A6y9zFTpJYkffg7XWV4RkY45mg=; b=aYKL3EDMXfEN5u/BkUloG96mutWZq+ZZ3GeBeND/InbJGzc5EnHbsePE/NpwThihtR6Vhg puXFNVoM0uOPbwIfHvqs1ebeGgAqdw3VXdJWbBvQu4mpWqUZBg/d2tdnQmp2wfSgJcp2jZ NjYDP6n6gg9s9TvsxVBcStU0AZ1dZ7kJ+pKz1h/wUmzThq5VLmQLyaorznGhZaKDHhyVNe iq/Kbs6sC4YZsWOjXtW/GhQ9mGzCkC3Qd0wCHIIxPkuzrm1zqjvW9ouu/FWC88PMgW4txo H3OBJW7ehFmb9jaEcgF1m0AEjBwBPgVTS3zhu7Ds6SwiIA/SmEpwqxNqdmSjRw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1716791907; 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=02mlGKrKUI3gQEB07A6y9zFTpJYkffg7XWV4RkY45mg=; b=DoZ/Rjz/SfznAeRULibeob0mkM4fpJHPWg3TxM8CdhkJ8PfklVRabiYNlhirPCEGqarBwn 9ywtzurOjt4ZM3AQ== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Andrew Morton , Arnd Bergmann , Lukas Wunner , Uros Bizjak , Kefeng Wang Subject: [PATCH printk v6 27/30] panic: Mark emergency section in warn Date: Mon, 27 May 2024 08:43:46 +0206 Message-Id: <20240527063749.391035-28-john.ogness@linutronix.de> In-Reply-To: <20240527063749.391035-1-john.ogness@linutronix.de> References: <20240527063749.391035-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 Mark the full contents of __warn() as an emergency section. In this section, the CPU will not perform console output for the printk() calls. Instead, a flushing of the console output is triggered when exiting the emergency section. Co-developed-by: John Ogness Signed-off-by: John Ogness Signed-off-by: Thomas Gleixner (Intel) Reviewed-by: Petr Mladek --- kernel/panic.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/panic.c b/kernel/panic.c index de8115c829cf..ee03193f9495 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -667,6 +667,8 @@ struct warn_args { void __warn(const char *file, int line, void *caller, unsigned taint, struct pt_regs *regs, struct warn_args *args) { + nbcon_cpu_emergency_enter(); + disable_trace_on_warning(); =20 if (file) @@ -697,6 +699,8 @@ void __warn(const char *file, int line, void *caller, u= nsigned taint, =20 /* Just a warning, don't kill lockdep. */ add_taint(taint, LOCKDEP_STILL_OK); + + nbcon_cpu_emergency_exit(); } =20 #ifdef CONFIG_BUG --=20 2.39.2 From nobody Fri Feb 13 13:25:47 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 EE03B13AA2D for ; Mon, 27 May 2024 06:38:28 +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=1716791910; cv=none; b=rSjK8dwn/1if+oyYZ057HHa3Il+28gOq5509ABnNAJBgPQVR0XOaLAz2dPm+Z6azHLMkxf/HkEQVjM48rFEz9qf5Q4UpGEZCx8nuPT1rBYV6DQzRh+qXBnOHk8XStuSFUeBPxzLw0WleOmFUEtm/1uj4oba6PcKxndZGA5KkCW0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716791910; c=relaxed/simple; bh=ApV3BrzIy3FzvWp+ns3WoghCqTJI0MOJzDStPgz0cJY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=px8XYre+nIXyap7zpBfy2adVlEXlIQfT3bJDCTinxI/ZEWzON0ECAPRSKd4uNaKbAOq1VgA9DM3hxWWk9qLkIjAFhrpC2wlPqafVph+KAbKGsWf7QQvsfxA7Mx0lpgnN440FxalLEx0xE20N0+OBgk6dSeuaLuay8CUCIuXT4dg= 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=xKwVz7Ri; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=TorGkXxy; 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="xKwVz7Ri"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="TorGkXxy" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1716791907; 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=Ypq720fklC/HaR4UTxfPN0fK1+MPpff79Yq5uFGIqB0=; b=xKwVz7RiSbkQ6LlCzh2pdMGlVTnTHcm80TDxjCbg98R66FcxTCVE276nR9ikUB3MgWLi+w dT2csWpy4EYXIbqxSZcPUqMqbiI6Lqr13wXPJ9OcuuANggqPvo2Y6CFK76j9mm/9WYxeHM r0CME2p0PREryWHTPXTcWis6lPEUd8HKOZs+5K1EJ4I8qjijhAdsN4u6uoWwnIU/2Z0M6w SlHMCl9E0AfmaDeqmCkYdwxMX8ktmV3DqlGAG0jp3b/zyLOvqW9JvCSCBZj/QGtTIFjDni GqZHtLyUcuIJqhpay/2cv8L7eTEK/WH5COJ9sFKZgJM9QzvV7B28mNOhLeGVIA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1716791907; 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=Ypq720fklC/HaR4UTxfPN0fK1+MPpff79Yq5uFGIqB0=; b=TorGkXxyqExrWA7fo16ISDGIhpNuo1sMGn4Cc0BBLveKqmAuU3HBCaF6DxM3YmyjGqd127 a46Oi2RTTYvIFPAA== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Andrew Morton , Ingo Molnar , Arnd Bergmann , Uros Bizjak , Kefeng Wang Subject: [PATCH printk v6 28/30] panic: Mark emergency section in oops Date: Mon, 27 May 2024 08:43:47 +0206 Message-Id: <20240527063749.391035-29-john.ogness@linutronix.de> In-Reply-To: <20240527063749.391035-1-john.ogness@linutronix.de> References: <20240527063749.391035-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" Mark an emergency section beginning with oops_enter() until the end of oops_exit(). In this section, the CPU will not perform console output for the printk() calls. Instead, a flushing of the console output is triggered when exiting the emergency section. The very end of oops_exit() performs a kmsg_dump(). This is not included in the emergency section because it is another flushing mechanism that should occur after the consoles have been triggered to flush. Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- kernel/panic.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/panic.c b/kernel/panic.c index ee03193f9495..3754a2471b4f 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -634,6 +634,7 @@ bool oops_may_print(void) */ void oops_enter(void) { + nbcon_cpu_emergency_enter(); tracing_off(); /* can't trust the integrity of the kernel anymore: */ debug_locks_off(); @@ -656,6 +657,7 @@ void oops_exit(void) { do_oops_enter_exit(); print_oops_end_marker(); + nbcon_cpu_emergency_exit(); kmsg_dump(KMSG_DUMP_OOPS); } =20 --=20 2.39.2 From nobody Fri Feb 13 13:25:47 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 911DC13AD09; Mon, 27 May 2024 06:38:29 +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=1716791911; cv=none; b=nFvMF/mo7vyeNwZEIvny/Au8GxyenH4/GNR2t7EDM2+uapgCF4+2UTkifEbN8RMtRY1OMsPiVC3FJyFJnYGckiFpPHlIh9/GBCD6hr87kYgxJQpkgggqKWbbxHFuVaBJ/tOHfu9VJHYMx9NyYoIpRHtpSlZnKr8Bjh/BVKdt9mw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716791911; c=relaxed/simple; bh=BVmTMTHIl4VcjgHY9wVIlpHojyLzzqPGNXbUpXRogjo=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=LddIvI77yyfWfWCQkkRFnJbSM+zYzuFjpjCOq8TL0x5wnAJBOx8aUcGp17HM5ujZX6xk/qk30uyYNIhUz7DNYCoeYn2cUQEHNTe54xWxBtsrTw4ZPqk4HdTgZUuTfDaTktyHNg1WrXL+dratjAfk68YReHYZxnGKMIOhmLxWid4= 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=AbFiw7CL; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=DqWpYgWn; 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="AbFiw7CL"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="DqWpYgWn" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1716791908; 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=BUJvi+cl+GnqVsi++YuWZL/DyNvN7UuVo3PX6B/yVfw=; b=AbFiw7CLQJ1nj4ywxswQa0dzSU2n+uowAMd95BAdErQTiLj35MbBTxJ8Rwv0LXw++ITn4d z5pH2QlZ9AaO4Zqyg3XFDAKzYODXH+N9tsqGwwEPQ5r5ZALIJtoi6Tlw3VFCWGTuHZ1AnU abb+ycMIEB5Eh68kIkANZc/4U4CveyjlNpdp+XR57G+tH+6bVXGRlRFDgiEhLiyI/78Cn8 4IwKuL125x2dK87X0uXNKD9EfGE7Eo48wyayFVG5peFp5OsYoEvFLZ9S0pYwjUSrpRGo7j uRdXrWqv3zKiumOUGHL5VrI+bfA7xzIzgZIuOG0wLZFwW6yMPCCST0cCEtGV8Q== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1716791908; 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=BUJvi+cl+GnqVsi++YuWZL/DyNvN7UuVo3PX6B/yVfw=; b=DqWpYgWnBbiXMTm9JFCIOFAqdixpYrPH/RlzRjAJc/jDdHZGMlbIQks2XV6NTzxHTcU1Pn uOSHzlQ2x8XykwAA== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, "Paul E. McKenney" , Frederic Weisbecker , Neeraj Upadhyay , Joel Fernandes , Josh Triplett , Boqun Feng , Mathieu Desnoyers , Lai Jiangshan , Zqiang , rcu@vger.kernel.org Subject: [PATCH printk v6 29/30] rcu: Mark emergency sections in rcu stalls Date: Mon, 27 May 2024 08:43:48 +0206 Message-Id: <20240527063749.391035-30-john.ogness@linutronix.de> In-Reply-To: <20240527063749.391035-1-john.ogness@linutronix.de> References: <20240527063749.391035-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" Mark emergency sections wherever multiple lines of rcu stall information are generated. In an emergency section the CPU will not perform console output for the printk() calls. Instead, a flushing of the console output is triggered when exiting the emergency section. This allows the full message block to be stored as quickly as possible in the ringbuffer. Signed-off-by: John Ogness --- kernel/rcu/tree_exp.h | 9 +++++++++ kernel/rcu/tree_stall.h | 11 +++++++++++ 2 files changed, 20 insertions(+) diff --git a/kernel/rcu/tree_exp.h b/kernel/rcu/tree_exp.h index 6b83537480b1..94457e36388f 100644 --- a/kernel/rcu/tree_exp.h +++ b/kernel/rcu/tree_exp.h @@ -7,6 +7,7 @@ * Authors: Paul E. McKenney */ =20 +#include #include =20 static void rcu_exp_handler(void *unused); @@ -571,6 +572,9 @@ static void synchronize_rcu_expedited_wait(void) return; if (rcu_stall_is_suppressed()) continue; + + nbcon_cpu_emergency_enter(); + j =3D jiffies; rcu_stall_notifier_call_chain(RCU_STALL_NOTIFY_EXP, (void *)(j - jiffies= _start)); trace_rcu_stall_warning(rcu_state.name, TPS("ExpeditedStall")); @@ -620,10 +624,14 @@ static void synchronize_rcu_expedited_wait(void) preempt_disable(); // For smp_processor_id() in dump_cpu_task(). dump_cpu_task(cpu); preempt_enable(); + nbcon_cpu_emergency_flush(); } rcu_exp_print_detail_task_stall_rnp(rnp); } jiffies_stall =3D 3 * rcu_exp_jiffies_till_stall_check() + 3; + + nbcon_cpu_emergency_exit(); + panic_on_rcu_stall(); } } @@ -792,6 +800,7 @@ static void rcu_exp_print_detail_task_stall_rnp(struct = rcu_node *rnp) */ touch_nmi_watchdog(); sched_show_task(t); + nbcon_cpu_emergency_flush(); } raw_spin_unlock_irqrestore_rcu_node(rnp, flags); } diff --git a/kernel/rcu/tree_stall.h b/kernel/rcu/tree_stall.h index 5d666428546b..1ca0826545c1 100644 --- a/kernel/rcu/tree_stall.h +++ b/kernel/rcu/tree_stall.h @@ -7,6 +7,7 @@ * Author: Paul E. McKenney */ =20 +#include #include #include =20 @@ -260,6 +261,7 @@ static void rcu_print_detail_task_stall_rnp(struct rcu_= node *rnp) */ touch_nmi_watchdog(); sched_show_task(t); + nbcon_cpu_emergency_flush(); } raw_spin_unlock_irqrestore_rcu_node(rnp, flags); } @@ -522,6 +524,7 @@ static void print_cpu_stall_info(int cpu) falsepositive ? " (false positive?)" : ""); =20 print_cpu_stat_info(cpu); + nbcon_cpu_emergency_flush(); } =20 /* Complain about starvation of grace-period kthread. */ @@ -604,6 +607,8 @@ static void print_other_cpu_stall(unsigned long gp_seq,= unsigned long gps) if (rcu_stall_is_suppressed()) return; =20 + nbcon_cpu_emergency_enter(); + /* * OK, time to rat on our buddy... * See Documentation/RCU/stallwarn.rst for info on how to debug @@ -655,6 +660,8 @@ static void print_other_cpu_stall(unsigned long gp_seq,= unsigned long gps) rcu_check_gp_kthread_expired_fqs_timer(); rcu_check_gp_kthread_starvation(); =20 + nbcon_cpu_emergency_exit(); + panic_on_rcu_stall(); =20 rcu_force_quiescent_state(); /* Kick them all. */ @@ -675,6 +682,8 @@ static void print_cpu_stall(unsigned long gps) if (rcu_stall_is_suppressed()) return; =20 + nbcon_cpu_emergency_enter(); + /* * OK, time to rat on ourselves... * See Documentation/RCU/stallwarn.rst for info on how to debug @@ -703,6 +712,8 @@ static void print_cpu_stall(unsigned long gps) jiffies + 3 * rcu_jiffies_till_stall_check() + 3); raw_spin_unlock_irqrestore_rcu_node(rnp, flags); =20 + nbcon_cpu_emergency_exit(); + panic_on_rcu_stall(); =20 /* --=20 2.39.2 From nobody Fri Feb 13 13:25:47 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 1F56413AD38 for ; Mon, 27 May 2024 06:38:30 +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=1716791912; cv=none; b=G5KBE5HsKXrfm4dQSsOSdPRrFq2jhxuLAAcDUAsQjA3UevIcx14NAXX/madzgzU8/epJ0DzxSPVgCKRkSftTih9lZkko8yHr2wlDuYaQtI7lWjtDow17dKttF/82ccFY/m2OutVwp/uFBYGaTuM9xQk9oZvdryRGu47y1+RBpsI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716791912; c=relaxed/simple; bh=1wETrd3QxZa6JEiWlFQIO6yl4IUpd7BYzrr49ZMy5YU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=sj8s6FROcGWcx7EPML661MAvqo9ZS+sJ6//L5SEPFAl98O/tQQxzytFkjJBmsMUS2sV9ejF3ZDFucwflP70kK+fjguCRJfXc4gqZlys9HoCMfgu78ZMkx18ZShrno3nd5hDsdhS8RezufF0JuKE6U84EHMpvKFUoL2ARg+RLKy0= 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=cQmCRvk4; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=4ANQSGG5; 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="cQmCRvk4"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="4ANQSGG5" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1716791908; 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+B1JLU7pRhvX/0oEMOhFW5PTzAmUDHfmWDy1oIGKPw=; b=cQmCRvk4KeDK0w3+Ymyc6U5m2VHtvUCVCVmuYNU4nsbZH8Qc14kfEq4A2i7pkxBF/LJd02 ZnYI7OB64yzK3pWm0B2K4WTfrJ/+gqgvIGCUxvpwvoQ+gicQR/5ikL9I4p/aLeJZP3qJtW R8OUNAjIb5stoa5ic0zj2JU/OXv+gyGO8yyr6FR69PC7S0OUKATH1CZLo7K7XT8/TY1tAB 0NhRcQ2g+B5FMkF+44ql3drQzGM8HYGTS6Y7GlLYUJiXj7QZbeLaBq4Q+JP+psmp1t0fMg lPD1CNsDdvVKBCH38ZVB0LcQ+1kDoMOcYBl/TMJEl/8ErzVF+aiHrpYgiSME1Q== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1716791908; 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+B1JLU7pRhvX/0oEMOhFW5PTzAmUDHfmWDy1oIGKPw=; b=4ANQSGG5OHfl40p35WBdEPDpZBa1BbQpxePPpMV1fi6uEXQF5v2lU4v9KCjtBBE+4zvuQx 5oyZ4ZHR2dobNHDA== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Peter Zijlstra , Ingo Molnar , Will Deacon , Waiman Long , Boqun Feng Subject: [PATCH printk v6 30/30] lockdep: Mark emergency sections in lockdep splats Date: Mon, 27 May 2024 08:43:49 +0206 Message-Id: <20240527063749.391035-31-john.ogness@linutronix.de> In-Reply-To: <20240527063749.391035-1-john.ogness@linutronix.de> References: <20240527063749.391035-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" Mark emergency sections wherever multiple lines of lock debugging output are generated. In an emergency section the CPU will not perform console output for the printk() calls. Instead, a flushing of the console output is triggered when exiting the emergency section. This allows the full message block to be stored as quickly as possible in the ringbuffer. Note that debug_show_all_locks() and lockdep_print_held_locks() rely on their callers to enter the emergency section. This is because these functions can also be called in non-emergency situations (such as sysrq). Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- kernel/locking/lockdep.c | 84 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 2 deletions(-) diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index 151bd3de5936..c06842e037d8 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -56,6 +56,7 @@ #include #include #include +#include =20 #include =20 @@ -574,8 +575,10 @@ static struct lock_trace *save_trace(void) if (!debug_locks_off_graph_unlock()) return NULL; =20 + nbcon_cpu_emergency_enter(); print_lockdep_off("BUG: MAX_STACK_TRACE_ENTRIES too low!"); dump_stack(); + nbcon_cpu_emergency_exit(); =20 return NULL; } @@ -888,11 +891,13 @@ look_up_lock_class(const struct lockdep_map *lock, un= signed int subclass) if (unlikely(subclass >=3D MAX_LOCKDEP_SUBCLASSES)) { instrumentation_begin(); debug_locks_off(); + nbcon_cpu_emergency_enter(); printk(KERN_ERR "BUG: looking up invalid subclass: %u\n", subclass); printk(KERN_ERR "turning off the locking correctness validator.\n"); dump_stack(); + nbcon_cpu_emergency_exit(); instrumentation_end(); return NULL; } @@ -969,11 +974,13 @@ static bool assign_lock_key(struct lockdep_map *lock) else { /* Debug-check: all keys must be persistent! */ debug_locks_off(); + nbcon_cpu_emergency_enter(); pr_err("INFO: trying to register non-static key.\n"); pr_err("The code is fine but needs lockdep annotation, or maybe\n"); pr_err("you didn't initialize this object before use?\n"); pr_err("turning off the locking correctness validator.\n"); dump_stack(); + nbcon_cpu_emergency_exit(); return false; } =20 @@ -1317,8 +1324,10 @@ register_lock_class(struct lockdep_map *lock, unsign= ed int subclass, int force) return NULL; } =20 + nbcon_cpu_emergency_enter(); print_lockdep_off("BUG: MAX_LOCKDEP_KEYS too low!"); dump_stack(); + nbcon_cpu_emergency_exit(); return NULL; } nr_lock_classes++; @@ -1350,11 +1359,13 @@ register_lock_class(struct lockdep_map *lock, unsig= ned int subclass, int force) if (verbose(class)) { graph_unlock(); =20 + nbcon_cpu_emergency_enter(); printk("\nnew class %px: %s", class->key, class->name); if (class->name_version > 1) printk(KERN_CONT "#%d", class->name_version); printk(KERN_CONT "\n"); dump_stack(); + nbcon_cpu_emergency_exit(); =20 if (!graph_lock()) { return NULL; @@ -1393,8 +1404,10 @@ static struct lock_list *alloc_list_entry(void) if (!debug_locks_off_graph_unlock()) return NULL; =20 + nbcon_cpu_emergency_enter(); print_lockdep_off("BUG: MAX_LOCKDEP_ENTRIES too low!"); dump_stack(); + nbcon_cpu_emergency_exit(); return NULL; } nr_list_entries++; @@ -2040,6 +2053,8 @@ static noinline void print_circular_bug(struct lock_l= ist *this, =20 depth =3D get_lock_depth(target); =20 + nbcon_cpu_emergency_enter(); + print_circular_bug_header(target, depth, check_src, check_tgt); =20 parent =3D get_lock_parent(target); @@ -2058,6 +2073,8 @@ static noinline void print_circular_bug(struct lock_l= ist *this, =20 printk("\nstack backtrace:\n"); dump_stack(); + + nbcon_cpu_emergency_exit(); } =20 static noinline void print_bfs_bug(int ret) @@ -2570,6 +2587,8 @@ print_bad_irq_dependency(struct task_struct *curr, if (!debug_locks_off_graph_unlock() || debug_locks_silent) return; =20 + nbcon_cpu_emergency_enter(); + pr_warn("\n"); pr_warn("=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\n"); pr_warn("WARNING: %s-safe -> %s-unsafe lock order detected\n", @@ -2619,11 +2638,13 @@ print_bad_irq_dependency(struct task_struct *curr, pr_warn(" and %s-irq-unsafe lock:\n", irqclass); next_root->trace =3D save_trace(); if (!next_root->trace) - return; + goto out; print_shortest_lock_dependencies(forwards_entry, next_root); =20 pr_warn("\nstack backtrace:\n"); dump_stack(); +out: + nbcon_cpu_emergency_exit(); } =20 static const char *state_names[] =3D { @@ -2988,6 +3009,8 @@ print_deadlock_bug(struct task_struct *curr, struct h= eld_lock *prev, if (!debug_locks_off_graph_unlock() || debug_locks_silent) return; =20 + nbcon_cpu_emergency_enter(); + pr_warn("\n"); pr_warn("=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\n"); pr_warn("WARNING: possible recursive locking detected\n"); @@ -3010,6 +3033,8 @@ print_deadlock_bug(struct task_struct *curr, struct h= eld_lock *prev, =20 pr_warn("\nstack backtrace:\n"); dump_stack(); + + nbcon_cpu_emergency_exit(); } =20 /* @@ -3607,6 +3632,8 @@ static void print_collision(struct task_struct *curr, struct held_lock *hlock_next, struct lock_chain *chain) { + nbcon_cpu_emergency_enter(); + pr_warn("\n"); pr_warn("=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\n"); pr_warn("WARNING: chain_key collision\n"); @@ -3623,6 +3650,8 @@ static void print_collision(struct task_struct *curr, =20 pr_warn("\nstack backtrace:\n"); dump_stack(); + + nbcon_cpu_emergency_exit(); } #endif =20 @@ -3713,8 +3742,10 @@ static inline int add_chain_cache(struct task_struct= *curr, if (!debug_locks_off_graph_unlock()) return 0; =20 + nbcon_cpu_emergency_enter(); print_lockdep_off("BUG: MAX_LOCKDEP_CHAINS too low!"); dump_stack(); + nbcon_cpu_emergency_exit(); return 0; } chain->chain_key =3D chain_key; @@ -3731,8 +3762,10 @@ static inline int add_chain_cache(struct task_struct= *curr, if (!debug_locks_off_graph_unlock()) return 0; =20 + nbcon_cpu_emergency_enter(); print_lockdep_off("BUG: MAX_LOCKDEP_CHAIN_HLOCKS too low!"); dump_stack(); + nbcon_cpu_emergency_exit(); return 0; } =20 @@ -3971,6 +4004,8 @@ print_usage_bug(struct task_struct *curr, struct held= _lock *this, if (!debug_locks_off() || debug_locks_silent) return; =20 + nbcon_cpu_emergency_enter(); + pr_warn("\n"); pr_warn("=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\n"); pr_warn("WARNING: inconsistent lock state\n"); @@ -3999,6 +4034,8 @@ print_usage_bug(struct task_struct *curr, struct held= _lock *this, =20 pr_warn("\nstack backtrace:\n"); dump_stack(); + + nbcon_cpu_emergency_exit(); } =20 /* @@ -4033,6 +4070,8 @@ print_irq_inversion_bug(struct task_struct *curr, if (!debug_locks_off_graph_unlock() || debug_locks_silent) return; =20 + nbcon_cpu_emergency_enter(); + pr_warn("\n"); pr_warn("=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\n"); pr_warn("WARNING: possible irq lock inversion dependency detected\n"); @@ -4073,11 +4112,13 @@ print_irq_inversion_bug(struct task_struct *curr, pr_warn("\nthe shortest dependencies between 2nd lock and 1st lock:\n"); root->trace =3D save_trace(); if (!root->trace) - return; + goto out; print_shortest_lock_dependencies(other, root); =20 pr_warn("\nstack backtrace:\n"); dump_stack(); +out: + nbcon_cpu_emergency_exit(); } =20 /* @@ -4154,6 +4195,8 @@ void print_irqtrace_events(struct task_struct *curr) { const struct irqtrace_events *trace =3D &curr->irqtrace; =20 + nbcon_cpu_emergency_enter(); + printk("irq event stamp: %u\n", trace->irq_events); printk("hardirqs last enabled at (%u): [<%px>] %pS\n", trace->hardirq_enable_event, (void *)trace->hardirq_enable_ip, @@ -4167,6 +4210,8 @@ void print_irqtrace_events(struct task_struct *curr) printk("softirqs last disabled at (%u): [<%px>] %pS\n", trace->softirq_disable_event, (void *)trace->softirq_disable_ip, (void *)trace->softirq_disable_ip); + + nbcon_cpu_emergency_exit(); } =20 static int HARDIRQ_verbose(struct lock_class *class) @@ -4687,10 +4732,12 @@ static int mark_lock(struct task_struct *curr, stru= ct held_lock *this, * We must printk outside of the graph_lock: */ if (ret =3D=3D 2) { + nbcon_cpu_emergency_enter(); printk("\nmarked lock as {%s}:\n", usage_str[new_bit]); print_lock(this); print_irqtrace_events(curr); dump_stack(); + nbcon_cpu_emergency_exit(); } =20 return ret; @@ -4731,6 +4778,8 @@ print_lock_invalid_wait_context(struct task_struct *c= urr, if (debug_locks_silent) return 0; =20 + nbcon_cpu_emergency_enter(); + pr_warn("\n"); pr_warn("=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\n"); pr_warn("[ BUG: Invalid wait context ]\n"); @@ -4750,6 +4799,8 @@ print_lock_invalid_wait_context(struct task_struct *c= urr, pr_warn("stack backtrace:\n"); dump_stack(); =20 + nbcon_cpu_emergency_exit(); + return 0; } =20 @@ -4954,6 +5005,8 @@ print_lock_nested_lock_not_held(struct task_struct *c= urr, if (debug_locks_silent) return; =20 + nbcon_cpu_emergency_enter(); + pr_warn("\n"); pr_warn("=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\n"); pr_warn("WARNING: Nested lock was not taken\n"); @@ -4974,6 +5027,8 @@ print_lock_nested_lock_not_held(struct task_struct *c= urr, =20 pr_warn("\nstack backtrace:\n"); dump_stack(); + + nbcon_cpu_emergency_exit(); } =20 static int __lock_is_held(const struct lockdep_map *lock, int read); @@ -5019,11 +5074,13 @@ static int __lock_acquire(struct lockdep_map *lock,= unsigned int subclass, debug_class_ops_inc(class); =20 if (very_verbose(class)) { + nbcon_cpu_emergency_enter(); printk("\nacquire class [%px] %s", class->key, class->name); if (class->name_version > 1) printk(KERN_CONT "#%d", class->name_version); printk(KERN_CONT "\n"); dump_stack(); + nbcon_cpu_emergency_exit(); } =20 /* @@ -5150,6 +5207,7 @@ static int __lock_acquire(struct lockdep_map *lock, u= nsigned int subclass, #endif if (unlikely(curr->lockdep_depth >=3D MAX_LOCK_DEPTH)) { debug_locks_off(); + nbcon_cpu_emergency_enter(); print_lockdep_off("BUG: MAX_LOCK_DEPTH too low!"); printk(KERN_DEBUG "depth: %i max: %lu!\n", curr->lockdep_depth, MAX_LOCK_DEPTH); @@ -5157,6 +5215,7 @@ static int __lock_acquire(struct lockdep_map *lock, u= nsigned int subclass, lockdep_print_held_locks(current); debug_show_all_locks(); dump_stack(); + nbcon_cpu_emergency_exit(); =20 return 0; } @@ -5176,6 +5235,8 @@ static void print_unlock_imbalance_bug(struct task_st= ruct *curr, if (debug_locks_silent) return; =20 + nbcon_cpu_emergency_enter(); + pr_warn("\n"); pr_warn("=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\n"); pr_warn("WARNING: bad unlock balance detected!\n"); @@ -5192,6 +5253,8 @@ static void print_unlock_imbalance_bug(struct task_st= ruct *curr, =20 pr_warn("\nstack backtrace:\n"); dump_stack(); + + nbcon_cpu_emergency_exit(); } =20 static noinstr int match_held_lock(const struct held_lock *hlock, @@ -5895,6 +5958,8 @@ static void print_lock_contention_bug(struct task_str= uct *curr, if (debug_locks_silent) return; =20 + nbcon_cpu_emergency_enter(); + pr_warn("\n"); pr_warn("=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\n"); pr_warn("WARNING: bad contention detected!\n"); @@ -5911,6 +5976,8 @@ static void print_lock_contention_bug(struct task_str= uct *curr, =20 pr_warn("\nstack backtrace:\n"); dump_stack(); + + nbcon_cpu_emergency_exit(); } =20 static void @@ -6524,6 +6591,8 @@ print_freed_lock_bug(struct task_struct *curr, const = void *mem_from, if (debug_locks_silent) return; =20 + nbcon_cpu_emergency_enter(); + pr_warn("\n"); pr_warn("=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\n"); pr_warn("WARNING: held lock freed!\n"); @@ -6536,6 +6605,8 @@ print_freed_lock_bug(struct task_struct *curr, const = void *mem_from, =20 pr_warn("\nstack backtrace:\n"); dump_stack(); + + nbcon_cpu_emergency_exit(); } =20 static inline int not_in_range(const void* mem_from, unsigned long mem_len, @@ -6582,6 +6653,8 @@ static void print_held_locks_bug(void) if (debug_locks_silent) return; =20 + nbcon_cpu_emergency_enter(); + pr_warn("\n"); pr_warn("=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\n"); pr_warn("WARNING: %s/%d still has locks held!\n", @@ -6591,6 +6664,8 @@ static void print_held_locks_bug(void) lockdep_print_held_locks(current); pr_warn("\nstack backtrace:\n"); dump_stack(); + + nbcon_cpu_emergency_exit(); } =20 void debug_check_no_locks_held(void) @@ -6616,6 +6691,7 @@ void debug_show_all_locks(void) if (!p->lockdep_depth) continue; lockdep_print_held_locks(p); + nbcon_cpu_emergency_flush(); touch_nmi_watchdog(); touch_all_softlockup_watchdogs(); } @@ -6648,6 +6724,7 @@ asmlinkage __visible void lockdep_sys_exit(void) if (unlikely(curr->lockdep_depth)) { if (!debug_locks_off()) return; + nbcon_cpu_emergency_enter(); pr_warn("\n"); pr_warn("=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\n"); pr_warn("WARNING: lock held when returning to user space!\n"); @@ -6656,6 +6733,7 @@ asmlinkage __visible void lockdep_sys_exit(void) pr_warn("%s/%d is leaving the kernel with locks still held!\n", curr->comm, curr->pid); lockdep_print_held_locks(curr); + nbcon_cpu_emergency_exit(); } =20 /* @@ -6672,6 +6750,7 @@ void lockdep_rcu_suspicious(const char *file, const i= nt line, const char *s) bool rcu =3D warn_rcu_enter(); =20 /* Note: the following can be executed concurrently, so be careful. */ + nbcon_cpu_emergency_enter(); pr_warn("\n"); pr_warn("=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\n"); pr_warn("WARNING: suspicious RCU usage\n"); @@ -6710,6 +6789,7 @@ void lockdep_rcu_suspicious(const char *file, const i= nt line, const char *s) lockdep_print_held_locks(curr); pr_warn("\nstack backtrace:\n"); dump_stack(); + nbcon_cpu_emergency_exit(); warn_rcu_exit(rcu); } EXPORT_SYMBOL_GPL(lockdep_rcu_suspicious); --=20 2.39.2