diff options
Diffstat (limited to 'debian/patches-rt/0027-printk-Coordinate-direct-printing-in-panic.patch')
-rw-r--r-- | debian/patches-rt/0027-printk-Coordinate-direct-printing-in-panic.patch | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/debian/patches-rt/0027-printk-Coordinate-direct-printing-in-panic.patch b/debian/patches-rt/0027-printk-Coordinate-direct-printing-in-panic.patch new file mode 100644 index 0000000000..4893dd463f --- /dev/null +++ b/debian/patches-rt/0027-printk-Coordinate-direct-printing-in-panic.patch @@ -0,0 +1,163 @@ +From: John Ogness <john.ogness@linutronix.de> +Date: Wed, 22 Nov 2023 11:56:58 +0000 +Subject: [PATCH 27/48] printk: Coordinate direct printing in panic +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/6.8/older/patches-6.8.2-rt11.tar.xz + +Perform printing by nbcon consoles on the panic CPU from the +printk() caller context in order to get panic messages printed +as soon as possible. + +If legacy and nbcon consoles are registered, the legacy consoles +will no longer perform direct printing on the panic CPU until +after the backtrace has been stored. This will give the safe +nbcon consoles a chance to print the panic messages before +allowing the unsafe legacy consoles to print. + +If no nbcon consoles are registered, there is no change in +behavior (i.e. legacy consoles will always attempt to print +from the printk() caller context). + +Signed-off-by: John Ogness <john.ogness@linutronix.de> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + include/linux/printk.h | 5 +++ + kernel/panic.c | 2 + + kernel/printk/printk.c | 62 ++++++++++++++++++++++++++++++++++++++++++------- + 3 files changed, 61 insertions(+), 8 deletions(-) + +--- a/include/linux/printk.h ++++ b/include/linux/printk.h +@@ -195,6 +195,7 @@ void show_regs_print_info(const char *lo + extern asmlinkage void dump_stack_lvl(const char *log_lvl) __cold; + extern asmlinkage void dump_stack(void) __cold; + void printk_trigger_flush(void); ++void printk_legacy_allow_panic_sync(void); + extern void nbcon_driver_acquire(struct console *con); + extern void nbcon_driver_release(struct console *con); + void nbcon_atomic_flush_unsafe(void); +@@ -278,6 +279,10 @@ static inline void printk_trigger_flush( + { + } + ++static inline void printk_legacy_allow_panic_sync(void) ++{ ++} ++ + static inline void nbcon_driver_acquire(struct console *con) + { + } +--- a/kernel/panic.c ++++ b/kernel/panic.c +@@ -364,6 +364,8 @@ void panic(const char *fmt, ...) + + panic_other_cpus_shutdown(_crash_kexec_post_notifiers); + ++ printk_legacy_allow_panic_sync(); ++ + /* + * Run any panic handlers, including those that might need to + * add information to the kmsg dump output. +--- a/kernel/printk/printk.c ++++ b/kernel/printk/printk.c +@@ -471,7 +471,9 @@ static DEFINE_MUTEX(syslog_lock); + static bool have_legacy_console; + + /* +- * Specifies if an nbcon console is registered. ++ * Specifies if an nbcon console is registered. If nbcon consoles are present, ++ * synchronous printing of legacy consoles will not occur during panic until ++ * the backtrace has been stored to the ringbuffer. + */ + static bool have_nbcon_console; + +@@ -2335,12 +2337,29 @@ int vprintk_store(int facility, int leve + return ret; + } + ++static bool legacy_allow_panic_sync; ++ ++/* ++ * This acts as a one-way switch to allow legacy consoles to print from ++ * the printk() caller context on a panic CPU. It also attempts to flush ++ * the legacy consoles in this context. ++ */ ++void printk_legacy_allow_panic_sync(void) ++{ ++ legacy_allow_panic_sync = true; ++ ++ if (printing_via_unlock && !in_nmi()) { ++ if (console_trylock()) ++ console_unlock(); ++ } ++} ++ + asmlinkage int vprintk_emit(int facility, int level, + const struct dev_printk_info *dev_info, + const char *fmt, va_list args) + { ++ bool do_trylock_unlock = printing_via_unlock; + int printed_len; +- bool in_sched = false; + + /* Suppress unimportant messages after panic happens */ + if (unlikely(suppress_printk)) +@@ -2356,15 +2375,42 @@ asmlinkage int vprintk_emit(int facility + + if (level == LOGLEVEL_SCHED) { + level = LOGLEVEL_DEFAULT; +- in_sched = true; ++ /* If called from the scheduler, we can not call up(). */ ++ do_trylock_unlock = false; + } + + printk_delay(level); + + printed_len = vprintk_store(facility, level, dev_info, fmt, args); + +- /* If called from the scheduler, we can not call up(). */ +- if (!in_sched && printing_via_unlock) { ++ if (have_nbcon_console && !have_boot_console) { ++ bool is_panic_context = this_cpu_in_panic(); ++ ++ /* ++ * In panic, the legacy consoles are not allowed to print from ++ * the printk calling context unless explicitly allowed. This ++ * gives the safe nbcon consoles a chance to print out all the ++ * panic messages first. This restriction only applies if ++ * there are nbcon consoles registered. ++ */ ++ if (is_panic_context) ++ do_trylock_unlock &= legacy_allow_panic_sync; ++ ++ /* ++ * There are situations where nbcon atomic printing should ++ * happen in the printk() caller context: ++ * ++ * - When this CPU is in panic. ++ * ++ * Note that if boot consoles are registered, the console ++ * lock/unlock dance must be relied upon instead because nbcon ++ * consoles cannot print simultaneously with boot consoles. ++ */ ++ if (is_panic_context) ++ nbcon_atomic_flush_pending(); ++ } ++ ++ if (do_trylock_unlock) { + /* + * The caller may be holding system-critical or + * timing-sensitive locks. Disable preemption during +@@ -2384,10 +2430,10 @@ asmlinkage int vprintk_emit(int facility + preempt_enable(); + } + +- if (in_sched) +- defer_console_output(); +- else ++ if (do_trylock_unlock) + wake_up_klogd(); ++ else ++ defer_console_output(); + + return printed_len; + } |