summaryrefslogtreecommitdiff
path: root/arch/um/kernel/kmsg_dump.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/kernel/kmsg_dump.c')
-rw-r--r--arch/um/kernel/kmsg_dump.c47
1 files changed, 34 insertions, 13 deletions
diff --git a/arch/um/kernel/kmsg_dump.c b/arch/um/kernel/kmsg_dump.c
index 98bdf69e4c2e..fc0f543d1d8e 100644
--- a/arch/um/kernel/kmsg_dump.c
+++ b/arch/um/kernel/kmsg_dump.c
@@ -1,42 +1,63 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/kmsg_dump.h>
+#include <linux/spinlock.h>
#include <linux/console.h>
+#include <linux/string.h>
#include <shared/init.h>
#include <shared/kern.h>
#include <os.h>
static void kmsg_dumper_stdout(struct kmsg_dumper *dumper,
- enum kmsg_dump_reason reason)
+ struct kmsg_dump_detail *detail)
{
+ static struct kmsg_dump_iter iter;
+ static DEFINE_SPINLOCK(lock);
static char line[1024];
-
+ struct console *con;
+ unsigned long flags;
size_t len = 0;
- bool con_available = false;
-
- /* only dump kmsg when no console is available */
- if (!console_trylock())
- return;
+ int cookie;
- if (console_drivers != NULL)
- con_available = true;
+ /*
+ * If no consoles are available to output crash information, dump
+ * the kmsg buffer to stdout.
+ */
- console_unlock();
+ cookie = console_srcu_read_lock();
+ for_each_console_srcu(con) {
+ /*
+ * The ttynull console and disabled consoles are ignored
+ * since they cannot output. All other consoles are
+ * expected to output the crash information.
+ */
+ if (strcmp(con->name, "ttynull") != 0 &&
+ console_is_usable(con, console_srcu_read_flags(con), true)) {
+ break;
+ }
+ }
+ console_srcu_read_unlock(cookie);
+ if (con)
+ return;
- if (con_available == true)
+ if (!spin_trylock_irqsave(&lock, flags))
return;
+ kmsg_dump_rewind(&iter);
+
printf("kmsg_dump:\n");
- while (kmsg_dump_get_line(dumper, true, line, sizeof(line), &len)) {
+ while (kmsg_dump_get_line(&iter, true, line, sizeof(line), &len)) {
line[len] = '\0';
printf("%s", line);
}
+
+ spin_unlock_irqrestore(&lock, flags);
}
static struct kmsg_dumper kmsg_dumper = {
.dump = kmsg_dumper_stdout
};
-int __init kmsg_dumper_stdout_init(void)
+static int __init kmsg_dumper_stdout_init(void)
{
return kmsg_dump_register(&kmsg_dumper);
}