1
1
mirror of https://github.com/OpenVoiceOS/OpenVoiceOS synced 2025-02-08 07:58:47 +01:00
OpenVoiceOS/buildroot-external/patches/linux/0142-printk-Coordinate-direct-printing-in-panic.patch

144 lines
4.4 KiB
Diff

From 3607ce2a07c3d015cfa9990bca4141c9cdd316ce Mon Sep 17 00:00:00 2001
From: John Ogness <john.ogness@linutronix.de>
Date: Wed, 22 Nov 2023 11:56:58 +0000
Subject: [PATCH 142/195] printk: Coordinate direct printing in panic
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 | 2 ++
kernel/panic.c | 2 ++
kernel/printk/printk.c | 53 ++++++++++++++++++++++++++++++++++++------
3 files changed, 50 insertions(+), 7 deletions(-)
diff --git a/include/linux/printk.h b/include/linux/printk.h
index e26dcf63efb1..cf545b76131f 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -782,3 +782,5 @@ static inline void print_hex_dump_debug(const char *prefix_str, int prefix_type,
print_hex_dump_debug(prefix_str, prefix_type, 16, 1, buf, len, true)
#endif
+
+void printk_legacy_allow_panic_sync(void);
diff --git a/kernel/panic.c b/kernel/panic.c
index 219b69fbe829..f0e91a0c4001 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -366,6 +366,8 @@ void panic(const char *fmt, ...)
*/
atomic_notifier_call_chain(&panic_notifier_list, 0, buf);
+ printk_legacy_allow_panic_sync();
+
panic_print_sys_info(false);
kmsg_dump(KMSG_DUMP_PANIC);
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index e84da28db173..9c2e26ce16f9 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -2330,12 +2330,23 @@ int vprintk_store(int facility, int level,
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.
+ */
+void printk_legacy_allow_panic_sync(void)
+{
+ legacy_allow_panic_sync = true;
+}
+
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))
@@ -2351,15 +2362,43 @@ asmlinkage int vprintk_emit(int facility, int level,
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_boot_console && have_nbcon_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/console_unlock dance must be relied upon
+ * instead because nbcon consoles cannot print simultaneously
+ * with boot consoles.
+ */
+ if (is_panic_context)
+ nbcon_atomic_flush_all();
+ }
+
+ if (do_trylock_unlock) {
/*
* The caller may be holding system-critical or
* timing-sensitive locks. Disable preemption during
@@ -2379,10 +2418,10 @@ asmlinkage int vprintk_emit(int facility, int level,
preempt_enable();
}
- if (in_sched)
- defer_console_output();
- else
+ if (do_trylock_unlock)
wake_up_klogd();
+ else
+ defer_console_output();
return printed_len;
}
--
2.43.0