Messages in this thread Patch in this message | | | From | John Ogness <> | Subject | [PATCH printk v4 05/39] printk: fix setting first seq for consoles | Date | Mon, 14 Nov 2022 17:34:58 +0106 |
| |
It used to be that all consoles were synchronized with respect to which message they were printing. After commit a699449bb13b ("printk: refactor and rework printing logic"), all consoles have their own @seq for tracking which message they are on. That commit also changed how the initial sequence number was chosen. Instead of choosing the next non-printed message, it chose the sequence number of the next message that will be added to the ringbuffer.
That change created a possibility that a non-boot console taking over for a boot console might skip messages if the boot console was behind and did not have a chance to catch up before being unregistered.
Since it is not possible to know which boot console a console is taking over, use the lowest @seq of all the enabled boot consoles. If no boot consoles are available/enabled, begin with the next message that will be added to the ringbuffer.
Also, since boot consoles are meant to be used at boot time, handle them the same as CON_PRINTBUFFER to ensure that no initial messages are skipped.
Signed-off-by: John Ogness <john.ogness@linutronix.de> --- kernel/printk/printk.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 3d449dfb1ed6..8dbf3461cba0 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -3222,14 +3222,31 @@ void register_console(struct console *newcon) } newcon->dropped = 0; - if (newcon->flags & CON_PRINTBUFFER) { + if (newcon->flags & (CON_PRINTBUFFER | CON_BOOT)) { /* Get a consistent copy of @syslog_seq. */ mutex_lock(&syslog_lock); newcon->seq = syslog_seq; mutex_unlock(&syslog_lock); } else { - /* Begin with next message. */ + /* Begin with next message added to ringbuffer. */ newcon->seq = prb_next_seq(prb); + + /* + * If any enabled boot consoles are due to be unregistered + * shortly, some may not be caught up and may be the same + * device as @newcon. Since it is not known which boot console + * is the same device, start with the message of the enabled + * boot console that is the furthest behind. + */ + if (bootcon_registered && !keep_bootcon) { + for_each_console(con) { + if ((con->flags & CON_BOOT) && + (con->flags & CON_ENABLED) && + con->seq < newcon->seq) { + newcon->seq = con->seq; + } + } + } } /* -- 2.30.2
| |