[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20231221133953.1507021-1-sreenath.vijayan@sony.com>
Date: Thu, 21 Dec 2023 19:09:53 +0530
From: Sreenath Vijayan <sreenath.vijayan@...y.com>
To: linux-doc@...r.kernel.org, linux-serial@...r.kernel.org, corbet@....net,
gregkh@...uxfoundation.org, jirislaby@...nel.org
Cc: linux-kernel@...r.kernel.org, anandakumar.balasubramaniam@...y.com,
Sreenath Vijayan <sreenath.vijayan@...y.com>,
Shimoyashiki Taichi <taichi.shimoyashiki@...y.com>
Subject: [PATCH] tty/sysrq: Dump kernel ring buffer messages via sysrq
When terminal is unresponsive, one cannot use dmesg to view kernel
ring buffer messages. Also, syslog services may be disabled,
to check them after a reboot, especially on embedded systems.
In this scenario, dump the kernel ring buffer messages via sysrq
by pressing sysrq+D.
Signed-off-by: Sreenath Vijayan <sreenath.vijayan@...y.com>
Signed-off-by: Shimoyashiki Taichi <taichi.shimoyashiki@...y.com>
---
Documentation/admin-guide/sysrq.rst | 2 ++
drivers/tty/sysrq.c | 43 ++++++++++++++++++++++++++++-
2 files changed, 44 insertions(+), 1 deletion(-)
diff --git a/Documentation/admin-guide/sysrq.rst b/Documentation/admin-guide/sysrq.rst
index 2f2e5bd440f9..464c4e138b9d 100644
--- a/Documentation/admin-guide/sysrq.rst
+++ b/Documentation/admin-guide/sysrq.rst
@@ -161,6 +161,8 @@ Command Function
will be printed to your console. (``0``, for example would make
it so that only emergency messages like PANICs or OOPSes would
make it to your console.)
+
+``D`` Dump the kernel ring buffer
=========== ===================================================================
Okay, so what can I use them for?
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
index 02217e3c916b..aa43cb40c117 100644
--- a/drivers/tty/sysrq.c
+++ b/drivers/tty/sysrq.c
@@ -51,6 +51,8 @@
#include <linux/syscalls.h>
#include <linux/of.h>
#include <linux/rcupdate.h>
+#include <linux/kmsg_dump.h>
+#include <linux/console.h>
#include <asm/ptrace.h>
#include <asm/irq_regs.h>
@@ -450,6 +452,45 @@ static const struct sysrq_key_op sysrq_unrt_op = {
.enable_mask = SYSRQ_ENABLE_RTNICE,
};
+static void dmesg_dump_callback(struct work_struct *work)
+{
+ struct kmsg_dump_iter iter;
+ size_t len;
+ char buf[1024];
+ struct console *con;
+ int cookie;
+
+ kmsg_dump_rewind(&iter);
+ while (kmsg_dump_get_line(&iter, 1, buf, sizeof(buf), &len)) {
+ /*
+ * Since using printk() or pr_*() will append the message to the
+ * kernel ring buffer, they cannot be used to display the retrieved
+ * message. Hence console_write() of serial drivers is used.
+ */
+ console_lock();
+ cookie = console_srcu_read_lock();
+ for_each_console_srcu(con) {
+ if ((console_srcu_read_flags(con) & CON_ENABLED) && con->write)
+ con->write(con, buf, len);
+ }
+ console_srcu_read_unlock(cookie);
+ console_unlock();
+ }
+}
+
+static DECLARE_WORK(sysrq_dmesg_work, dmesg_dump_callback);
+
+static void sysrq_handle_dmesg_dump(u8 key)
+{
+ queue_work(system_unbound_wq, &sysrq_dmesg_work);
+}
+static struct sysrq_key_op sysrq_dmesg_dump_op = {
+ .handler = sysrq_handle_dmesg_dump,
+ .help_msg = "dump-dmesg(D)",
+ .action_msg = "Dump dmesg",
+ .enable_mask = SYSRQ_ENABLE_DUMP,
+};
+
/* Key Operations table and lock */
static DEFINE_SPINLOCK(sysrq_key_table_lock);
@@ -505,7 +546,7 @@ static const struct sysrq_key_op *sysrq_key_table[62] = {
NULL, /* A */
NULL, /* B */
NULL, /* C */
- NULL, /* D */
+ &sysrq_dmesg_dump_op, /* D */
NULL, /* E */
NULL, /* F */
NULL, /* G */
--
2.42.0
Powered by blists - more mailing lists