From nobody Sat Dec 27 22:51:33 2025 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 841086ABB3 for ; Thu, 14 Dec 2023 21:42:06 +0000 (UTC) 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="yOcxR/U3"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="29jZVYcn" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1702590124; 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=P/NotbYcz70vb9TswAdSo/L8cfzqAV5DTPxEUBxk0c8=; b=yOcxR/U3d0FPxIrFHLpGXYySVhpZMfr8I4Hwg/QRm4ZmNnim7rbVwus6zENdtjbEYhAAok ogs1XfQ9tfNvH7fxUr1+O49TWlfkwLfYVAmcVHAKTVM7HPz7t1UqtlaWJALqXp5iw7+VNf g4bwS+GDik7bOP2vg3GiQZxdsQacxZbqH5jHVV9A7x0IsVay2n7Zgy3RYunu6U9QwEtJ21 IGY+XPt4RlJo3O0oib/dknKxb/lFv54+LSseI/z4J/7ybeLK+WkkHVL7nrMsuJrsp4R3Ca 8ybVr0+0LtBDGI4yyWgQ2Pst+poQwDBu7kRIkNxnrl2m06JY0N5Y8r7lC90yPQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1702590124; 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=P/NotbYcz70vb9TswAdSo/L8cfzqAV5DTPxEUBxk0c8=; b=29jZVYcnmRq2m2fajNwN2rkwlfR5X8Uq/N8rbSOC8BypMgCEoiI+HSyjdwf/tuPOIeV6I1 1r0swCE9anxCijBQ== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v3 01/14] printk: nbcon: Relocate 32bit seq macros Date: Thu, 14 Dec 2023 22:47:48 +0106 Message-Id: <20231214214201.499426-2-john.ogness@linutronix.de> In-Reply-To: <20231214214201.499426-1-john.ogness@linutronix.de> References: <20231214214201.499426-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 macros __seq_to_nbcon_seq() and __nbcon_seq_to_seq() are used to provide support for atomic handling of sequence numbers on 32bit systems. Until now this was only used by nbcon.c, which is why they were located in nbcon.c and include nbcon in the name. In a follow-up commit this functionality is also needed by printk_ringbuffer. Rather than duplicating the functionality, relocate the macros to printk_ringbuffer.h. Also, since the macros will be no longer nbcon-specific, rename them to __u64seq_to_ulseq() and __ulseq_to_u64seq(). This does not result in any functional change. Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- kernel/printk/nbcon.c | 41 +++---------------------------- kernel/printk/printk_ringbuffer.h | 33 +++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c index b96077152f49..c8093bcc01fe 100644 --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c @@ -140,39 +140,6 @@ static inline bool nbcon_state_try_cmpxchg(struct cons= ole *con, struct nbcon_sta return atomic_try_cmpxchg(&ACCESS_PRIVATE(con, nbcon_state), &cur->atom, = new->atom); } =20 -#ifdef CONFIG_64BIT - -#define __seq_to_nbcon_seq(seq) (seq) -#define __nbcon_seq_to_seq(seq) (seq) - -#else /* CONFIG_64BIT */ - -#define __seq_to_nbcon_seq(seq) ((u32)seq) - -static inline u64 __nbcon_seq_to_seq(u32 nbcon_seq) -{ - u64 seq; - u64 rb_next_seq; - - /* - * The provided sequence is only the lower 32 bits of the ringbuffer - * sequence. It needs to be expanded to 64bit. Get the next sequence - * number from the ringbuffer and fold it. - * - * Having a 32bit representation in the console is sufficient. - * If a console ever gets more than 2^31 records behind - * the ringbuffer then this is the least of the problems. - * - * Also the access to the ring buffer is always safe. - */ - rb_next_seq =3D prb_next_seq(prb); - seq =3D rb_next_seq - ((u32)rb_next_seq - nbcon_seq); - - return seq; -} - -#endif /* CONFIG_64BIT */ - /** * nbcon_seq_read - Read the current console sequence * @con: Console to read the sequence of @@ -183,7 +150,7 @@ u64 nbcon_seq_read(struct console *con) { unsigned long nbcon_seq =3D atomic_long_read(&ACCESS_PRIVATE(con, nbcon_s= eq)); =20 - return __nbcon_seq_to_seq(nbcon_seq); + return __ulseq_to_u64seq(prb, nbcon_seq); } =20 /** @@ -204,7 +171,7 @@ 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), __seq_to_nbcon_seq(valid= _seq)); + atomic_long_set(&ACCESS_PRIVATE(con, nbcon_seq), __u64seq_to_ulseq(valid_= seq)); =20 /* Clear con->seq since nbcon consoles use con->nbcon_seq instead. */ con->seq =3D 0; @@ -223,11 +190,11 @@ void nbcon_seq_force(struct console *con, u64 seq) */ static void nbcon_seq_try_update(struct nbcon_context *ctxt, u64 new_seq) { - unsigned long nbcon_seq =3D __seq_to_nbcon_seq(ctxt->seq); + unsigned long nbcon_seq =3D __u64seq_to_ulseq(ctxt->seq); struct console *con =3D ctxt->console; =20 if (atomic_long_try_cmpxchg(&ACCESS_PRIVATE(con, nbcon_seq), &nbcon_seq, - __seq_to_nbcon_seq(new_seq))) { + __u64seq_to_ulseq(new_seq))) { ctxt->seq =3D new_seq; } else { ctxt->seq =3D nbcon_seq_read(con); diff --git a/kernel/printk/printk_ringbuffer.h b/kernel/printk/printk_ringb= uffer.h index 18cd25e489b8..b82a96dc2ea2 100644 --- a/kernel/printk/printk_ringbuffer.h +++ b/kernel/printk/printk_ringbuffer.h @@ -381,4 +381,37 @@ bool prb_read_valid_info(struct printk_ringbuffer *rb,= u64 seq, u64 prb_first_valid_seq(struct printk_ringbuffer *rb); u64 prb_next_seq(struct printk_ringbuffer *rb); =20 +#ifdef CONFIG_64BIT + +#define __u64seq_to_ulseq(u64seq) (u64seq) +#define __ulseq_to_u64seq(rb, ulseq) (ulseq) + +#else /* CONFIG_64BIT */ + +#define __u64seq_to_ulseq(u64seq) ((u32)u64seq) + +static inline u64 __ulseq_to_u64seq(struct printk_ringbuffer *rb, u32 ulse= q) +{ + u64 seq; + u64 rb_next_seq; + + /* + * The provided sequence is only the lower 32 bits of the ringbuffer + * sequence. It needs to be expanded to 64bit. Get the next sequence + * number from the ringbuffer and fold it. + * + * Having a 32bit representation in the console is sufficient. + * If a console ever gets more than 2^31 records behind + * the ringbuffer then this is the least of the problems. + * + * Also the access to the ring buffer is always safe. + */ + rb_next_seq =3D prb_next_seq(rb); + seq =3D rb_next_seq - ((u32)rb_next_seq - ulseq); + + return seq; +} + +#endif /* CONFIG_64BIT */ + #endif /* _KERNEL_PRINTK_RINGBUFFER_H */ --=20 2.39.2 From nobody Sat Dec 27 22:51:33 2025 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 37D636A34D for ; Thu, 14 Dec 2023 21:42:07 +0000 (UTC) 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="ELKFiU6Q"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="N18HNVVu" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1702590125; 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=n7/AQ14CtAPSsdBF4bK1N6nAJCYWmYHbSVQMVRCyl58=; b=ELKFiU6QcHpmyjj4y3/ThWrC6NQsGQrxCPGsHKykjs/CeBfb1lK742gwL4JdDM8lCJjxFZ w+ymCW6goNmRY5vxbSXxHJ/onItb2M5fnM2QrmKkat5qnFhhrwKT8jrB4n+R6Ukd6zzinb 1jdOKuWs/T04n+S6Aou6k+sjVMrAS2iMYCfHDme3aNQKFJ3O1cdTPyagsQhPbkVA0wx2gR V5HQuORKoXg6WyYNjOyoMgwv1vDu+x9W84Rq46CcnV3SrIbOOOi5+btRwkOr9jrxFKuM2r 2u4tWmuFFrnavCGbKEMk/FpbZNgfhRGBR/Q8ByC4CaMGJNea1odvqekSvqiJNg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1702590125; 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=n7/AQ14CtAPSsdBF4bK1N6nAJCYWmYHbSVQMVRCyl58=; b=N18HNVVuiXztnaW/iSDFaWUXfIQT0nam9vm/nj3pVKOO4M1DD9GYxXgV0hGTwzBUbPMjDr 9e6CQjVJbikgkJCg== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Francesco Dolcini , kernel test robot , Sebastian Andrzej Siewior Subject: [PATCH printk v3 02/14] printk: Adjust mapping for 32bit seq macros Date: Thu, 14 Dec 2023 22:47:49 +0106 Message-Id: <20231214214201.499426-3-john.ogness@linutronix.de> In-Reply-To: <20231214214201.499426-1-john.ogness@linutronix.de> References: <20231214214201.499426-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" Note: This change only applies to 32bit architectures. On 64bit architectures the macros are NOPs. __ulseq_to_u64seq() computes the upper 32 bits of the passed argument value (@ulseq). The upper bits are derived from a base value (@rb_next_seq) in a way that assumes @ulseq represents a 64bit number that is less than or equal to @rb_next_seq. Until now this mapping has been correct for all call sites. However, in a follow-up commit, values of @ulseq will be passed in that are higher than the base value. This requires a change to how the 32bit value is mapped to a 64bit sequence number. Rather than mapping @ulseq such that the base value is the end of a 32bit block, map @ulseq such that the base value is in the middle of a 32bit block. This allows supporting 31 bits before and after the base value, which is deemed acceptable for the console sequence number during runtime. Here is an example to illustrate the previous and new mappings. For a base value (@rb_next_seq) of 2 2000 0000... Before this change the range of possible return values was: 1 2000 0001 to 2 2000 0000 __ulseq_to_u64seq(1fff ffff) =3D> 2 1fff ffff __ulseq_to_u64seq(2000 0000) =3D> 2 2000 0000 __ulseq_to_u64seq(2000 0001) =3D> 1 2000 0001 __ulseq_to_u64seq(9fff ffff) =3D> 1 9fff ffff __ulseq_to_u64seq(a000 0000) =3D> 1 a000 0000 __ulseq_to_u64seq(a000 0001) =3D> 1 a000 0001 After this change the range of possible return values are: 1 a000 0001 to 2 a000 0000 __ulseq_to_u64seq(1fff ffff) =3D> 2 1fff ffff __ulseq_to_u64seq(2000 0000) =3D> 2 2000 0000 __ulseq_to_u64seq(2000 0001) =3D> 2 2000 0001 __ulseq_to_u64seq(9fff ffff) =3D> 2 9fff ffff __ulseq_to_u64seq(a000 0000) =3D> 2 a000 0000 __ulseq_to_u64seq(a000 0001) =3D> 1 a000 0001 [ john.ogness: Rewrite commit message. ] Reported-by: Francesco Dolcini Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-lkp/202311171611.78d41dbe-oliver.sang@in= tel.com Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-lkp/202311161555.3ee16fc9-oliver.sang@in= tel.com Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- kernel/printk/printk_ringbuffer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/printk/printk_ringbuffer.h b/kernel/printk/printk_ringb= uffer.h index b82a96dc2ea2..12f60c782e46 100644 --- a/kernel/printk/printk_ringbuffer.h +++ b/kernel/printk/printk_ringbuffer.h @@ -407,7 +407,7 @@ static inline u64 __ulseq_to_u64seq(struct printk_ringb= uffer *rb, u32 ulseq) * Also the access to the ring buffer is always safe. */ rb_next_seq =3D prb_next_seq(rb); - seq =3D rb_next_seq - ((u32)rb_next_seq - ulseq); + seq =3D rb_next_seq - (s32)((u32)rb_next_seq - ulseq); =20 return seq; } --=20 2.39.2 From nobody Sat Dec 27 22:51:33 2025 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 37E496ABB5 for ; Thu, 14 Dec 2023 21:42:07 +0000 (UTC) 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="b+oQS7ov"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="phT90Otf" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1702590125; 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=muVNDGHsflpPS75QT30/xhAWDErFJBhvBumoamznaLA=; b=b+oQS7ovxSclsqr8szoXFqH5thsF+V/j7hxOLnR6shH6GCgYLVavhZbEycUD0bPh8KIsd3 /HQ8unq761Xz6A/zlKW0c1tqBwiK+RPYSw8z9b3h5Fag97ckFU1lZUqITRUv/S8r46v69P BCQGaJacgenSB1odluZ4hrYsY04KsCHBS8BmWKl/jka072/PNjXPSNQSd+5MzTOBt7Sr6C 6aD0jtwk9E1j9N8Z7odbKB2nM7msQTNTwU86Opx5sL9z3eT6Elac/AcyaHBTJHTLOTf2qA jUzNItuhD/asRLVfhBa/aDlLPiko1FuNfZqi2A01jZUn8r3708PYNY4WE1C9Lg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1702590125; 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=muVNDGHsflpPS75QT30/xhAWDErFJBhvBumoamznaLA=; b=phT90OtfDCug3ZR3eWCa6Yqoc+ndgc1bUViER55GRkZespCIz0VYuEMEEGNPQB0TvYN5gX 9z3IEeo8V9KuY7BA== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v3 03/14] printk: Use prb_first_seq() as base for 32bit seq macros Date: Thu, 14 Dec 2023 22:47:50 +0106 Message-Id: <20231214214201.499426-4-john.ogness@linutronix.de> In-Reply-To: <20231214214201.499426-1-john.ogness@linutronix.de> References: <20231214214201.499426-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" Note: This change only applies to 32bit architectures. On 64bit architectures the macros are NOPs. Currently prb_next_seq() is used as the base for the 32bit seq macros __u64seq_to_ulseq() and __ulseq_to_u64seq(). However, in a follow-up commit, prb_next_seq() will need to make use of the 32bit seq macros. Use prb_first_seq() as the base for the 32bit seq macros instead because it is guaranteed to return 64bit sequence numbers without relying on any 32bit seq macros. Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- kernel/printk/printk_ringbuffer.c | 2 +- kernel/printk/printk_ringbuffer.h | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/kernel/printk/printk_ringbuffer.c b/kernel/printk/printk_ringb= uffer.c index fde338606ce8..49a82ccce8e9 100644 --- a/kernel/printk/printk_ringbuffer.c +++ b/kernel/printk/printk_ringbuffer.c @@ -1832,7 +1832,7 @@ static int prb_read(struct printk_ringbuffer *rb, u64= seq, } =20 /* Get the sequence number of the tail descriptor. */ -static u64 prb_first_seq(struct printk_ringbuffer *rb) +u64 prb_first_seq(struct printk_ringbuffer *rb) { struct prb_desc_ring *desc_ring =3D &rb->desc_ring; enum desc_state d_state; diff --git a/kernel/printk/printk_ringbuffer.h b/kernel/printk/printk_ringb= uffer.h index 12f60c782e46..ee294aaf4aeb 100644 --- a/kernel/printk/printk_ringbuffer.h +++ b/kernel/printk/printk_ringbuffer.h @@ -378,6 +378,7 @@ bool prb_read_valid(struct printk_ringbuffer *rb, u64 s= eq, bool prb_read_valid_info(struct printk_ringbuffer *rb, u64 seq, struct printk_info *info, unsigned int *line_count); =20 +u64 prb_first_seq(struct printk_ringbuffer *rb); u64 prb_first_valid_seq(struct printk_ringbuffer *rb); u64 prb_next_seq(struct printk_ringbuffer *rb); =20 @@ -392,12 +393,12 @@ u64 prb_next_seq(struct printk_ringbuffer *rb); =20 static inline u64 __ulseq_to_u64seq(struct printk_ringbuffer *rb, u32 ulse= q) { + u64 rb_first_seq =3D prb_first_seq(rb); u64 seq; - u64 rb_next_seq; =20 /* * The provided sequence is only the lower 32 bits of the ringbuffer - * sequence. It needs to be expanded to 64bit. Get the next sequence + * sequence. It needs to be expanded to 64bit. Get the first sequence * number from the ringbuffer and fold it. * * Having a 32bit representation in the console is sufficient. @@ -406,8 +407,7 @@ static inline u64 __ulseq_to_u64seq(struct printk_ringb= uffer *rb, u32 ulseq) * * Also the access to the ring buffer is always safe. */ - rb_next_seq =3D prb_next_seq(rb); - seq =3D rb_next_seq - (s32)((u32)rb_next_seq - ulseq); + seq =3D rb_first_seq - (s32)((u32)rb_first_seq - ulseq); =20 return seq; } --=20 2.39.2 From nobody Sat Dec 27 22:51:33 2025 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 785526ABB7 for ; Thu, 14 Dec 2023 21:42:07 +0000 (UTC) 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="HkbtUXy9"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="WAOVSLxW" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1702590125; 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=AnwPd7XIokQ/bLOcP3/FHbKObdxJLytnqkjXweQk6XQ=; b=HkbtUXy9HfPOvBlylkVursMQdKGv354mjRQZyCJHFNdsGMCBc5l+Sk2jJT/H4Bmi4gl1+d ZJwXdLmzoBIYC5FQPAktUaHHJN6cOOgpwZVZ/tEnpONSezyja3m5SY/EXSYasF7woZQSa8 zOLg7giGSXjvPPQ3F467bvougvrrb/7ghhjOb9x2FVx1S0tE5vNbMRmAqKEiNGxDqBvpzZ MIDnfHqML+U1C2sfrEhs2m34oKfZNrjBtxEPmXHFXblTM+PJsj0JpXfhTu9zVf6x6Bb2l0 wl2iJmC3RwFHnIJmy6K7eIynmkPVp8LWa/s+8tzNGSFd0Mv79oKyhcQlKdxC3A== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1702590125; 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=AnwPd7XIokQ/bLOcP3/FHbKObdxJLytnqkjXweQk6XQ=; b=WAOVSLxW3hYnadim2qDrP1Rl3u5O4bI8RknF0VkzQUPexiJIia0vbqzSVCrK2qnTkdZW3s bzgv0EjaVs/9JNCg== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Mukesh Ojha Subject: [PATCH printk v3 04/14] printk: ringbuffer: Do not skip non-finalized records with prb_next_seq() Date: Thu, 14 Dec 2023 22:47:51 +0106 Message-Id: <20231214214201.499426-5-john.ogness@linutronix.de> In-Reply-To: <20231214214201.499426-1-john.ogness@linutronix.de> References: <20231214214201.499426-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" Commit f244b4dc53e5 ("printk: ringbuffer: Improve prb_next_seq() performance") introduced an optimization for prb_next_seq() by using best-effort to track recently finalized records. However, the order of finalization does not necessarily match the order of the records. The optimization changed prb_next_seq() to return inconsistent results, possibly yielding sequence numbers that are not available to readers because they are preceded by non-finalized records or they are not yet visible to the reader CPU. Rather than simply best-effort tracking recently finalized records, force the committing writer to read records and increment the last "contiguous block" of finalized records. In order to do this, the sequence number instead of ID must be stored because ID's cannot be directly compared. A new memory barrier pair is introduced to guarantee that a reader can always read the records up until the sequence number returned by prb_next_seq() (unless the records have since been overwritten in the ringbuffer). This restores the original functionality of prb_next_seq() while also keeping the optimization. For 32bit systems, only the lower 32 bits of the sequence number are stored. When reading the value, it is expanded to the full 64bit sequence number using the 32bit seq macros, which fold in the value returned by prb_first_seq(). Fixes: f244b4dc53e5 ("printk: ringbuffer: Improve prb_next_seq() performanc= e") Signed-off-by: John Ogness --- kernel/printk/printk_ringbuffer.c | 164 +++++++++++++++++++++++------- kernel/printk/printk_ringbuffer.h | 4 +- 2 files changed, 127 insertions(+), 41 deletions(-) diff --git a/kernel/printk/printk_ringbuffer.c b/kernel/printk/printk_ringb= uffer.c index 49a82ccce8e9..04c26cca546f 100644 --- a/kernel/printk/printk_ringbuffer.c +++ b/kernel/printk/printk_ringbuffer.c @@ -6,6 +6,7 @@ #include #include #include "printk_ringbuffer.h" +#include "internal.h" =20 /** * DOC: printk_ringbuffer overview @@ -303,6 +304,9 @@ * * desc_push_tail:B / desc_reserve:D * set descriptor reusable (state), then push descriptor tail (id) + * + * desc_update_last_finalized:A / desc_last_finalized_seq:A + * store finalized record, then set new highest finalized sequence num= ber */ =20 #define DATA_SIZE(data_ring) _DATA_SIZE((data_ring)->size_bits) @@ -1441,20 +1445,118 @@ bool prb_reserve_in_last(struct prb_reserved_entry= *e, struct printk_ringbuffer return false; } =20 +/* + * @last_finalized_seq value guarantees that all records up to and includi= ng + * this sequence number are finalized and can be read. The only exception = are + * too old records which have already been overwritten. + * + * It is also guaranteed that @last_finalized_seq only increases. + * + * Be aware that finalized records following non-finalized records are not + * reported because they are not yet available to the reader. For example, + * a new record stored via printk() will not be available to a printer if + * it follows a record that has not been finalized yet. However, once that + * non-finalized record becomes finalized, @last_finalized_seq will be + * appropriately updated and the full set of finalized records will be + * available to the printer. And since each printk() caller will either + * directly print or trigger deferred printing of all available unprinted + * records, all printk() messages will get printed. + */ +static u64 desc_last_finalized_seq(struct printk_ringbuffer *rb) +{ + struct prb_desc_ring *desc_ring =3D &rb->desc_ring; + unsigned long ulseq; + + /* + * Guarantee the sequence number is loaded before loading the + * associated record in order to guarantee that the record can be + * seen by this CPU. This pairs with desc_update_last_finalized:A. + */ + ulseq =3D atomic_long_read_acquire(&desc_ring->last_finalized_seq + ); /* LMM(desc_last_finalized_seq:A) */ + + return __ulseq_to_u64seq(rb, ulseq); +} + +static bool _prb_read_valid(struct printk_ringbuffer *rb, u64 *seq, + struct printk_record *r, unsigned int *line_count); + +/* + * Check if there are records directly following @last_finalized_seq that = are + * finalized. If so, update @last_finalized_seq to the latest of these + * records. It is not allowed to skip over records that are not yet finali= zed. + */ +static void desc_update_last_finalized(struct printk_ringbuffer *rb) +{ + struct prb_desc_ring *desc_ring =3D &rb->desc_ring; + u64 old_seq =3D desc_last_finalized_seq(rb); + unsigned long oldval; + unsigned long newval; + u64 finalized_seq; + u64 try_seq; + +try_again: + finalized_seq =3D old_seq; + try_seq =3D finalized_seq + 1; + + /* Try to find later finalized records. */ + while (_prb_read_valid(rb, &try_seq, NULL, NULL)) { + finalized_seq =3D try_seq; + try_seq++; + } + + /* No update needed if no later finalized record was found. */ + if (finalized_seq =3D=3D old_seq) + return; + + oldval =3D __u64seq_to_ulseq(old_seq); + newval =3D __u64seq_to_ulseq(finalized_seq); + + /* + * Set the sequence number of a later finalized record that has been + * seen. + * + * Guarantee the record data is visible to other CPUs before storing + * its sequence number. This pairs with desc_last_finalized_seq:A. + * + * Memory barrier involvement: + * + * If desc_last_finalized_seq:A reads from + * desc_update_last_finalized:A, then desc_read:A reads from + * _prb_commit:B. + * + * Relies on: + * + * RELEASE from _prb_commit:B to desc_update_last_finalized:A + * matching + * ACQUIRE from desc_last_finalized_seq:A to desc_read:A + * + * Note: _prb_commit:B and desc_update_last_finalized:A can be + * different CPUs. However, the desc_update_last_finalized:A + * CPU (which performs the release) must have previously seen + * _prb_commit:B. + */ + if (!atomic_long_try_cmpxchg_release(&desc_ring->last_finalized_seq, + &oldval, newval)) { /* LMM(desc_update_last_finalized:A) */ + old_seq =3D __ulseq_to_u64seq(rb, oldval); + goto try_again; + } +} + /* * Attempt to finalize a specified descriptor. If this fails, the descript= or * is either already final or it will finalize itself when the writer comm= its. */ -static void desc_make_final(struct prb_desc_ring *desc_ring, unsigned long= id) +static void desc_make_final(struct printk_ringbuffer *rb, unsigned long id) { + struct prb_desc_ring *desc_ring =3D &rb->desc_ring; unsigned long prev_state_val =3D DESC_SV(id, desc_committed); struct prb_desc *d =3D to_desc(desc_ring, id); =20 - atomic_long_cmpxchg_relaxed(&d->state_var, prev_state_val, - DESC_SV(id, desc_finalized)); /* LMM(desc_make_final:A) */ - - /* Best effort to remember the last finalized @id. */ - atomic_long_set(&desc_ring->last_finalized_id, id); + if (atomic_long_try_cmpxchg_relaxed(&d->state_var, &prev_state_val, + DESC_SV(id, desc_finalized))) { /* LMM(desc_make_final:A) */ + desc_update_last_finalized(rb); + } } =20 /** @@ -1550,7 +1652,7 @@ bool prb_reserve(struct prb_reserved_entry *e, struct= printk_ringbuffer *rb, * readers. (For seq=3D=3D0 there is no previous descriptor.) */ if (info->seq > 0) - desc_make_final(desc_ring, DESC_ID(id - 1)); + desc_make_final(rb, DESC_ID(id - 1)); =20 r->text_buf =3D data_alloc(rb, r->text_buf_size, &d->text_blk_lpos, id); /* If text data allocation fails, a data-less record is committed. */ @@ -1643,7 +1745,7 @@ void prb_commit(struct prb_reserved_entry *e) */ head_id =3D atomic_long_read(&desc_ring->head_id); /* LMM(prb_commit:A) */ if (head_id !=3D e->id) - desc_make_final(desc_ring, e->id); + desc_make_final(e->rb, e->id); } =20 /** @@ -1663,12 +1765,9 @@ void prb_commit(struct prb_reserved_entry *e) */ void prb_final_commit(struct prb_reserved_entry *e) { - struct prb_desc_ring *desc_ring =3D &e->rb->desc_ring; - _prb_commit(e, desc_finalized); =20 - /* Best effort to remember the last finalized @id. */ - atomic_long_set(&desc_ring->last_finalized_id, e->id); + desc_update_last_finalized(e->rb); } =20 /* @@ -2008,7 +2107,9 @@ u64 prb_first_valid_seq(struct printk_ringbuffer *rb) * newest sequence number available to readers will be. * * This provides readers a sequence number to jump to if all currently - * available records should be skipped. + * available records should be skipped. It is guaranteed that all records + * previous to the returned value have been finalized and are (or were) + * available to the reader. * * Context: Any context. * Return: The sequence number of the next newest (not yet available) reco= rd @@ -2016,34 +2117,19 @@ u64 prb_first_valid_seq(struct printk_ringbuffer *r= b) */ u64 prb_next_seq(struct printk_ringbuffer *rb) { - struct prb_desc_ring *desc_ring =3D &rb->desc_ring; - enum desc_state d_state; - unsigned long id; u64 seq; =20 - /* Check if the cached @id still points to a valid @seq. */ - id =3D atomic_long_read(&desc_ring->last_finalized_id); - d_state =3D desc_read(desc_ring, id, NULL, &seq, NULL); + seq =3D desc_last_finalized_seq(rb); =20 - if (d_state =3D=3D desc_finalized || d_state =3D=3D desc_reusable) { - /* - * Begin searching after the last finalized record. - * - * On 0, the search must begin at 0 because of hack#2 - * of the bootstrapping phase it is not known if a - * record at index 0 exists. - */ - if (seq !=3D 0) - seq++; - } else { - /* - * The information about the last finalized sequence number - * has gone. It should happen only when there is a flood of - * new messages and the ringbuffer is rapidly recycled. - * Give up and start from the beginning. - */ - seq =3D 0; - } + /* + * Begin searching after the last finalized record. + * + * On 0, the search must begin at 0 because of hack#2 + * of the bootstrapping phase it is not known if a + * record at index 0 exists. + */ + if (seq !=3D 0) + seq++; =20 /* * The information about the last finalized @seq might be inaccurate. @@ -2085,7 +2171,7 @@ void prb_init(struct printk_ringbuffer *rb, rb->desc_ring.infos =3D infos; atomic_long_set(&rb->desc_ring.head_id, DESC0_ID(descbits)); atomic_long_set(&rb->desc_ring.tail_id, DESC0_ID(descbits)); - atomic_long_set(&rb->desc_ring.last_finalized_id, DESC0_ID(descbits)); + atomic_long_set(&rb->desc_ring.last_finalized_seq, 0); =20 rb->text_data_ring.size_bits =3D textbits; rb->text_data_ring.data =3D text_buf; diff --git a/kernel/printk/printk_ringbuffer.h b/kernel/printk/printk_ringb= uffer.h index ee294aaf4aeb..2d948cc82b5b 100644 --- a/kernel/printk/printk_ringbuffer.h +++ b/kernel/printk/printk_ringbuffer.h @@ -75,7 +75,7 @@ struct prb_desc_ring { struct printk_info *infos; atomic_long_t head_id; atomic_long_t tail_id; - atomic_long_t last_finalized_id; + atomic_long_t last_finalized_seq; }; =20 /* @@ -259,7 +259,7 @@ static struct printk_ringbuffer name =3D { \ .infos =3D &_##name##_infos[0], \ .head_id =3D ATOMIC_INIT(DESC0_ID(descbits)), \ .tail_id =3D ATOMIC_INIT(DESC0_ID(descbits)), \ - .last_finalized_id =3D ATOMIC_INIT(DESC0_ID(descbits)), \ + .last_finalized_seq =3D ATOMIC_INIT(0), \ }, \ .text_data_ring =3D { \ .size_bits =3D (avgtextbits) + (descbits), \ --=20 2.39.2 From nobody Sat Dec 27 22:51:33 2025 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 9C1FE6E2B5 for ; Thu, 14 Dec 2023 21:42:10 +0000 (UTC) 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="zHOemZYY"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="pr25KLwQ" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1702590126; 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=q48uIAB5AY2ApKCo1murQeJaZPOP9JBGkCMa5H/oZks=; b=zHOemZYYUinMd2+/7z/PQK/1U+igGlMmD7jmxS6Ujm81Or1gMFCOoM+izS3ovWoNVJ97tB uA9ukV2FOOOIUDQytwfsbYIR3+BauWy7FCDYOb5bgi64ehVTu/xqXo5XneymPobzurpnVE RZdwxZJpRAShbTVLBbFRYl7z5KBdCosXmU7FKu4A+V9vqd7EmhzTGAdqSz6Nld579vhFLj nC952Fb91S/HCwroykcAHUWkF4ek1Va1RdTgT42/tMrwnFSmIgR01Y+HQ+aOOL8AlFw+Kd QN/Z9vsLxsAaEnYxLJVRDSzZhLiJ3S6RjQtTnJvA+dMGeDVg739sMfCkW75cxw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1702590126; 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=q48uIAB5AY2ApKCo1murQeJaZPOP9JBGkCMa5H/oZks=; b=pr25KLwQUYt7bJV24yRRf26QkQaWfQ8a2xyOsOekYXPINKQ2n8GiQESfD07H7wbe+Babal sq/QlnfnnIh5XTBw== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v3 05/14] printk: ringbuffer: Clarify special lpos values Date: Thu, 14 Dec 2023 22:47:52 +0106 Message-Id: <20231214214201.499426-6-john.ogness@linutronix.de> In-Reply-To: <20231214214201.499426-1-john.ogness@linutronix.de> References: <20231214214201.499426-1-john.ogness@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" For empty line records, no data blocks are created. Instead, these valid records are identified by special logical position values (in fields of @prb_desc.text_blk_lpos). Currently the macro NO_LPOS is used for empty line records. This name is confusing because it does not imply _why_ there is no data block. Rename NO_LPOS to EMPTY_LINE_LPOS so that it is clear why there is no data block. Also add comments explaining the use of EMPTY_LINE_LPOS as well as clarification to the values used to represent data-less blocks. Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- kernel/printk/printk_ringbuffer.c | 20 ++++++++++++++++---- kernel/printk/printk_ringbuffer.h | 16 +++++++++++++++- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/kernel/printk/printk_ringbuffer.c b/kernel/printk/printk_ringb= uffer.c index 04c26cca546f..244d991ffd73 100644 --- a/kernel/printk/printk_ringbuffer.c +++ b/kernel/printk/printk_ringbuffer.c @@ -1034,9 +1034,13 @@ static char *data_alloc(struct printk_ringbuffer *rb= , unsigned int size, unsigned long next_lpos; =20 if (size =3D=3D 0) { - /* Specify a data-less block. */ - blk_lpos->begin =3D NO_LPOS; - blk_lpos->next =3D NO_LPOS; + /* + * Data blocks are not created for empty lines. Instead, the + * reader will recognize these special lpos values and handle + * it appropriately. + */ + blk_lpos->begin =3D EMPTY_LINE_LPOS; + blk_lpos->next =3D EMPTY_LINE_LPOS; return NULL; } =20 @@ -1214,10 +1218,18 @@ static const char *get_data(struct prb_data_ring *d= ata_ring, =20 /* Data-less data block description. */ if (BLK_DATALESS(blk_lpos)) { - if (blk_lpos->begin =3D=3D NO_LPOS && blk_lpos->next =3D=3D NO_LPOS) { + /* + * Records that are just empty lines are also valid, even + * though they do not have a data block. For such records + * explicitly return empty string data to signify success. + */ + if (blk_lpos->begin =3D=3D EMPTY_LINE_LPOS && + blk_lpos->next =3D=3D EMPTY_LINE_LPOS) { *data_size =3D 0; return ""; } + + /* Data lost, invalid, or otherwise unavailable. */ return NULL; } =20 diff --git a/kernel/printk/printk_ringbuffer.h b/kernel/printk/printk_ringb= uffer.h index 2d948cc82b5b..d49460f7578e 100644 --- a/kernel/printk/printk_ringbuffer.h +++ b/kernel/printk/printk_ringbuffer.h @@ -127,8 +127,22 @@ enum desc_state { #define DESC_SV(id, state) (((unsigned long)state << DESC_FLAGS_SHIFT) | i= d) #define DESC_ID_MASK (~DESC_FLAGS_MASK) #define DESC_ID(sv) ((sv) & DESC_ID_MASK) + +/* + * Special data block logical position values (for fields of + * @prb_desc.text_blk_lpos). + * + * - Bit0 is used to identify if the record has no data block. (Implemente= d in + * the LPOS_DATALESS() macro.) + * + * - Bit1 specifies the reason for not having a data block. + * + * These special values could never be real lpos values because of the + * meta data and alignment padding of data blocks. (See to_blk_size() for + * details.) + */ #define FAILED_LPOS 0x1 -#define NO_LPOS 0x3 +#define EMPTY_LINE_LPOS 0x3 =20 #define FAILED_BLK_LPOS \ { \ --=20 2.39.2 From nobody Sat Dec 27 22:51:33 2025 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 D9ED06E2BF for ; Thu, 14 Dec 2023 21:42:10 +0000 (UTC) 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="qFYyVTuH"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="BsC4fnb9" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1702590126; 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=krH2QkxdJALvXRu9Bq+Fw3gs7PqsPIKkUheQqZKkVK0=; b=qFYyVTuHxgTC9QlqyN1QHK4WWfE+6QS+rbWzDp1kBMoZyEwL1jBrlUDxSBt83RF2jSKdlA 7yg9jBlzbenZo7mLyIr1X94I8l71A4kFMrVWwjuSQoVBE7UUdKn5C7q72xIHkRcsFipQ1p SUC0G6X64Ls7EHDGpIWHfWB2FOQ4Y+3YGhF9ezaXMQ0Oqy5tWZvSH7It2NZGDZ3mSbWHsA bGA5qd3r5PI28RTsZ/NPKam9jm18sp7LTL7YQtn8bR0womOuLsioiX3v5r8+F46kqNG0k9 DZYZqLCVOQzeq/o8a5LqDMlwuya6GYVe5l16p+R+mZSbncMtq82KHSTWy6JS4Q== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1702590126; 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=krH2QkxdJALvXRu9Bq+Fw3gs7PqsPIKkUheQqZKkVK0=; b=BsC4fnb9tj450t5e44z0HhzQgechD4kbG8CjJvyXCEcSe27WZN0mvwHswe3ax+IlcCw2RX yGM+a1ZEl7KBdfAA== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v3 06/14] printk: For @suppress_panic_printk check for other CPU in panic Date: Thu, 14 Dec 2023 22:47:53 +0106 Message-Id: <20231214214201.499426-7-john.ogness@linutronix.de> In-Reply-To: <20231214214201.499426-1-john.ogness@linutronix.de> References: <20231214214201.499426-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 @suppress_panic_printk is checked along with non-matching @panic_cpu and current CPU. This works because @suppress_panic_printk is only set when panic_in_progress() is true. Rather than relying on the @suppress_panic_printk semantics, use the concise helper function other_cpu_in_progress(). The helper function exists to avoid open coding such tests. Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- kernel/printk/printk.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index be95a6851164..22bb45d8f2f2 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -2270,8 +2270,7 @@ asmlinkage int vprintk_emit(int facility, int level, if (unlikely(suppress_printk)) return 0; =20 - if (unlikely(suppress_panic_printk) && - atomic_read(&panic_cpu) !=3D raw_smp_processor_id()) + if (unlikely(suppress_panic_printk) && other_cpu_in_panic()) return 0; =20 if (level =3D=3D LOGLEVEL_SCHED) { --=20 2.39.2 From nobody Sat Dec 27 22:51:33 2025 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 D9F646E2C1 for ; Thu, 14 Dec 2023 21:42:10 +0000 (UTC) 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="Fl9EDpri"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="F1l2H1G/" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1702590126; 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=EjNlI5JonKv0m/kINdXCywSbWYOfTvFxrSFxNOQW5Ko=; b=Fl9EDpriC4isCU/BtgR2fdrIobGrK+hq+Ifz9dlN3/a1ySYUNd1l8M8/WQCtjZso2uBmwY Uz7xWkah907tDY34I+G0Rv68veVCA64rwBs8UMzMFc+M92sG8xPSNeA0g6op0LWfTGnChz ITiH2Li9Zl2EVtitjdzhIS4aK60cshGIyCblZ1/0DdbZdVctvHoWpulv1yRRX2inGcKUBK DuyUZH6NSSFdU35rNVJz8t+vO+yF+rDyB7faIZxTKCYvBPVQTzwqbL6NX9AG3GTBfteHGz idEOWRMKsuB2x0026kUWgjX8jIZ91v8kZ5MXyoYvpq96CtrXV5MahJvvRB6Hug== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1702590126; 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=EjNlI5JonKv0m/kINdXCywSbWYOfTvFxrSFxNOQW5Ko=; b=F1l2H1G/fVUwDSZT60vtw3F6/tqAwdlqkl2Nn/lHaRx4HraBC0vfmiFsvJOZUmAE6vQqJM g6/09CwYWZ8gPIDg== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v3 07/14] printk: Add this_cpu_in_panic() Date: Thu, 14 Dec 2023 22:47:54 +0106 Message-Id: <20231214214201.499426-8-john.ogness@linutronix.de> In-Reply-To: <20231214214201.499426-1-john.ogness@linutronix.de> References: <20231214214201.499426-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" There is already panic_in_progress() and other_cpu_in_panic(), but checking if the current CPU is the panic CPU must still be open coded. Add this_cpu_in_panic() to complete the set. Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- kernel/printk/internal.h | 1 + kernel/printk/printk.c | 43 +++++++++++++++++++++------------------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h index 6c2afee5ef62..ac2d9750e5f8 100644 --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h @@ -130,6 +130,7 @@ struct printk_message { }; =20 bool other_cpu_in_panic(void); +bool this_cpu_in_panic(void); bool printk_get_next_message(struct printk_message *pmsg, u64 seq, bool is_extended, bool may_supress); =20 diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 22bb45d8f2f2..82dc2c7949b7 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -347,6 +347,29 @@ static bool panic_in_progress(void) return unlikely(atomic_read(&panic_cpu) !=3D PANIC_CPU_INVALID); } =20 +/* Return true if a panic is in progress on the current CPU. */ +bool this_cpu_in_panic(void) +{ + /* + * We can use raw_smp_processor_id() here because it is impossible for + * the task to be migrated to the panic_cpu, or away from it. If + * panic_cpu has already been set, and we're not currently executing on + * that CPU, then we never will be. + */ + return unlikely(atomic_read(&panic_cpu) =3D=3D raw_smp_processor_id()); +} + +/* + * Return true if a panic is in progress on a remote CPU. + * + * On true, the local CPU should immediately release any printing resources + * that may be needed by the panic CPU. + */ +bool other_cpu_in_panic(void) +{ + return (panic_in_progress() && !this_cpu_in_panic()); +} + /* * This is used for debugging the mess that is the VT code by * keeping track if we have the console semaphore held. It's @@ -2592,26 +2615,6 @@ static int console_cpu_notify(unsigned int cpu) return 0; } =20 -/* - * Return true if a panic is in progress on a remote CPU. - * - * On true, the local CPU should immediately release any printing resources - * that may be needed by the panic CPU. - */ -bool other_cpu_in_panic(void) -{ - if (!panic_in_progress()) - return false; - - /* - * We can use raw_smp_processor_id() here because it is impossible for - * the task to be migrated to the panic_cpu, or away from it. If - * panic_cpu has already been set, and we're not currently executing on - * that CPU, then we never will be. - */ - return atomic_read(&panic_cpu) !=3D raw_smp_processor_id(); -} - /** * console_lock - block the console subsystem from printing * --=20 2.39.2 From nobody Sat Dec 27 22:51:33 2025 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 D9F086E2C0 for ; Thu, 14 Dec 2023 21:42:10 +0000 (UTC) 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="Um+KStAI"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="QiXbx7oE" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1702590127; 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=dulH4uTFGHjZfiwmh5wTwYSUbBhMPUk3D6gHo+246W0=; b=Um+KStAIeVeli6ubkyXVvhUMFOAS+CGHsj0pasba2RsNvgIJw6sMPi6+2Vl8+YxYNV55aQ Da1wq69Q1xiAHokJ9oILGdhGR5TZQxwJTSBizELnIG3HKzRamrshLvpLNA/+M1JmcR5q53 VxjgXE2dr8QYemoKKg7U5rxSrUgive0oXyomTR7Wf1vn0Z7Y75VR20+NmhymkVi7zOcevk lzUtmXaEyZCRhIPQPcU7V1y9BadI4EN8LaeawoE7tktDmktre7YG9MaCEu9TicCDFSeR/N iYmWkn0KTiQIgHKzgWKs7UzoUNtO13GD28o2yRJLQ7j0G8Ev4WFJlTN8NWIMOQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1702590127; 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=dulH4uTFGHjZfiwmh5wTwYSUbBhMPUk3D6gHo+246W0=; b=QiXbx7oE4vDke9/uZ44k7k21fMsLQKRToJN9tPxb+hM7GI2qYu0A5+vThpVToe1d2Ki58B 5EpLq38dMFioq3DQ== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v3 08/14] printk: ringbuffer: Cleanup reader terminology Date: Thu, 14 Dec 2023 22:47:55 +0106 Message-Id: <20231214214201.499426-9-john.ogness@linutronix.de> In-Reply-To: <20231214214201.499426-1-john.ogness@linutronix.de> References: <20231214214201.499426-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" With the lockless ringbuffer, it is allowed that multiple CPUs/contexts write simultaneously into the buffer. This creates an ambiguity as some writers will finalize sooner. The documentation for the prb_read functions is not clear as it refers to "not yet written" and "no data available". Clarify the return values and language to be in terms of the reader: records available for reading. Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- kernel/printk/printk_ringbuffer.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/kernel/printk/printk_ringbuffer.c b/kernel/printk/printk_ringb= uffer.c index 244d991ffd73..67ee1c62fcd6 100644 --- a/kernel/printk/printk_ringbuffer.c +++ b/kernel/printk/printk_ringbuffer.c @@ -1987,11 +1987,13 @@ u64 prb_first_seq(struct printk_ringbuffer *rb) } =20 /* - * Non-blocking read of a record. Updates @seq to the last finalized record - * (which may have no data available). + * Non-blocking read of a record. * - * See the description of prb_read_valid() and prb_read_valid_info() - * for details. + * On success @seq is updated to the record that was read and (if provided) + * @r and @line_count will contain the read/calculated data. + * + * On failure @seq is updated to a record that is not yet available to the + * reader, but it will be the next record available to the reader. */ static bool _prb_read_valid(struct printk_ringbuffer *rb, u64 *seq, struct printk_record *r, unsigned int *line_count) @@ -2010,7 +2012,7 @@ static bool _prb_read_valid(struct printk_ringbuffer = *rb, u64 *seq, *seq =3D tail_seq; =20 } else if (err =3D=3D -ENOENT) { - /* Record exists, but no data available. Skip. */ + /* Record exists, but the data was lost. Skip. */ (*seq)++; =20 } else { @@ -2043,7 +2045,7 @@ static bool _prb_read_valid(struct printk_ringbuffer = *rb, u64 *seq, * On success, the reader must check r->info.seq to see which record was * actually read. This allows the reader to detect dropped records. * - * Failure means @seq refers to a not yet written record. + * Failure means @seq refers to a record not yet available to the reader. */ bool prb_read_valid(struct printk_ringbuffer *rb, u64 seq, struct printk_record *r) @@ -2073,7 +2075,7 @@ bool prb_read_valid(struct printk_ringbuffer *rb, u64= seq, * On success, the reader must check info->seq to see which record meta da= ta * was actually read. This allows the reader to detect dropped records. * - * Failure means @seq refers to a not yet written record. + * Failure means @seq refers to a record not yet available to the reader. */ bool prb_read_valid_info(struct printk_ringbuffer *rb, u64 seq, struct printk_info *info, unsigned int *line_count) --=20 2.39.2 From nobody Sat Dec 27 22:51:33 2025 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 42DDA6E2D7 for ; Thu, 14 Dec 2023 21:42:11 +0000 (UTC) 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="BGFw4z8G"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="XW50EL5e" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1702590127; 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=pUhEFAmqLD7ygnXJGj4vVb5QLJptqeAU+A1URy+61A8=; b=BGFw4z8GXTG4+lXC2XhFYg47yYM3CZpM/hEavqQBtMYFlcUsezpwQwfgstX/dLMKaQPqAk Z3yLT4SaRfXts6yLQZpFODk385p9MjdU0/GUe2/Nzw7HLbwZk2hi8wBoRlChg4f6KWXSU2 BVNwX92MW37LW4liOvI1cd8eS7zfqoSHgqLAwdJ+YiJwf+EWP/bBiQSaNNKouagjbXNKqC r2BWFLDIMvrYexCKnv9hyAXUsE/mdpS7INtMSDM1hwVTqwvFpoQE+1Ml3xGSDNXuqiF4AT xeR8RozDa8ABAe0UJnJ5XgW4iU+PEVM88VH5lTcNagQNSd7Sb6e2y1oppm8/0g== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1702590127; 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=pUhEFAmqLD7ygnXJGj4vVb5QLJptqeAU+A1URy+61A8=; b=XW50EL5elAICRmd/Vsrw95l0aW3NnSv38FOMtMx45k9bOkCSWFuwpl8xYGdvVInIYvcT2O 3hpo244AZTdrJ5AA== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v3 09/14] printk: Wait for all reserved records with pr_flush() Date: Thu, 14 Dec 2023 22:47:56 +0106 Message-Id: <20231214214201.499426-10-john.ogness@linutronix.de> In-Reply-To: <20231214214201.499426-1-john.ogness@linutronix.de> References: <20231214214201.499426-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 pr_flush() will only wait for records that were available to readers at the time of the call (using prb_next_seq()). But there may be more records (non-finalized) that have following finalized records. pr_flush() should wait for these to print as well. Particularly because any trailing finalized records may be the messages that the calling context wants to ensure are printed. Add a new ringbuffer function prb_next_reserve_seq() to return the sequence number following the most recently reserved record. This guarantees that pr_flush() will wait until all current printk() messages (completed or in progress) have been printed. Fixes: 3b604ca81202 ("printk: add pr_flush()") Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- kernel/printk/printk.c | 2 +- kernel/printk/printk_ringbuffer.c | 113 ++++++++++++++++++++++++++++++ kernel/printk/printk_ringbuffer.h | 1 + 3 files changed, 115 insertions(+), 1 deletion(-) diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 82dc2c7949b7..f3a7f5a6f6f8 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -3755,7 +3755,7 @@ static bool __pr_flush(struct console *con, int timeo= ut_ms, bool reset_on_progre =20 might_sleep(); =20 - seq =3D prb_next_seq(prb); + seq =3D prb_next_reserve_seq(prb); =20 /* Flush the consoles so that records up to @seq are printed. */ console_lock(); diff --git a/kernel/printk/printk_ringbuffer.c b/kernel/printk/printk_ringb= uffer.c index 67ee1c62fcd6..b7748d7c44c1 100644 --- a/kernel/printk/printk_ringbuffer.c +++ b/kernel/printk/printk_ringbuffer.c @@ -1986,6 +1986,119 @@ u64 prb_first_seq(struct printk_ringbuffer *rb) return seq; } =20 +/** + * prb_next_reserve_seq() - Get the sequence number after the most recently + * reserved record. + * + * @rb: The ringbuffer to get the sequence number from. + * + * This is the public function available to readers to see what sequence + * number will be assigned to the next reserved record. + * + * Note that depending on the situation, this value can be equal to or + * higher than the sequence number returned by prb_next_seq(). + * + * Context: Any context. + * Return: The sequence number that will be assigned to the next record + * reserved. + */ +u64 prb_next_reserve_seq(struct printk_ringbuffer *rb) +{ + struct prb_desc_ring *desc_ring =3D &rb->desc_ring; + unsigned long last_finalized_id; + atomic_long_t *state_var; + u64 last_finalized_seq; + unsigned long head_id; + struct prb_desc desc; + unsigned long diff; + struct prb_desc *d; + int err; + + /* + * It may not be possible to read a sequence number for @head_id. + * So the ID of @last_finailzed_seq is used to calculate what the + * sequence number of @head_id will be. + */ + +try_again: + last_finalized_seq =3D desc_last_finalized_seq(rb); + + /* + * @head_id is loaded after @last_finalized_seq to ensure that it is + * at or beyond @last_finalized_seq. + * + * Memory barrier involvement: + * + * If desc_last_finalized_seq:A reads from + * desc_update_last_finalized:A, then + * prb_next_reserve_seq:A reads from desc_reserve:D. + * + * Relies on: + * + * RELEASE from desc_reserve:D to desc_update_last_finalized:A + * matching + * ACQUIRE from desc_last_finalized_seq:A to prb_next_reserve_seq:A + * + * Note: desc_reserve:D and desc_update_last_finalized:A can be + * different CPUs. However, the desc_update_last_finalized:A CPU + * (which performs the release) must have previously seen + * desc_read:C, which implies desc_reserve:D can be seen. + */ + head_id =3D atomic_long_read(&desc_ring->head_id); /* LMM(prb_next_reserv= e_seq:A) */ + + d =3D to_desc(desc_ring, last_finalized_seq); + state_var =3D &d->state_var; + + /* Extract the ID, used to specify the descriptor to read. */ + last_finalized_id =3D DESC_ID(atomic_long_read(state_var)); + + /* Ensure @last_finalized_id is correct. */ + err =3D desc_read_finalized_seq(desc_ring, last_finalized_id, last_finali= zed_seq, &desc); + + if (err =3D=3D -EINVAL) { + if (last_finalized_seq =3D=3D 0) { + /* + * @last_finalized_seq still contains its initial + * value. Probably no record has been finalized yet. + * This means the ringbuffer is not yet full and the + * @head_id value can be used directly (subtracting + * off the id value corresponding to seq=3D0). + */ + + /* + * Because of hack#2 of the bootstrapping phase, the + * @head_id initial value must be handled separately. + */ + if (head_id =3D=3D DESC0_ID(desc_ring->count_bits)) + return 0; + + /* + * The @head_id is initialized such that the first + * increment will yield the first record (seq=3D0). + * Therefore use the initial value +1 as the base to + * subtract from @head_id. + */ + last_finalized_id =3D DESC0_ID(desc_ring->count_bits) + 1; + } else { + /* Record must have been overwritten. Try again. */ + goto try_again; + } + } + + /* + * @diff is the number of records beyond the last record available + * to readers. + */ + diff =3D head_id - last_finalized_id; + + /* + * @head_id points to the most recently reserved record, but this + * function returns the sequence number that will be assigned to the + * next (not yet reserved) record. Thus +1 is needed. + */ + return (last_finalized_seq + diff + 1); +} + /* * Non-blocking read of a record. * diff --git a/kernel/printk/printk_ringbuffer.h b/kernel/printk/printk_ringb= uffer.h index d49460f7578e..52626d0f1fa3 100644 --- a/kernel/printk/printk_ringbuffer.h +++ b/kernel/printk/printk_ringbuffer.h @@ -395,6 +395,7 @@ bool prb_read_valid_info(struct printk_ringbuffer *rb, = u64 seq, u64 prb_first_seq(struct printk_ringbuffer *rb); u64 prb_first_valid_seq(struct printk_ringbuffer *rb); u64 prb_next_seq(struct printk_ringbuffer *rb); +u64 prb_next_reserve_seq(struct printk_ringbuffer *rb); =20 #ifdef CONFIG_64BIT =20 --=20 2.39.2 From nobody Sat Dec 27 22:51:33 2025 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 42E446E2D9 for ; Thu, 14 Dec 2023 21:42:11 +0000 (UTC) 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="3XPgKbTY"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="y8/Gtj27" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1702590127; 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=AOpz80KH0gOIPorBUANVFFuEUm2IlzR04QH0UC2n8ec=; b=3XPgKbTYjsOSZZI8Z0yrQGgswsqfMiaE7LTZuoZlvjGuK0QB2uH+6eWXptBrjF0N1QXiNz XZ2QDMG0/8fkf4dRt8pddUR6G1VYuX2DjCbBCMX8gYVUUcM8YnZH9ZNil23NZ3KV7NIEAV oUXhE88cRwHF4MzdPo45kcwPU/vppvgtM8XkZdCtxDkeqEaIw3dD1t/nV6i41/WK7M58fn mGLa4m71D/jZOOCzeKiEbdBbVTAUPUHQqPVz7Rps+6UBq4XFf7GhhrIOAfhAxZ1VMy4mw3 lVw2boR0W/FUVmYQ17ZoQ8oOdAV2wh/pto+a4EDaVr00NGltAoAWE6pvIMEf4w== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1702590127; 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=AOpz80KH0gOIPorBUANVFFuEUm2IlzR04QH0UC2n8ec=; b=y8/Gtj27CBD6NJc0FZUEREShj5VIVtIJaLWUgTsuCtS9F+eakMLN6S2Rqku02qW3KLc87y aGeNAXVmuQ5UbiAQ== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v3 10/14] printk: ringbuffer: Skip non-finalized records in panic Date: Thu, 14 Dec 2023 22:47:57 +0106 Message-Id: <20231214214201.499426-11-john.ogness@linutronix.de> In-Reply-To: <20231214214201.499426-1-john.ogness@linutronix.de> References: <20231214214201.499426-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" Normally a reader will stop once reaching a non-finalized record. However, when a panic happens, writers from other CPUs (or an interrupted context on the panic CPU) may have been writing a record and were unable to finalize it. The panic CPU will reserve/commit/finalize its panic records, but these will be located after the non-finalized records. This results in panic() not flushing the panic messages. Extend _prb_read_valid() to skip over non-finalized records if on the panic CPU. Fixes: 896fbe20b4e2 ("printk: use the lockless ringbuffer") Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- kernel/printk/printk_ringbuffer.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/kernel/printk/printk_ringbuffer.c b/kernel/printk/printk_ringb= uffer.c index b7748d7c44c1..d6ed33683b8b 100644 --- a/kernel/printk/printk_ringbuffer.c +++ b/kernel/printk/printk_ringbuffer.c @@ -2107,6 +2107,10 @@ u64 prb_next_reserve_seq(struct printk_ringbuffer *r= b) * * On failure @seq is updated to a record that is not yet available to the * reader, but it will be the next record available to the reader. + * + * Note: When the current CPU is in panic, this function will skip over any + * non-existent/non-finalized records in order to allow the panic CPU + * to print any and all records that have been finalized. */ static bool _prb_read_valid(struct printk_ringbuffer *rb, u64 *seq, struct printk_record *r, unsigned int *line_count) @@ -2129,8 +2133,28 @@ static bool _prb_read_valid(struct printk_ringbuffer= *rb, u64 *seq, (*seq)++; =20 } else { - /* Non-existent/non-finalized record. Must stop. */ - return false; + /* + * Non-existent/non-finalized record. Must stop. + * + * For panic situations it cannot be expected that + * non-finalized records will become finalized. But + * there may be other finalized records beyond that + * need to be printed for a panic situation. If this + * is the panic CPU, skip this + * non-existent/non-finalized record unless it is + * at or beyond the head, in which case it is not + * possible to continue. + * + * Note that new messages printed on panic CPU are + * finalized when we are here. The only exception + * might be the last message without trailing newline. + * But it would have the sequence number returned + * by "prb_next_reserve_seq() - 1". + */ + if (this_cpu_in_panic() && ((*seq + 1) < prb_next_reserve_seq(rb))) + (*seq)++; + else + return false; } } =20 --=20 2.39.2 From nobody Sat Dec 27 22:51:33 2025 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 4572B6E2DB for ; Thu, 14 Dec 2023 21:42:11 +0000 (UTC) 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="rYKzl1gL"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="E4nJ9zge" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1702590128; 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=w+Rj9ow8fovhfkl47C5quy90KNsRy8XmYEJxuaPSPxc=; b=rYKzl1gLfyiH9IJP+TFLliwyltsoWallmmQO2rIWW8Z/fGewTSWXqFjmYrmYTF+CeN4zKV wPontEoTCZuXFuB3Ybr6bj8SPuuXyeVscircT/Ol/ro4/4dtG60znLbdixzbjBmpbJlFq3 J3TKHO8N6BO1RKK25l+KflE1Xq/GC2yT5PjTw3ZWCPgmMuFfXHba9D9gMifVHVXsifgcar /6IPOTBBy9xorvPK9ZfRGwCxypgXJ6rrybFNb9io6crG3P4hKA5Ph1junGYvzLOycp+ckA d1JYd/lzSbUDSdRQ2G9pcAEg7G9bpuDMUoSFxsEw+Kaq+kojiFKqWrbCnXIIhg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1702590128; 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=w+Rj9ow8fovhfkl47C5quy90KNsRy8XmYEJxuaPSPxc=; b=E4nJ9zgeLAGTpX7uf+GwQSKNUOUmHjHZFCXuM4dmVdN4NYPZT8iNldWycwr5Ytv/BL7qeg JD1ZUoqpcg9ry0DQ== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v3 11/14] printk: ringbuffer: Consider committed as finalized in panic Date: Thu, 14 Dec 2023 22:47:58 +0106 Message-Id: <20231214214201.499426-12-john.ogness@linutronix.de> In-Reply-To: <20231214214201.499426-1-john.ogness@linutronix.de> References: <20231214214201.499426-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" A descriptor in the committed state means the record does not yet exist for the reader. However, for the panic CPU, committed records should be handled as finalized records since they contain message data in a consistent state and may contain additional hints as to the cause of the panic. Add an exception for records in the commit state to not be considered non-existing when reading from the panic CPU. Signed-off-by: John Ogness --- kernel/printk/printk_ringbuffer.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/kernel/printk/printk_ringbuffer.c b/kernel/printk/printk_ringb= uffer.c index d6ed33683b8b..e7b808b829a0 100644 --- a/kernel/printk/printk_ringbuffer.c +++ b/kernel/printk/printk_ringbuffer.c @@ -1857,6 +1857,8 @@ static bool copy_data(struct prb_data_ring *data_ring, * descriptor. However, it also verifies that the record is finalized and = has * the sequence number @seq. On success, 0 is returned. * + * For the panic CPU, committed descriptors are also considered finalized. + * * Error return values: * -EINVAL: A finalized record with sequence number @seq does not exist. * -ENOENT: A finalized record with sequence number @seq exists, but its d= ata @@ -1875,16 +1877,25 @@ static int desc_read_finalized_seq(struct prb_desc_= ring *desc_ring, =20 /* * An unexpected @id (desc_miss) or @seq mismatch means the record - * does not exist. A descriptor in the reserved or committed state - * means the record does not yet exist for the reader. + * does not exist. A descriptor in the reserved state means the + * record does not yet exist for the reader. */ if (d_state =3D=3D desc_miss || d_state =3D=3D desc_reserved || - d_state =3D=3D desc_committed || s !=3D seq) { return -EINVAL; } =20 + /* + * A descriptor in the committed state means the record does not yet + * exist for the reader. However, for the panic CPU, committed + * records are also handled as finalized records since they contain + * message data in a consistent state and may contain additional + * hints as to the cause of the panic. + */ + if (d_state =3D=3D desc_committed && !this_cpu_in_panic()) + return -EINVAL; + /* * A descriptor in the reusable state may no longer have its data * available; report it as existing but with lost data. Or the record --=20 2.39.2 From nobody Sat Dec 27 22:51:33 2025 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 463FD6E2DD for ; Thu, 14 Dec 2023 21:42:11 +0000 (UTC) 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="tv9svISY"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="I/fIFq+C" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1702590128; 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=5gccnnm0QINuqJ5Q69vjwoN8uCr8tb4sBQoCznhnpik=; b=tv9svISYbQXkoRePsS+M089g14wfdhxM4HHUsK+JwLPSbUtHs9Oo4otPG1X4ctpuCo92lv +Egv1fOKFhbHDtSyvl3sGOiZjMm75TXwyiMqtkHdo/HTc3MHPt1H0sZvE+AiodYv1Jtq+m HhgCENbsxbC7YKL0n06eqds4KlnUdHLqj8Ai6CIgUdXMbv+nLP6yo+38BipdjZxa8UhgHC FNquv+2VA+vhroxEm255Xmi8Qmx4LeMFa1jKa4+4E1Ad5dtayOeNPHN4NNZWCxZoJTykqV mv3gIgoBgFaB2h3VF/HyNi7Abxgev8Qof7x7DL/z/Q0pr3KPslMpAkch1wJVrA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1702590128; 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=5gccnnm0QINuqJ5Q69vjwoN8uCr8tb4sBQoCznhnpik=; b=I/fIFq+CG8/UDnQj2JPgMa4ksS360/MfB8fZoC9axu75aBKifTSPv3TlZlcgKQJStcIqsE CKlnl5yoUg2E2BCg== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v3 12/14] printk: Disable passing console lock owner completely during panic() Date: Thu, 14 Dec 2023 22:47:59 +0106 Message-Id: <20231214214201.499426-13-john.ogness@linutronix.de> In-Reply-To: <20231214214201.499426-1-john.ogness@linutronix.de> References: <20231214214201.499426-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 The commit d51507098ff91 ("printk: disable optimistic spin during panic") added checks to avoid becoming a console waiter if a panic is in progress. However, the transition to panic can occur while there is already a waiter. The current owner should not pass the lock to the waiter because it might get stopped or blocked anytime. Also the panic context might pass the console lock owner to an already stopped waiter by mistake. It might happen when console_flush_on_panic() ignores the current lock owner, for example: CPU0 CPU1 ---- ---- console_lock_spinning_enable() console_trylock_spinning() [CPU1 now console waiter] NMI: panic() panic_other_cpus_shutdown() [stopped as console waiter] console_flush_on_panic() console_lock_spinning_enable() [print 1 record] console_lock_spinning_disable_and_check() [handover to stopped CPU1] This results in panic() not flushing the panic messages. Fix these problems by disabling all spinning operations completely during panic(). Another advantage is that it prevents possible deadlocks caused by "console_owner_lock". The panic() context does not need to take it any longer. The lockless checks are safe because the functions become NOPs when they see the panic in progress. All operations manipulating the state are still synchronized by the lock even when non-panic CPUs would notice the panic synchronously. The current owner might stay spinning. But non-panic() CPUs would get stopped anyway and the panic context will never start spinning. Fixes: dbdda842fe96 ("printk: Add console owner and waiter logic to load ba= lance console writes") Signed-off-by: Petr Mladek Signed-off-by: John Ogness --- kernel/printk/printk.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index f3a7f5a6f6f8..cb99c854a648 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -1869,10 +1869,23 @@ static bool console_waiter; */ static void console_lock_spinning_enable(void) { + /* + * Do not use spinning in panic(). The panic CPU wants to keep the lock. + * Non-panic CPUs abandon the flush anyway. + * + * Just keep the lockdep annotation. The panic-CPU should avoid + * taking console_owner_lock because it might cause a deadlock. + * This looks like the easiest way how to prevent false lockdep + * reports without handling races a lockless way. + */ + if (panic_in_progress()) + goto lockdep; + raw_spin_lock(&console_owner_lock); console_owner =3D current; raw_spin_unlock(&console_owner_lock); =20 +lockdep: /* The waiter may spin on us after setting console_owner */ spin_acquire(&console_owner_dep_map, 0, 0, _THIS_IP_); } @@ -1897,6 +1910,22 @@ static int console_lock_spinning_disable_and_check(i= nt cookie) { int waiter; =20 + /* + * Ignore spinning waiters during panic() because they might get stopped + * or blocked at any time, + * + * It is safe because nobody is allowed to start spinning during panic + * in the first place. If there has been a waiter then non panic CPUs + * might stay spinning. They would get stopped anyway. The panic context + * will never start spinning and an interrupted spin on panic CPU will + * never continue. + */ + if (panic_in_progress()) { + /* Keep lockdep happy. */ + spin_release(&console_owner_dep_map, _THIS_IP_); + return 0; + } + raw_spin_lock(&console_owner_lock); waiter =3D READ_ONCE(console_waiter); console_owner =3D NULL; --=20 2.39.2 From nobody Sat Dec 27 22:51:33 2025 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 DF1496E58E for ; Thu, 14 Dec 2023 21:42:11 +0000 (UTC) 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="IczEGKqF"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="EZ/nLN6F" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1702590128; 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=X4rvWoxnqgzEuAgNoYI/eGkAegsSWbGumqPznFMqF+U=; b=IczEGKqFD1oy+Qg8z9W3ASm1EtJPsy0YWe3mtabbGGlNNi+1YViu93FrmJd/s0YY/mjwVv IbjcDUoXwTMgDkjFvNEIMdAs3d2wRqq22t6BgChFhGJ/ipARopaROpvgZbQQiFta1P8oJ3 86G1akAsb0XQkl/xgOrcdboEkLI2tqDe+uIrsXsYhlxxKS+ThW6/LpoDksG4VC/MqlZeMW lUvFe1M6o66t4WVMSlikkgtaooz6ztl0xuVce+klfEvFeuvHqjDK68JtT5J63BuDEKsDO1 KeC3A2M09eVmkhhXjlCuT9ICK97N/q7lGJ4YzNcUFyHFIQPCKx9EIv1XvRbakA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1702590128; 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=X4rvWoxnqgzEuAgNoYI/eGkAegsSWbGumqPznFMqF+U=; b=EZ/nLN6FZnFW+QHK6HtPkCdu30khYWm1kLAFdRJgMDfIsfceHUVNIecPc9cscZ9BaccODt phCyLhtqdyFnt1Ag== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v3 13/14] printk: Avoid non-panic CPUs writing to ringbuffer Date: Thu, 14 Dec 2023 22:48:00 +0106 Message-Id: <20231214214201.499426-14-john.ogness@linutronix.de> In-Reply-To: <20231214214201.499426-1-john.ogness@linutronix.de> References: <20231214214201.499426-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" Commit 13fb0f74d702 ("printk: Avoid livelock with heavy printk during panic") introduced a mechanism to silence non-panic CPUs if too many messages are being dropped. Aside from trying to workaround the livelock bugs of legacy consoles, it was also intended to avoid losing panic messages. However, if non-panic CPUs are writing to the ringbuffer, then reacting to dropped messages is too late. To avoid losing panic CPU messages, silence non-panic CPUs immediately on panic. Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- kernel/printk/printk.c | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index cb99c854a648..1685a71f3f71 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -462,12 +462,6 @@ static int console_msg_format =3D MSG_FORMAT_DEFAULT; static DEFINE_MUTEX(syslog_lock); =20 #ifdef CONFIG_PRINTK -/* - * During panic, heavy printk by other CPUs can delay the - * panic and risk deadlock on console resources. - */ -static int __read_mostly suppress_panic_printk; - DECLARE_WAIT_QUEUE_HEAD(log_wait); /* All 3 protected by @syslog_lock. */ /* the next printk record to read by syslog(READ) or /proc/kmsg */ @@ -2322,7 +2316,12 @@ asmlinkage int vprintk_emit(int facility, int level, if (unlikely(suppress_printk)) return 0; =20 - if (unlikely(suppress_panic_printk) && other_cpu_in_panic()) + /* + * The messages on the panic CPU are the most important. If + * non-panic CPUs are generating any messages, they will be + * silently dropped. + */ + if (other_cpu_in_panic()) return 0; =20 if (level =3D=3D LOGLEVEL_SCHED) { @@ -2799,8 +2798,6 @@ void console_prepend_dropped(struct printk_message *p= msg, unsigned long dropped) bool printk_get_next_message(struct printk_message *pmsg, u64 seq, bool is_extended, bool may_suppress) { - static int panic_console_dropped; - struct printk_buffers *pbufs =3D pmsg->pbufs; const size_t scratchbuf_sz =3D sizeof(pbufs->scratchbuf); const size_t outbuf_sz =3D sizeof(pbufs->outbuf); @@ -2828,17 +2825,6 @@ bool printk_get_next_message(struct printk_message *= pmsg, u64 seq, pmsg->seq =3D r.info->seq; pmsg->dropped =3D r.info->seq - seq; =20 - /* - * Check for dropped messages in panic here so that printk - * suppression can occur as early as possible if necessary. - */ - if (pmsg->dropped && - panic_in_progress() && - panic_console_dropped++ > 10) { - suppress_panic_printk =3D 1; - pr_warn_once("Too many dropped messages. Suppress messages on non-panic = CPUs to prevent livelock.\n"); - } - /* Skip record that has level above the console loglevel. */ if (may_suppress && suppress_message_printing(r.info->level)) goto out; --=20 2.39.2 From nobody Sat Dec 27 22:51:33 2025 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 C54866E58B for ; Thu, 14 Dec 2023 21:42:11 +0000 (UTC) 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="yErQmSVa"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="dDrnk0pC" From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1702590129; 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=/oXCn644qxpD8FMpAqd87EWn4tyrdJdGrCu1+KrDVIM=; b=yErQmSVaMfHU6Ut0SEf2M9UrFhXD9j0kjQV3rjWR+rqsZaRuPnqIGH+/+FYhiB7Htqqb29 yxaTR7aEz/PPEAxvz2mSUJvMHkZGYz8RpgI4rAcnaUowr3ErKV0ABZpqnGVn7dz6R7zShG fqGLTasMEoAFZm7wtYSBs+AFqqs3nSn1KR8FnPxDNIY+vNTVBoMEFc1R5swNBo7n6TrQa1 MV86Wenak/8A6p4+FLFqBC8T3JbzuLCYF1MjRQDb0Z/zk8QBH3vkCOm3Ak7C+Q2M4kK9hj 6AYcNCsjG+jnCZ9RzJBFI5+EhKjf2YMkl3Gdf6N5KBS9d+HS8zrSZZ2FjXk0WA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1702590129; 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=/oXCn644qxpD8FMpAqd87EWn4tyrdJdGrCu1+KrDVIM=; b=dDrnk0pCjG5yxf/tj6SXs8Ji2aYRRfbnhY4f4NyzYMRs3Z1mUilD+Qi2DKWl2C+h99oUHp Y9t649zENTvgbxBQ== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Andrew Morton , Peter Zijlstra , Josh Poimboeuf , Ingo Molnar , "Guilherme G. Piccoli" , Kefeng Wang , Kees Cook , Uros Bizjak , Arnd Bergmann Subject: [PATCH printk v3 14/14] panic: Flush kernel log buffer at the end Date: Thu, 14 Dec 2023 22:48:01 +0106 Message-Id: <20231214214201.499426-15-john.ogness@linutronix.de> In-Reply-To: <20231214214201.499426-1-john.ogness@linutronix.de> References: <20231214214201.499426-1-john.ogness@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" If the kernel crashes in a context where printk() calls always defer printing (such as in NMI or inside a printk_safe section) then the final panic messages will be deferred to irq_work. But if irq_work is not available, the messages will not get printed unless explicitly flushed. The result is that the final "end Kernel panic" banner does not get printed. Add one final flush after the last printk() call to make sure the final panic messages make it out as well. Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- kernel/panic.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/kernel/panic.c b/kernel/panic.c index 2807639aab51..f22d8f33ea14 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -446,6 +446,14 @@ void panic(const char *fmt, ...) =20 /* Do not scroll important messages printed above */ suppress_printk =3D 1; + + /* + * The final messages may not have been printed if in a context that + * defers printing (such as NMI) and irq_work is not available. + * Explicitly flush the kernel log buffer one last time. + */ + console_flush_on_panic(CONSOLE_FLUSH_PENDING); + local_irq_enable(); for (i =3D 0; ; i +=3D PANIC_TIMER_STEP) { touch_softlockup_watchdog(); --=20 2.39.2