Re: [RFC PATCH v1] panic: Flush unsafe consoles before panic reboot
From: John Ogness
Date: Mon Nov 02 2026 - 17:15:18 EST
On 2026-10-30, Breno Leitao <leitao@xxxxxxxxxx> wrote:
> diff --git a/kernel/crash_core.c b/kernel/crash_core.c
> index d0bd2d0cf8990b..d00a8ce5cb618c 100644
> --- a/kernel/crash_core.c
> +++ b/kernel/crash_core.c
> @@ -140,6 +140,13 @@ void __noclone __crash_kexec(struct pt_regs *regs)
>
> crash_setup_regs(&fixed_regs, regs);
> crash_save_vmcoreinfo();
> + /*
> + * Flush the unsafe consoles with the other CPUs
> + * stopped, before machine_crash_shutdown() tears
> + * down what they may need.
> + */
> + crash_smp_send_stop();
I advise against this if it is just for console flushing since it is
changing behavior. If it is generally a good idea, then ok.
> + nbcon_atomic_unsafe_only_flush();
> machine_crash_shutdown(&fixed_regs);
> crash_cma_clear_pending_dma();
> machine_kexec(kexec_crash_image);
> diff --git a/kernel/panic.c b/kernel/panic.c
> index 91e48d33b7dbbd..e14b1b60828130 100644
> --- a/kernel/panic.c
> +++ b/kernel/panic.c
> @@ -723,6 +723,9 @@ void vpanic(const char *fmt, va_list args)
> panic_console_replay)
> console_flush_on_panic(CONSOLE_REPLAY_ALL);
>
> + /* The other CPUs are stopped, flush the unsafe consoles too.
> + nbcon_atomic_unsafe_only_flush();
> +
As Petr mentioned, this is too early. It should be after the final
printk().
> if (!panic_blink)
> panic_blink = no_blink;
>
> diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c
> index 5f8afaca886650..a43143eca1a015 100644
> --- a/kernel/printk/nbcon.c
> +++ b/kernel/printk/nbcon.c
> @@ -1653,8 +1653,9 @@ static void nbcon_atomic_flush_pending_con(struct console *con, u64 stop_seq)
> * __nbcon_atomic_flush_pending - Flush all nbcon consoles using their
> * write_atomic() callback
> * @stop_seq: Flush up until this record
> + * @unsafe_only: Flush only the CON_NBCON_ATOMIC_UNSAFE consoles
> */
> -static void __nbcon_atomic_flush_pending(u64 stop_seq)
> +static void __nbcon_atomic_flush_pending(u64 stop_seq, bool unsafe_only)
> {
> struct console *con;
> int cookie;
> @@ -1666,6 +1667,9 @@ static void __nbcon_atomic_flush_pending(u64 stop_seq)
> if (!(flags & CON_NBCON))
> continue;
>
> + if (unsafe_only && !(flags & CON_NBCON_ATOMIC_UNSAFE))
> + continue;
> +
> if (!console_is_usable(con, flags, true))
> continue;
>
> @@ -1688,7 +1692,7 @@ static void __nbcon_atomic_flush_pending(u64 stop_seq)
> */
> void nbcon_atomic_flush_pending(void)
> {
> - __nbcon_atomic_flush_pending(prb_next_reserve_seq(prb));
> + __nbcon_atomic_flush_pending(prb_next_reserve_seq(prb), false);
> }
>
> /**
> @@ -1701,7 +1705,21 @@ void nbcon_atomic_flush_pending(void)
> void nbcon_atomic_flush_unsafe(void)
> {
> panic_nbcon_allow_unsafe_takeover = true;
> - __nbcon_atomic_flush_pending(prb_next_reserve_seq(prb));
> + __nbcon_atomic_flush_pending(prb_next_reserve_seq(prb), false);
> + panic_nbcon_allow_unsafe_takeover = false;
> +}
> +
> +/**
> + * nbcon_atomic_unsafe_only_flush - Flush only the CON_NBCON_ATOMIC_UNSAFE
> + * consoles, allowing unsafe hostile takeovers
> + *
> + * Like nbcon_atomic_flush_unsafe(), but consoles with a safe write_atomic()
> + * are left alone. Meant for the panic CPU once the other CPUs are stopped.
> + */
> +void nbcon_atomic_unsafe_only_flush(void)
> +{
> + panic_nbcon_allow_unsafe_takeover = true;
> + __nbcon_atomic_flush_pending(prb_next_reserve_seq(prb), true);
> panic_nbcon_allow_unsafe_takeover = false;
> }
The rest looks ok to me.
John