mirror of
https://github.com/OpenVoiceOS/OpenVoiceOS
synced 2025-02-08 07:58:47 +01:00
144 lines
4.4 KiB
Diff
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
|
|
|