From: Calvin Owens <calvin@wbinvd.org>
To: John Ogness <john.ogness@linutronix.de>,
Breno Leitao <leitao@debian.org>
Cc: Mike Galbraith <efault@gmx.de>, Simon Horman <horms@kernel.org>,
kuba@kernel.org, Pavel Begunkov <asml.silence@gmail.com>,
Johannes Berg <johannes@sipsolutions.net>,
paulmck@kernel.org, LKML <linux-kernel@vger.kernel.org>,
netdev@vger.kernel.org, boqun.feng@gmail.com
Subject: Re: netconsole: HARDIRQ-safe -> HARDIRQ-unsafe lock order warning
Date: Mon, 8 Sep 2025 13:27:05 -0700 [thread overview]
Message-ID: <aL88Gb6R5M3zhMTb@mozart.vkv.me> (raw)
In-Reply-To: <84a539f4kf.fsf@jogness.linutronix.de>
On Friday 09/05 at 14:54 +0206, John Ogness wrote:
> <snip>
>
> NBCON is meant to deprecate @oops_in_progress. However, it is true that
> consoles not implementing ->write_atomic() will never print panic
> output.
Below is a silly little testcase that makes it more convenient to test
if crashes are getting out in a few canned cases, in case anyone else
finds it useful.
Testing this on 6.17-rc5 on a Pi 4b, I don't get any netconsole output
at all for any crash case over wifi, so that already doesn't work. All
the cases currently work over ethernet.
----8<----
From: Calvin Owens <calvin@wbinvd.org>
Subject: [PATCH] Quick and dirty testcase for netconsole (and other consoles)
Signed-off-by: Calvin Owens <calvin@wbinvd.org>
---
drivers/tty/Kconfig | 9 ++
drivers/tty/Makefile | 1 +
drivers/tty/crashtest.c | 178 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 188 insertions(+)
create mode 100644 drivers/tty/crashtest.c
diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig
index 149f3d53b760..c0f58943202c 100644
--- a/drivers/tty/Kconfig
+++ b/drivers/tty/Kconfig
@@ -424,6 +424,15 @@ config RPMSG_TTY
To compile this driver as a module, choose M here: the module will be
called rpmsg_tty.
+config CRASHTEST
+ tristate "Empirical testcase for console crash output"
+ help
+ Say Y to expose a file at /sys/kernel/debug/crashtest which allows
+ the kernel to be deliberately crashed in various execution contexts to
+ prove crash traces can be successfully emitted on the console.
+
+ To compile this driver as a module, choose M here. If unsure, say N.
+
endif # TTY
source "drivers/tty/serdev/Kconfig"
diff --git a/drivers/tty/Makefile b/drivers/tty/Makefile
index 07aca5184a55..0448b8285079 100644
--- a/drivers/tty/Makefile
+++ b/drivers/tty/Makefile
@@ -27,5 +27,6 @@ obj-$(CONFIG_GOLDFISH_TTY) += goldfish.o
obj-$(CONFIG_MIPS_EJTAG_FDC_TTY) += mips_ejtag_fdc.o
obj-$(CONFIG_VCC) += vcc.o
obj-$(CONFIG_RPMSG_TTY) += rpmsg_tty.o
+obj-$(CONFIG_CRASHTEST) += crashtest.o
obj-y += ipwireless/
diff --git a/drivers/tty/crashtest.c b/drivers/tty/crashtest.c
new file mode 100644
index 000000000000..a7b90300d906
--- /dev/null
+++ b/drivers/tty/crashtest.c
@@ -0,0 +1,178 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * # cat /sys/kernel/debug/crashtest
+ * crash_user
+ * crash_user_nobh
+ * crash_user_noirq
+ * crash_user_conlock
+ * crash_user_rtnllock
+ * crash_bh
+ * crash_irq
+ * # echo "crash_user" > /sys/kernel/debug/crashtest
+ */
+
+#include <linux/console.h>
+#include <linux/debugfs.h>
+#include <linux/irq_work.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/rtnetlink.h>
+#include <linux/string.h>
+
+static ssize_t __crash(void)
+{
+ pr_emerg("BANG!\n");
+ *(volatile unsigned char *)NULL = '!';
+ return -ENOSYS;
+}
+
+static void __crash_irq_work(struct irq_work *work)
+{
+ __crash();
+}
+
+static struct irq_work irq_crash_work;
+
+static ssize_t crash_irq(void)
+{
+ if (!irq_work_queue(&irq_crash_work))
+ return -EBUSY;
+
+ irq_work_sync(&irq_crash_work);
+ return -ENOSYS;
+}
+
+static void __crash_bh_work(struct work_struct *work)
+{
+ __crash();
+}
+
+static struct work_struct bh_crash_work;
+
+static ssize_t crash_bh(void)
+{
+ if (!queue_work(system_bh_wq, &bh_crash_work))
+ return -EBUSY;
+
+ flush_work(&bh_crash_work);
+ return -ENOSYS;
+}
+
+static ssize_t crash_user(void)
+{
+ return __crash();
+}
+
+static ssize_t crash_user_nobh(void)
+{
+ local_bh_disable();
+ return crash_user();
+}
+
+static ssize_t crash_user_noirq(void)
+{
+ local_irq_disable();
+ return crash_user();
+}
+
+static ssize_t crash_user_conlock(void)
+{
+ console_lock();
+ return crash_user();
+}
+
+static ssize_t crash_user_rtnllock(void)
+{
+ rtnl_lock();
+ return crash_user();
+}
+
+struct crashtest_case {
+ ssize_t (*fn)(void);
+ const char *str;
+};
+
+#define CRASHTEST_CASE(fn_) \
+ (struct crashtest_case){.fn = fn_, .str = #fn_ "\n"}
+
+static const struct crashtest_case tests[] = {
+ CRASHTEST_CASE(crash_user),
+ CRASHTEST_CASE(crash_user_nobh),
+ CRASHTEST_CASE(crash_user_noirq),
+ CRASHTEST_CASE(crash_user_conlock),
+ CRASHTEST_CASE(crash_user_rtnllock),
+ CRASHTEST_CASE(crash_bh),
+ CRASHTEST_CASE(crash_irq),
+};
+
+static ssize_t crashtest_write(struct file *file, const char __user *u_buf,
+ size_t u_len, loff_t *u_off)
+{
+ char buf[32] = {0};
+ unsigned i;
+
+ if (copy_from_user(buf, u_buf, min(u_len, sizeof(buf) - 1)) != 0)
+ return -EFAULT;
+
+ for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
+ if (!strcmp(tests[i].str, buf))
+ return tests[i].fn();
+
+ return -EEXIST;
+}
+
+static ssize_t crashtest_read(struct file *file, char __user *u_buf,
+ size_t u_len, loff_t *u_off)
+{
+ ssize_t ret = 0;
+ unsigned i;
+
+ if (*u_off > 0)
+ return 0;
+
+ for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
+ unsigned long len, done;
+
+ len = strlen(tests[i].str);
+ done = len - copy_to_user(u_buf, tests[i].str, min(u_len, len));
+ u_len -= done;
+ u_buf += done;
+ ret += done;
+ if (done != len)
+ break;
+ }
+
+ *u_off += ret;
+ return ret;
+}
+
+static const struct file_operations crashtest_fops = {
+ .write = crashtest_write,
+ .read = crashtest_read,
+};
+
+static struct dentry *crashtest_dentry;
+
+static int __init setup_crashtest(void)
+{
+ INIT_WORK(&bh_crash_work, __crash_bh_work);
+ init_irq_work(&irq_crash_work, __crash_irq_work);
+ crashtest_dentry = debugfs_create_file("crashtest", 0600, NULL, NULL,
+ &crashtest_fops);
+ if (IS_ERR(crashtest_dentry))
+ return PTR_ERR(crashtest_dentry);
+
+ return 0;
+}
+
+static void __exit cleanup_crashtest(void)
+{
+ debugfs_remove(crashtest_dentry);
+}
+
+late_initcall(setup_crashtest);
+module_exit(cleanup_crashtest);
+
+MODULE_AUTHOR("Calvin Owens <calvin@wbinvd.org>");
+MODULE_DESCRIPTION("Empirical testcase for console crash output");
+MODULE_LICENSE("GPL");
--
2.47.2
next prev parent reply other threads:[~2025-09-08 20:27 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-13 4:14 Mike Galbraith
2025-08-14 10:16 ` Breno Leitao
2025-08-14 15:45 ` Pavel Begunkov
2025-08-15 0:23 ` Jakub Kicinski
2025-08-15 10:44 ` Pavel Begunkov
2025-08-15 16:42 ` Jakub Kicinski
2025-08-15 17:29 ` Breno Leitao
2025-08-15 17:33 ` Jakub Kicinski
2025-08-18 12:23 ` Breno Leitao
2025-08-15 19:10 ` Calvin Owens
2025-08-16 9:19 ` Mike Galbraith
2025-08-15 20:02 ` Pavel Begunkov
2025-08-18 12:10 ` Breno Leitao
2025-08-19 17:27 ` Breno Leitao
2025-08-20 12:31 ` Mike Galbraith
2025-08-20 17:36 ` Breno Leitao
2025-08-21 3:37 ` Mike Galbraith
2025-08-21 3:51 ` Mike Galbraith
2025-08-21 17:35 ` Breno Leitao
2025-08-22 3:54 ` Mike Galbraith
2025-08-26 12:43 ` Breno Leitao
2025-08-26 13:56 ` Mike Galbraith
2025-09-05 12:48 ` John Ogness
2025-09-06 2:32 ` Mike Galbraith
2025-09-08 13:30 ` John Ogness
2025-09-08 15:18 ` Mike Galbraith
2025-09-08 20:27 ` Calvin Owens [this message]
2025-09-09 15:49 ` Mike Galbraith
2025-09-10 15:51 ` Petr Mladek
2025-09-09 12:50 ` Breno Leitao
2025-09-10 12:22 ` John Ogness
2025-09-10 15:12 ` Petr Mladek
2025-09-10 18:26 ` Breno Leitao
2025-09-30 13:57 ` Calvin Owens
2025-09-30 14:23 ` John Ogness
2025-09-30 14:30 ` Sebastian Siewior
2025-09-30 17:35 ` Mike Galbraith
2025-10-01 6:00 ` Mike Galbraith
2025-09-11 13:03 ` John Ogness
2025-09-10 18:23 ` Breno Leitao
2025-09-11 13:13 ` John Ogness
2025-08-21 10:06 ` Mike Galbraith
2025-08-21 13:12 ` Mike Galbraith
2025-08-15 17:37 ` Calvin Owens
2025-08-26 14:10 ` Johannes Berg
2025-08-15 12:45 ` Mike Galbraith
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aL88Gb6R5M3zhMTb@mozart.vkv.me \
--to=calvin@wbinvd.org \
--cc=asml.silence@gmail.com \
--cc=boqun.feng@gmail.com \
--cc=efault@gmx.de \
--cc=horms@kernel.org \
--cc=johannes@sipsolutions.net \
--cc=john.ogness@linutronix.de \
--cc=kuba@kernel.org \
--cc=leitao@debian.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=paulmck@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®