From nobody Wed Sep 17 06:42:28 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 39D9EC4332F for ; Wed, 21 Dec 2022 20:28:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234884AbiLUU2B (ORCPT ); Wed, 21 Dec 2022 15:28:01 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58764 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234853AbiLUU1s (ORCPT ); Wed, 21 Dec 2022 15:27:48 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AB5D325289 for ; Wed, 21 Dec 2022 12:27:45 -0800 (PST) From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1671654455; 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=5G3xENZmVjolt+mUZuerb1/7WYIT6u0len7EJM2bSQA=; b=PJDN6GMTUudEE4qCop+B0eSpJDhKhQpAwrDfuQ7CAdnJ8bRbftzotDPi1II7gSqXlkiuZI AyYuW1usB0J22wee3c4MIc0D7CrT1La9p8YiNY6tlXne+AAn+OHqevKOers3PbFsH0Gc4j FlgPgQfQ1nJcvSond6Jk17MtoUFVlDlNV86myfWgvqPVKoYjuKIyqmFVZOxjYcwFS7XDw6 l0LCRsYQsnUQAnVn6j09Dx0r0u3u8ocYVAuMut7oC33OpJ94Nq3EkDkR74A36QBAVHCWwe q+QPalrXKwY9w4YVP1n29sktkfd/0WhBc7bdKPdB65plr/Ol2A1FG/XZqHsCCg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1671654455; 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=5G3xENZmVjolt+mUZuerb1/7WYIT6u0len7EJM2bSQA=; b=IV6hMJkJVKuax53a8g6jMlIV8CTvhwCQdY1HyhB+Vdd3NKl1lTQJcwl5H/y1jYHLkvnDNE wTjUD44Fv2oPpRBw== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v3 1/6] printk: move size limit macros into internal.h Date: Wed, 21 Dec 2022 21:32:59 +0106 Message-Id: <20221221202704.857925-2-john.ogness@linutronix.de> In-Reply-To: <20221221202704.857925-1-john.ogness@linutronix.de> References: <20221221202704.857925-1-john.ogness@linutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The size limit macros are located further down in printk.c and behind ifdef macros. This complicates their usage for upcoming changes. Move the macros into internal.h so that they are still invisible outside of printk, but easily accessible for printk. Also, the maximum size of formatted extended messages does not need to be known by any code outside of printk, so move it to internal.h as well. And like CONSOLE_LOG_MAX, for !CONFIG_PRINTK set CONSOLE_EXT_LOG_MAX to 0 to reduce the static memory footprint. Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- include/linux/printk.h | 2 -- kernel/printk/internal.h | 23 +++++++++++++++++++++++ kernel/printk/printk.c | 17 ----------------- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/include/linux/printk.h b/include/linux/printk.h index 8c81806c2e99..8ef499ab3c1e 100644 --- a/include/linux/printk.h +++ b/include/linux/printk.h @@ -44,8 +44,6 @@ static inline const char *printk_skip_headers(const char = *buffer) return buffer; } =20 -#define CONSOLE_EXT_LOG_MAX 8192 - /* printk's without a loglevel use this.. */ #define MESSAGE_LOGLEVEL_DEFAULT CONFIG_MESSAGE_LOGLEVEL_DEFAULT =20 diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h index d947ca6c84f9..319bc7ee46f7 100644 --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h @@ -14,6 +14,24 @@ int devkmsg_sysctl_set_loglvl(struct ctl_table *table, i= nt write, =20 #ifdef CONFIG_PRINTK =20 +#ifdef CONFIG_PRINTK_CALLER +#define PREFIX_MAX 48 +#else +#define PREFIX_MAX 32 +#endif + +/* the maximum size of a formatted record (i.e. with prefix added per line= ) */ +#define CONSOLE_LOG_MAX 1024 + +/* the maximum size of a formatted extended record */ +#define CONSOLE_EXT_LOG_MAX 8192 + +/* the maximum size for a dropped text message */ +#define DROPPED_TEXT_MAX 64 + +/* the maximum size allowed to be reserved for a record */ +#define LOG_LINE_MAX (CONSOLE_LOG_MAX - PREFIX_MAX) + /* Flags for a single printk record. */ enum printk_info_flags { LOG_NEWLINE =3D 2, /* text ended with a newline */ @@ -48,6 +66,11 @@ u16 printk_parse_prefix(const char *text, int *level, enum printk_info_flags *flags); #else =20 +#define CONSOLE_LOG_MAX 0 +#define CONSOLE_EXT_LOG_MAX 0 +#define DROPPED_TEXT_MAX 0 +#define LOG_LINE_MAX 0 + /* * In !PRINTK builds we still export console_sem * semaphore and some of console functions (console_unlock()/etc.), so diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 7decf1e9c486..55bb065de65f 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -465,21 +465,6 @@ static struct latched_seq clear_seq =3D { .val[1] =3D 0, }; =20 -#ifdef CONFIG_PRINTK_CALLER -#define PREFIX_MAX 48 -#else -#define PREFIX_MAX 32 -#endif - -/* the maximum size of a formatted record (i.e. with prefix added per line= ) */ -#define CONSOLE_LOG_MAX 1024 - -/* the maximum size for a dropped text message */ -#define DROPPED_TEXT_MAX 64 - -/* the maximum size allowed to be reserved for a record */ -#define LOG_LINE_MAX (CONSOLE_LOG_MAX - PREFIX_MAX) - #define LOG_LEVEL(v) ((v) & 0x07) #define LOG_FACILITY(v) ((v) >> 3 & 0xff) =20 @@ -2387,8 +2372,6 @@ static bool __pr_flush(struct console *con, int timeo= ut_ms, bool reset_on_progre =20 #else /* CONFIG_PRINTK */ =20 -#define CONSOLE_LOG_MAX 0 -#define DROPPED_TEXT_MAX 0 #define printk_time false =20 #define prb_read_valid(rb, seq, r) false --=20 2.30.2 From nobody Wed Sep 17 06:42:28 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 709ECC4332F for ; Wed, 21 Dec 2022 20:27:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234869AbiLUU1t (ORCPT ); Wed, 21 Dec 2022 15:27:49 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58734 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230072AbiLUU1q (ORCPT ); Wed, 21 Dec 2022 15:27:46 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8F4CC24F36 for ; Wed, 21 Dec 2022 12:27:44 -0800 (PST) From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1671654456; 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=XbYaurIRdFG+/mjMZ4Nnsd0tE8OMeEIDH+uE2KSAjBQ=; b=cjIIarYaLNRrJ9U6jobnezJxa8LsxtUTGv6H0nvK2Zz0/oHmaL8DvY5jYMkW1hVz46Jc5B /2mAJmx1gQ1DEodvRzA6axnnYuC32/AGBMNqD6jpkiZJCRoamdPHNPLMdHtOVF5IGwijyt fFpJpcqFaAOV9E9M7TcjNnz379PenGUuoZ7XgkP6I2TQ8JebtZ5KUs/0slDpyzqNSEeC4j dRjv7B1RtcXNexb8vRb10shvgjiV35UM8J5cYdl9vA9pz4byitYhAfOl4nQE+qeUApvVUA 2GWsUFskZdGaf1CBhiNwpVSktrzg0cFhKmJrLQ0EpIJDU5WIeIq9KilCpQhqgQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1671654456; 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=XbYaurIRdFG+/mjMZ4Nnsd0tE8OMeEIDH+uE2KSAjBQ=; b=4TSiJ9Ap4RH/5TawmXK3mWI9q7LE9Be2M5rpkMiSed9fNwA00b+9qnT1Api1blU23G4aN1 OlO3YyYtzDFwMLCw== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Greg Kroah-Hartman Subject: [PATCH printk v3 2/6] console: Use BIT() macros for @flags values Date: Wed, 21 Dec 2022 21:33:00 +0106 Message-Id: <20221221202704.857925-3-john.ogness@linutronix.de> In-Reply-To: <20221221202704.857925-1-john.ogness@linutronix.de> References: <20221221202704.857925-1-john.ogness@linutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner Rather than manually calculating powers of 2, use the BIT() macros. Also take this opportunatity to cleanup and restructure the value comments into proper kerneldoc comments. Signed-off-by: Thomas Gleixner Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- include/linux/console.h | 46 ++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/include/linux/console.h b/include/linux/console.h index 9cea254b34b8..ed804dd7c2e8 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -15,6 +15,7 @@ #define _LINUX_CONSOLE_H_ 1 =20 #include +#include #include #include =20 @@ -125,18 +126,43 @@ static inline int con_debug_leave(void) /* * The interface for a console, or any other device that wants to capture * console messages (printer driver?) - * - * If a console driver is marked CON_BOOT then it will be auto-unregistered - * when the first real console is registered. This is for early-printk dr= ivers. */ =20 -#define CON_PRINTBUFFER (1) -#define CON_CONSDEV (2) /* Preferred console, /dev/console */ -#define CON_ENABLED (4) -#define CON_BOOT (8) -#define CON_ANYTIME (16) /* Safe to call when cpu is offline */ -#define CON_BRL (32) /* Used for a braille device */ -#define CON_EXTENDED (64) /* Use the extended output format a la /dev/kmsg= */ +/** + * 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. + * @CON_CONSDEV: Indicates that the console driver is backing + * /dev/console. + * @CON_ENABLED: Indicates if a console is allowed to print records. If + * false, the console also will not advance to later + * records. + * @CON_BOOT: Marks the console driver as early console driver which + * is used during boot before the real driver becomes + * available. It will be automatically unregistered + * when the real console driver is registered unless + * "keep_bootcon" parameter is used. + * @CON_ANYTIME: A misnomed historical flag which tells the core code + * that the legacy @console::write callback can be invoked + * on a CPU which is marked OFFLINE. That is misleading as + * it suggests that there is no contextual limit for + * invoking the callback. The original motivation was + * readiness of the per-CPU areas. + * @CON_BRL: Indicates a braille device which is exempt from + * receiving the printk spam for obvious reasons. + * @CON_EXTENDED: The console supports the extended output format of + * /dev/kmesg which requires a larger output buffer. + */ +enum cons_flags { + CON_PRINTBUFFER =3D BIT(0), + CON_CONSDEV =3D BIT(1), + CON_ENABLED =3D BIT(2), + CON_BOOT =3D BIT(3), + CON_ANYTIME =3D BIT(4), + CON_BRL =3D BIT(5), + CON_EXTENDED =3D BIT(6), +}; =20 struct console { char name[16]; --=20 2.30.2 From nobody Wed Sep 17 06:42:28 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D5210C4332F for ; Wed, 21 Dec 2022 20:28:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234916AbiLUU2G (ORCPT ); Wed, 21 Dec 2022 15:28:06 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58766 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234852AbiLUU1s (ORCPT ); Wed, 21 Dec 2022 15:27:48 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ABD4B2528D for ; Wed, 21 Dec 2022 12:27:45 -0800 (PST) From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1671654456; 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+UJBfU/8l7fpxJzETJJj+Hr/lkYjP0wgmBYzutEocw=; b=r4PbESKXOL3kCggBPqyUPhgRbSc8To8Kef7clkha0yXtBADOKJ4tD7scZbSKGVRBtaoXd4 9iSnQ5azRTbrzoFmgK+Gpl1KSp5MAF4YilrXzOnu1+plFbp9FomLdtXta+WoGhhlIBXtUH MSjANCfhHNIiEskP+/QcZ/tenk4pY/Hm+MUKz4qRmiYehn5EgESjgnHmwgQqgNwNo6z2gp abSKVQv+mN7XIWpnM+KTZtaRXsGk60QI6CaUvNbtL/FzOm2WnYlE5AmlAWTnXS71L70UUO z7VmfdUJpdcYg/Zps09xusOMghL84wlg/6kCrjKjIchVfNojbgztFKAv7TBO2w== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1671654456; 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+UJBfU/8l7fpxJzETJJj+Hr/lkYjP0wgmBYzutEocw=; b=ZkyOoCL+G6d76XUi8UG/eVSRiG7d37JqkdZbW0drIhSv/9/8dX6I9yJfQG/ybG1q9r4SPF gNhMhrCfU1gIi9DQ== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Greg Kroah-Hartman Subject: [PATCH printk v3 3/6] console: Document struct console Date: Wed, 21 Dec 2022 21:33:01 +0106 Message-Id: <20221221202704.857925-4-john.ogness@linutronix.de> In-Reply-To: <20221221202704.857925-1-john.ogness@linutronix.de> References: <20221221202704.857925-1-john.ogness@linutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner Add kerneldoc comments to struct console. Signed-off-by: Thomas Gleixner Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- include/linux/console.h | 54 ++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/include/linux/console.h b/include/linux/console.h index ed804dd7c2e8..1e36958aa656 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -164,24 +164,44 @@ enum cons_flags { CON_EXTENDED =3D BIT(6), }; =20 +/** + * struct console - The console descriptor structure + * @name: The name of the console driver + * @write: 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) + * @setup: Callback for initializing the console (Optional) + * @exit: Callback for teardown of the console (Optional) + * @match: Callback for matching a console (Optional) + * @flags: Console flags. See enum cons_flags + * @index: Console index, e.g. port number + * @cflag: TTY control mode flags + * @ispeed: TTY input speed + * @ospeed: TTY output speed + * @seq: Sequence number of the next ringbuffer record to print + * @dropped: Number of unreported dropped ringbuffer records + * @data: Driver private data + * @node: hlist node for the console list + */ struct console { - char name[16]; - void (*write)(struct console *, const char *, unsigned); - int (*read)(struct console *, char *, unsigned); - struct tty_driver *(*device)(struct console *, int *); - void (*unblank)(void); - int (*setup)(struct console *, char *); - int (*exit)(struct console *); - int (*match)(struct console *, char *name, int idx, char *options); - short flags; - short index; - int cflag; - uint ispeed; - uint ospeed; - u64 seq; - unsigned long dropped; - void *data; - struct hlist_node node; + char name[16]; + void (*write)(struct console *co, const char *s, unsigned int count); + int (*read)(struct console *co, char *s, unsigned int count); + struct tty_driver *(*device)(struct console *co, int *index); + void (*unblank)(void); + int (*setup)(struct console *co, char *options); + int (*exit)(struct console *co); + int (*match)(struct console *co, char *name, int idx, char *options); + short flags; + short index; + int cflag; + uint ispeed; + uint ospeed; + u64 seq; + unsigned long dropped; + void *data; + struct hlist_node node; }; =20 #ifdef CONFIG_LOCKDEP --=20 2.30.2 From nobody Wed Sep 17 06:42:28 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F0D66C4332F for ; Wed, 21 Dec 2022 20:27:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234889AbiLUU15 (ORCPT ); Wed, 21 Dec 2022 15:27:57 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58746 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234615AbiLUU1q (ORCPT ); Wed, 21 Dec 2022 15:27:46 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8F5B525285 for ; Wed, 21 Dec 2022 12:27:44 -0800 (PST) From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1671654457; 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=Q4Vu+r5yLKsl2SkQL/uUdW8OcACzMwITXivvlA5+0HQ=; b=OTUPHXXdCnU+pDU+UEMFpK3RkC7NxLKhaEygEeKyvIQaAikTHkvv9QvmqTWS4BinHKjJMo IuMcxRa+607MGRAY7STLJkEuyFm1R4bdij5vqPPQchPqWqxXVN0TrdMDw6DaeaRbpMj/YG KjrMMCTzU8tfteM2csoPoasbYIBXsMSfrwE+O6pf9pGhcFum2PdhtCKXzCCbAtr9ZZPzgj UN2HIwYKPp9q5mnWE0Gcg5F4XBwskP9zIbydNhXh3UYGVQjMG49lufvVO7/10YcrVXz5B9 d6fyfp0kElPPTyTGhSv0U6hHx7B0WmdZhPXjq82RApL+2nEROkRIy3nX+TZEaA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1671654457; 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=Q4Vu+r5yLKsl2SkQL/uUdW8OcACzMwITXivvlA5+0HQ=; b=Sr6JyXQfqOGyyrp7Pj+dFRS4t5kkf2BdCWYEDDs3O35b2wFcoLPBsZHLNeuq1SbkMr1Ina l4Xt9lN7uuhgopAw== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v3 4/6] printk: introduce struct console_buffers Date: Wed, 21 Dec 2022 21:33:02 +0106 Message-Id: <20221221202704.857925-5-john.ogness@linutronix.de> In-Reply-To: <20221221202704.857925-1-john.ogness@linutronix.de> References: <20221221202704.857925-1-john.ogness@linutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Introduce a new struct console_buffers to contain all the buffers needed to read and format a printk message for console output. Putting the buffers inside a struct reduces the number of buffer pointers that need to be tracked. Also, it allows usage of the sizeof() macro for the buffer sizes, rather than expecting certain sized buffers being passed in. Note that since the output buffer for normal consoles is now CONSOLE_EXT_LOG_MAX instead of CONSOLE_LOG_MAX, multi-line messages that may have been previously truncated will now be printed in full. This should be considered a feature and not a bug since the CONSOLE_LOG_MAX restriction was about limiting static buffer usage rather than limiting printed text. Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- kernel/printk/internal.h | 10 +++++++ kernel/printk/printk.c | 56 ++++++++++++++++++---------------------- 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h index 319bc7ee46f7..f5ebbd392fee 100644 --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h @@ -81,3 +81,13 @@ u16 printk_parse_prefix(const char *text, int *level, =20 static inline bool printk_percpu_data_ready(void) { return false; } #endif /* CONFIG_PRINTK */ + +/** + * console_buffers - Buffers to read/format/output printk messages. + * @outbuf: After formatting, contains text to output. + * @scratchbuf: Used as temporary ringbuffer reading and string-print spac= e. + */ +struct console_buffers { + char outbuf[CONSOLE_EXT_LOG_MAX]; + char scratchbuf[LOG_LINE_MAX]; +}; diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 55bb065de65f..2e5e2eda1fa1 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -2728,14 +2728,6 @@ static void __console_unlock(void) * Print one record for the given console. The record printed is whatever * record is the next available record for the given console. * - * @text is a buffer of size CONSOLE_LOG_MAX. - * - * If extended messages should be printed, @ext_text is a buffer of size - * CONSOLE_EXT_LOG_MAX. Otherwise @ext_text must be NULL. - * - * If dropped messages should be printed, @dropped_text is a buffer of size - * DROPPED_TEXT_MAX. Otherwise @dropped_text must be NULL. - * * @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. @@ -2747,17 +2739,32 @@ static void __console_unlock(void) * * Requires the console_lock and the SRCU read lock. */ -static bool console_emit_next_record(struct console *con, char *text, char= *ext_text, - char *dropped_text, bool *handover, int cookie) +static bool console_emit_next_record(struct console *con, bool *handover, = int cookie) { + bool is_extended =3D console_srcu_read_flags(con) & CON_EXTENDED; + static char dropped_text[DROPPED_TEXT_MAX]; + static struct console_buffers cbufs; + const size_t scratchbuf_sz =3D sizeof(cbufs.scratchbuf); + const size_t outbuf_sz =3D sizeof(cbufs.outbuf); + char *scratchbuf =3D &cbufs.scratchbuf[0]; + char *outbuf =3D &cbufs.outbuf[0]; static int panic_console_dropped; struct printk_info info; struct printk_record r; unsigned long flags; - char *write_text; size_t len; =20 - prb_rec_init_rd(&r, &info, text, CONSOLE_LOG_MAX); + /* + * Formatting extended messages requires a separate buffer, so use the + * scratch buffer to read in the ringbuffer text. + * + * Formatting normal messages is done in-place, so read the ringbuffer + * text directly into the output buffer. + */ + if (is_extended) + prb_rec_init_rd(&r, &info, scratchbuf, scratchbuf_sz); + else + prb_rec_init_rd(&r, &info, outbuf, outbuf_sz); =20 *handover =3D false; =20 @@ -2779,13 +2786,11 @@ static bool console_emit_next_record(struct console= *con, char *text, char *ext_ goto skip; } =20 - if (ext_text) { - write_text =3D ext_text; - len =3D info_print_ext_header(ext_text, CONSOLE_EXT_LOG_MAX, r.info); - len +=3D msg_print_ext_body(ext_text + len, CONSOLE_EXT_LOG_MAX - len, + if (is_extended) { + len =3D info_print_ext_header(outbuf, outbuf_sz, r.info); + len +=3D msg_print_ext_body(outbuf + len, outbuf_sz - len, &r.text_buf[0], r.info->text_len, &r.info->dev_info); } else { - write_text =3D text; len =3D record_print_text(&r, console_msg_format & MSG_FORMAT_SYSLOG, pr= intk_time); } =20 @@ -2803,7 +2808,8 @@ static bool console_emit_next_record(struct console *= con, char *text, char *ext_ console_lock_spinning_enable(); =20 stop_critical_timings(); /* don't trace print latency */ - call_console_driver(con, write_text, len, dropped_text); + call_console_driver(con, outbuf, len, + is_extended ? NULL : dropped_text); start_critical_timings(); =20 con->seq++; @@ -2839,9 +2845,6 @@ static bool console_emit_next_record(struct console *= con, char *text, char *ext_ */ static bool console_flush_all(bool do_cond_resched, u64 *next_seq, bool *h= andover) { - static char dropped_text[DROPPED_TEXT_MAX]; - static char ext_text[CONSOLE_EXT_LOG_MAX]; - static char text[CONSOLE_LOG_MAX]; bool any_usable =3D false; struct console *con; bool any_progress; @@ -2861,16 +2864,7 @@ static bool console_flush_all(bool do_cond_resched, = u64 *next_seq, bool *handove continue; any_usable =3D true; =20 - if (console_srcu_read_flags(con) & CON_EXTENDED) { - /* Extended consoles do not print "dropped messages". */ - progress =3D console_emit_next_record(con, &text[0], - &ext_text[0], NULL, - handover, cookie); - } else { - progress =3D console_emit_next_record(con, &text[0], - NULL, &dropped_text[0], - handover, cookie); - } + progress =3D console_emit_next_record(con, handover, cookie); =20 /* * If a handover has occurred, the SRCU read lock --=20 2.30.2 From nobody Wed Sep 17 06:42:28 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9D43EC4332F for ; Wed, 21 Dec 2022 20:28:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234927AbiLUU2M (ORCPT ); Wed, 21 Dec 2022 15:28:12 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58790 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234866AbiLUU1t (ORCPT ); Wed, 21 Dec 2022 15:27:49 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8C6AF24F2A for ; Wed, 21 Dec 2022 12:27:47 -0800 (PST) From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1671654457; 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=JpYeAsldPGyAqY4hxNmOiSJNyyD2urN7p0Yg2vrAx2c=; b=xvp7nfVsG/2UWcrRmq3FP1izPmpSS3nfNf7XsM8DFLHTcMaQKxlclgn3vj4MF63Y2fcwRB lBDcqnwdJZBDF59ZDVhf+2HYn3JfWiy0lNmDgPnE9ZVyXpvw/IlL/75BOhmoEMNGWueya0 Rvw5/VFvniQVej7shM7uckephlcKPYeOv9gaMPZzV9++d9/QXX9li5MbSP5eghwdlYkGfo +zEXfni+jHD8JSYOmDYZUqsEN+D0/COC1ulAeKTmA8RfpmkaNIQo/Rlj80v4UMnhtMNE1k aES5ugP0q1uaf4M5xESKztPeACzNwAh7M/4Vynjf3UweI/T4nVWTYQztxOlQpQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1671654457; 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=JpYeAsldPGyAqY4hxNmOiSJNyyD2urN7p0Yg2vrAx2c=; b=7PXG36TiyDcN4uGOntSv9FbBRnVA5iWktYsRZnRDlIT9BhKnjJqTQeMz8TLJG5LZ37LEEA 992Ssau2EPqDRdCA== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v3 5/6] printk: introduce console_get_next_message() and console_message Date: Wed, 21 Dec 2022 21:33:03 +0106 Message-Id: <20221221202704.857925-6-john.ogness@linutronix.de> In-Reply-To: <20221221202704.857925-1-john.ogness@linutronix.de> References: <20221221202704.857925-1-john.ogness@linutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Code for performing the console output is intermixed with code that is formatting the output for that console. Introduce a new helper function console_get_next_message() to handle the reading and formatting of the console text. The helper does not require any locking so that in the future it can be used for other console printing contexts as well. This also introduces a new struct console_message to wrap the struct console_buffers adding meta-data about its contents. This allows users of console_get_next_message() to receive all relevant information about the message that was read and formatted. The reason a wrapper struct is introduced instead of adding the meta-data to struct console_buffers is because the upcoming atomic consoles will need per-cpu and per-context console_buffers. It would not make sense to make the meta-data also per-cpu and per-context as that data can be easily stored on the stack of the console printing context. Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- kernel/printk/internal.h | 16 ++++++ kernel/printk/printk.c | 118 +++++++++++++++++++++++++++------------ 2 files changed, 97 insertions(+), 37 deletions(-) diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h index f5ebbd392fee..4f2eb8c470bc 100644 --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h @@ -91,3 +91,19 @@ struct console_buffers { char outbuf[CONSOLE_EXT_LOG_MAX]; char scratchbuf[LOG_LINE_MAX]; }; + +/** + * console_message - Container for a prepared console message. + * @cbufs: Console buffers used to prepare the message. + * @outbuf_len: The length of prepared text in @cbufs->outbuf to output. T= his + * does not count the terminator. A value of 0 means there is + * nothing to output and this record should be skipped. + * @outbuf_seq: The sequence number of the record used for @cbufs->outbuf. + * @dropped: The number of dropped records from reading @outbuf_seq. + */ +struct console_message { + struct console_buffers *cbufs; + unsigned int outbuf_len; + u64 outbuf_seq; + unsigned long dropped; +}; diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 2e5e2eda1fa1..7cac636600f8 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -2725,34 +2725,34 @@ static void __console_unlock(void) } =20 /* - * Print one record for the given console. The record printed is whatever - * record is the next available record for the given console. + * Read and format the specified record (or a later record if the specified + * record is not available). * - * @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. + * @cmsg will contain the formatted result. @cmsg->cbufs must point to a + * struct console_buffers. * - * @cookie is the cookie from the SRCU read lock. + * @seq is the record to read and format. If it is not available, the next + * valid record is read. * - * Returns false if the given console has no next record to print, otherwi= se - * true. + * @is_extended specifies the message should be formatted for extended + * console output. * - * Requires the console_lock and the SRCU read lock. + * Returns false if no record is available. Otherwise true and all fields + * of @cmsg are valid. (See the documentation of struct console_message + * for information about the @cmsg fields.) */ -static bool console_emit_next_record(struct console *con, bool *handover, = int cookie) -{ - bool is_extended =3D console_srcu_read_flags(con) & CON_EXTENDED; - static char dropped_text[DROPPED_TEXT_MAX]; - static struct console_buffers cbufs; - const size_t scratchbuf_sz =3D sizeof(cbufs.scratchbuf); - const size_t outbuf_sz =3D sizeof(cbufs.outbuf); - char *scratchbuf =3D &cbufs.scratchbuf[0]; - char *outbuf =3D &cbufs.outbuf[0]; +static bool console_get_next_message(struct console_message *cmsg, u64 seq, + bool is_extended) +{ + struct console_buffers *cbufs =3D cmsg->cbufs; + const size_t scratchbuf_sz =3D sizeof(cbufs->scratchbuf); + const size_t outbuf_sz =3D sizeof(cbufs->outbuf); + char *scratchbuf =3D &cbufs->scratchbuf[0]; + char *outbuf =3D &cbufs->outbuf[0]; static int panic_console_dropped; struct printk_info info; struct printk_record r; - unsigned long flags; - size_t len; + size_t len =3D 0; =20 /* * Formatting extended messages requires a separate buffer, so use the @@ -2766,33 +2766,77 @@ static bool console_emit_next_record(struct console= *con, bool *handover, int co else prb_rec_init_rd(&r, &info, outbuf, outbuf_sz); =20 - *handover =3D false; - - if (!prb_read_valid(prb, con->seq, &r)) + if (!prb_read_valid(prb, seq, &r)) return false; =20 - if (con->seq !=3D r.info->seq) { - con->dropped +=3D r.info->seq - con->seq; - con->seq =3D r.info->seq; - if (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"); - } + cmsg->outbuf_seq =3D r.info->seq; + cmsg->dropped =3D r.info->seq - seq; + + /* + * Check for dropped messages in panic here so that printk + * suppression can occur as early as possible if necessary. + */ + if (cmsg->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"); } =20 /* Skip record that has level above the console loglevel. */ - if (suppress_message_printing(r.info->level)) { - con->seq++; - goto skip; - } + if (suppress_message_printing(r.info->level)) + goto out; =20 if (is_extended) { len =3D info_print_ext_header(outbuf, outbuf_sz, r.info); len +=3D msg_print_ext_body(outbuf + len, outbuf_sz - len, - &r.text_buf[0], r.info->text_len, &r.info->dev_info); + r.text_buf, r.info->text_len, &r.info->dev_info); } else { len =3D record_print_text(&r, console_msg_format & MSG_FORMAT_SYSLOG, pr= intk_time); } +out: + cmsg->outbuf_len =3D len; + return true; +} + +/* + * Print one record for the given console. The record printed is whatever + * record is the next available record for the given console. + * + * @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 is the cookie from the SRCU read lock. + * + * Returns false if the given console has no next record to print, otherwi= se + * true. + * + * Requires the console_lock and the SRCU read lock. + */ +static bool console_emit_next_record(struct console *con, bool *handover, = int cookie) +{ + bool is_extended =3D console_srcu_read_flags(con) & CON_EXTENDED; + static char dropped_text[DROPPED_TEXT_MAX]; + static struct console_buffers cbufs; + static struct console_message cmsg =3D { + .cbufs =3D &cbufs, + }; + char *outbuf =3D &cbufs.outbuf[0]; + unsigned long flags; + + *handover =3D false; + + if (!console_get_next_message(&cmsg, con->seq, is_extended)) + return false; + + con->dropped +=3D cmsg.dropped; + + /* Skip messages of formatted length 0. */ + if (cmsg.outbuf_len =3D=3D 0) { + con->seq =3D cmsg.outbuf_seq + 1; + goto skip; + } =20 /* * While actively printing out messages, if another printk() @@ -2808,11 +2852,11 @@ static bool console_emit_next_record(struct console= *con, bool *handover, int co console_lock_spinning_enable(); =20 stop_critical_timings(); /* don't trace print latency */ - call_console_driver(con, outbuf, len, + call_console_driver(con, outbuf, cmsg.outbuf_len, is_extended ? NULL : dropped_text); start_critical_timings(); =20 - con->seq++; + con->seq =3D cmsg.outbuf_seq + 1; =20 *handover =3D console_lock_spinning_disable_and_check(cookie); printk_safe_exit_irqrestore(flags); --=20 2.30.2 From nobody Wed Sep 17 06:42:28 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6EA6CC4332F for ; Wed, 21 Dec 2022 20:28:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234920AbiLUU2K (ORCPT ); Wed, 21 Dec 2022 15:28:10 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58788 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234865AbiLUU1t (ORCPT ); Wed, 21 Dec 2022 15:27:49 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 855BB24F1C for ; Wed, 21 Dec 2022 12:27:47 -0800 (PST) From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1671654457; 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=QVOOi+FhBYdbpRctUmJiqLD3QlodKxzJcuWxQBTUUXw=; b=r73NfUunzkfx2+18tfEaTjjMkO/lYXl9EnpwhC4IAixPJ9o0okDb2iDIULdUR1TrdhsGg0 Av1hYoWooGLoahdtEmA27zcwgBpFM2FROFHKX5pbhz+T6/9NcEo+sr+wqFSmnw6ugf35vy ULaBODZZjRkZFFVSdH/HJHmk87gR7PZj4LPKs+gwDWYKYT7UPkeDybjaOXmxBkABp7/0OV o/pTAgTMUtXMAyx04Juo7T9Ewot2F3Awxt/6PR4gRu/1PaP3AApxQV405Y2lUIwKOEEbxm td85zd46y9/k/ad10yxlPd+8drtfidk0p3e+7KAzGnReEVK4pqFXBjmXlLxmiA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1671654457; 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=QVOOi+FhBYdbpRctUmJiqLD3QlodKxzJcuWxQBTUUXw=; b=H7Dvp85tv9KqH4VKY7PBVrsZtA2fm9FZ6EVL3lCe5Oklk6j8Zhm7XQw0IPmhf8JoEhxt9k 1YYTQ2FM2uZoKYCQ== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org Subject: [PATCH printk v3 6/6] printk: introduce console_prepend_dropped() for dropped messages Date: Wed, 21 Dec 2022 21:33:04 +0106 Message-Id: <20221221202704.857925-7-john.ogness@linutronix.de> In-Reply-To: <20221221202704.857925-1-john.ogness@linutronix.de> References: <20221221202704.857925-1-john.ogness@linutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Currently "dropped messages" are separately printed immediately before printing the printk message. Since normal consoles are now using an output buffer that is much larger than previously, the "dropped message" could be prepended to the printk message and output in a single call. Introduce a helper function console_prepend_dropped() to prepend an existing message with a "dropped message". This simplifies the code by allowing all message formatting to be handled together and then only requires a single write() call to output the full message. And since this helper does not require any locking, it can be used in the future for other console printing contexts as well. Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- kernel/printk/internal.h | 4 -- kernel/printk/printk.c | 84 ++++++++++++++++++++++++++-------------- 2 files changed, 55 insertions(+), 33 deletions(-) diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h index 4f2eb8c470bc..b0ca59e6edad 100644 --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h @@ -26,9 +26,6 @@ int devkmsg_sysctl_set_loglvl(struct ctl_table *table, in= t write, /* the maximum size of a formatted extended record */ #define CONSOLE_EXT_LOG_MAX 8192 =20 -/* the maximum size for a dropped text message */ -#define DROPPED_TEXT_MAX 64 - /* the maximum size allowed to be reserved for a record */ #define LOG_LINE_MAX (CONSOLE_LOG_MAX - PREFIX_MAX) =20 @@ -68,7 +65,6 @@ u16 printk_parse_prefix(const char *text, int *level, =20 #define CONSOLE_LOG_MAX 0 #define CONSOLE_EXT_LOG_MAX 0 -#define DROPPED_TEXT_MAX 0 #define LOG_LINE_MAX 0 =20 /* diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 7cac636600f8..f0d9c88e434f 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -1995,27 +1995,6 @@ static int console_trylock_spinning(void) return 1; } =20 -/* - * Call the specified console driver, asking it to write out the specified - * text and length. If @dropped_text is non-NULL and any records have been - * dropped, a dropped message will be written out first. - */ -static void call_console_driver(struct console *con, const char *text, siz= e_t len, - char *dropped_text) -{ - size_t dropped_len; - - if (con->dropped && dropped_text) { - dropped_len =3D snprintf(dropped_text, DROPPED_TEXT_MAX, - "** %lu printk messages dropped **\n", - con->dropped); - con->dropped =3D 0; - con->write(con, dropped_text, dropped_len); - } - - con->write(con, text, len); -} - /* * Recursion is tracked separately on each CPU. If NMIs are supported, an * additional NMI context per CPU is also separately tracked. Until per-CPU @@ -2395,10 +2374,6 @@ static ssize_t msg_print_ext_body(char *buf, size_t = size, struct dev_printk_info *dev_info) { return 0; } static void console_lock_spinning_enable(void) { } static int console_lock_spinning_disable_and_check(int cookie) { return 0;= } -static void call_console_driver(struct console *con, const char *text, siz= e_t len, - char *dropped_text) -{ -} static bool suppress_message_printing(int level) { return false; } static bool pr_flush(int timeout_ms, bool reset_on_progress) { return true= ; } static bool __pr_flush(struct console *con, int timeout_ms, bool reset_on_= progress) { return true; } @@ -2724,6 +2699,50 @@ static void __console_unlock(void) up_console_sem(); } =20 +/* + * Prepend the message in @cmsg->cbufs->outbuf with a "dropped message". T= his + * is achieved by shifting the existing message over and inserting the dro= pped + * message. + * + * @cmsg is the console message to prepend. + * + * @dropped is the dropped count to report in the dropped message. + * + * If the message text in @cmsg->cbufs->outbuf does not have enough space = for + * the dropped message, the message text will be sufficiently truncated. + * + * If @cmsg->cbufs->outbuf is modified, @cmsg->outbuf_len is updated. + */ +static void console_prepend_dropped(struct console_message *cmsg, unsigned= long dropped) +{ + struct console_buffers *cbufs =3D cmsg->cbufs; + const size_t scratchbuf_sz =3D sizeof(cbufs->scratchbuf); + const size_t outbuf_sz =3D sizeof(cbufs->outbuf); + char *scratchbuf =3D &cbufs->scratchbuf[0]; + char *outbuf =3D &cbufs->outbuf[0]; + size_t len; + + len =3D snprintf(scratchbuf, scratchbuf_sz, + "** %lu printk messages dropped **\n", dropped); + + /* + * Make sure outbuf is sufficiently large before prepending. Space + * for a terminator is also counted in case truncation occurs. + */ + if (WARN_ON_ONCE(len + 1 >=3D outbuf_sz)) + return; + + if (cmsg->outbuf_len + len >=3D outbuf_sz) { + /* Truncate the message, but keep it terminated. */ + cmsg->outbuf_len =3D outbuf_sz - (len + 1); + outbuf[cmsg->outbuf_len] =3D 0; + } + + memmove(outbuf + len, outbuf, cmsg->outbuf_len + 1); + memcpy(outbuf, scratchbuf, len); + cmsg->outbuf_len +=3D len; +} + /* * Read and format the specified record (or a later record if the specified * record is not available). @@ -2817,7 +2836,6 @@ static bool console_get_next_message(struct console_m= essage *cmsg, u64 seq, static bool console_emit_next_record(struct console *con, bool *handover, = int cookie) { bool is_extended =3D console_srcu_read_flags(con) & CON_EXTENDED; - static char dropped_text[DROPPED_TEXT_MAX]; static struct console_buffers cbufs; static struct console_message cmsg =3D { .cbufs =3D &cbufs, @@ -2838,6 +2856,11 @@ static bool console_emit_next_record(struct console = *con, bool *handover, int co goto skip; } =20 + if (con->dropped && !is_extended) { + console_prepend_dropped(&cmsg, con->dropped); + con->dropped =3D 0; + } + /* * While actively printing out messages, if another printk() * were to occur on another CPU, it may wait for this one to @@ -2851,9 +2874,12 @@ static bool console_emit_next_record(struct console = *con, bool *handover, int co printk_safe_enter_irqsave(flags); console_lock_spinning_enable(); =20 - stop_critical_timings(); /* don't trace print latency */ - call_console_driver(con, outbuf, cmsg.outbuf_len, - is_extended ? NULL : dropped_text); + /* Do not trace print latency. */ + stop_critical_timings(); + + /* Write everything out to the hardware. */ + con->write(con, outbuf, cmsg.outbuf_len); + start_critical_timings(); =20 con->seq =3D cmsg.outbuf_seq + 1; --=20 2.30.2