From: Gabriele Monaco <gmonaco@redhat.com>
To: "Thomas Weißschuh" <thomas.weissschuh@linutronix.de>,
"Nam Cao" <namcao@linutronix.de>
Cc: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org,
Steven Rostedt <rostedt@goodmis.org>,
Masami Hiramatsu <mhiramat@kernel.org>,
Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Subject: Re: [PATCH] rv: Add signal reactor
Date: Fri, 19 Sep 2025 14:26:12 +0200 [thread overview]
Message-ID: <d0aaaf1f47f0d948b60b0575e179564e3c024188.camel@redhat.com> (raw)
In-Reply-To: <20250919-rv-reactor-signal-v1-1-fb0012034158@linutronix.de>
On Fri, 2025-09-19 at 12:49 +0200, Thomas Weißschuh wrote:
> Reactions of the existing reactors are not easily detectable from programs
> and also not easily attributable to the triggering task.
> This makes it hard to test the monitors themselves programmatically.
>
> The signal reactors allows applications to validate the correct operations
> of monitors either by installing custom signal handlers or by forking a
> child and waiting for the expected exit code.
Thanks, this looks like a really nice addition!
> For now only SIGBUS is supported, but additional signals can be added.
Curious choice of a default signal, is this specific to your use-case?
We may want to add some kind of reactors options in the future to allow
configuring this, but I'd say it isn't needed for now.
> As the reactors are called from tracepoints they need to be able to run in
> any context. To avoid taking any of the looks used during signal delivery
You probably meant "locks"
> from an invalid context, schedule it through task_work. The delivery will
> be delayed, for example when then sleep monitor detects an invalid sleep.
>
> Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
> ---
> kernel/trace/rv/Kconfig | 8 +++
> kernel/trace/rv/Makefile | 1 +
> kernel/trace/rv/reactor_signal.c | 114
> +++++++++++++++++++++++++++++++++++++++
> 3 files changed, 123 insertions(+)
>
> diff --git a/kernel/trace/rv/Kconfig b/kernel/trace/rv/Kconfig
> index
> 5b4be87ba59d3fa5123a64efa746320c9e8b73b1..dc7b546615a67c811ce94c43bb1db2826cd0
> 0c77 100644
> --- a/kernel/trace/rv/Kconfig
> +++ b/kernel/trace/rv/Kconfig
> @@ -93,3 +93,11 @@ config RV_REACT_PANIC
> help
> Enables the panic reactor. The panic reactor emits a printk()
> message if an exception is found and panic()s the system.
> +
> +config RV_REACT_SIGNAL
> + bool "Signal reactor"
> + depends on RV_REACTORS
> + default y
> + help
> + Enables the signal reactor. The signal reactors sends a signal to
> the
> + task triggering an exception.
This assumption is not always correct, imagine a failure in the sleep monitor
caused by the wakeup event. The offending task is not current but the wakee.
This is a bit tricky because reactors don't have access to that task, just to
keep the same implementation between per-cpu and per-task monitors.
We may want to revise that, perhaps like Nam is doing with the monitor_target
thing [1].
Besides, I'm assuming this reactor is only meaningful for monitors written to
validate userspace tasks (signals and TWA_RESUME are probably
meaningless/dangerous for kernel threads).
I'm fine with that but you should probably mention it here and/or in the reactor
itself, since we have also monitors validating kernel behaviour (see the sched
collection).
[1] -
https://lore.kernel.org/lkml/9a1b5a8c449fcb4f1a671016389c1e4fca49a351.1754900299.git.namcao@linutronix.de
> diff --git a/kernel/trace/rv/Makefile b/kernel/trace/rv/Makefile
> index
> 42ff5d5aa9dde3ed2964e0b8d4ab7b236f498319..adf56bbd03ffa0d48de1f0d86ca5fcce1628
> bdba 100644
> --- a/kernel/trace/rv/Makefile
> +++ b/kernel/trace/rv/Makefile
> @@ -23,3 +23,4 @@ obj-$(CONFIG_RV_MON_OPID) += monitors/opid/opid.o
> obj-$(CONFIG_RV_REACTORS) += rv_reactors.o
> obj-$(CONFIG_RV_REACT_PRINTK) += reactor_printk.o
> obj-$(CONFIG_RV_REACT_PANIC) += reactor_panic.o
> +obj-$(CONFIG_RV_REACT_SIGNAL) += reactor_signal.o
> diff --git a/kernel/trace/rv/reactor_signal.c
> b/kernel/trace/rv/reactor_signal.c
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..e123786d94371a240beb63b2d1b2f3044a46
> 6404
> --- /dev/null
> +++ b/kernel/trace/rv/reactor_signal.c
> @@ -0,0 +1,114 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2025 Thomas Weißschuh, Linutronix GmbH
> + *
> + * Signal RV reactor:
> + * Prints the exception msg to the kernel message log and sends a signal to
> the offending task.
> + */
> +
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
> +#include <linux/cpumask.h>
> +#include <linux/init.h>
> +#include <linux/mempool.h>
> +#include <linux/module.h>
> +#include <linux/printk.h>
> +#include <linux/rv.h>
> +#include <linux/sched/signal.h>
> +#include <linux/task_work.h>
> +
> +struct rv_signal_work {
> + struct callback_head twork;
> + int signal;
> + char message[256];
> +};
> +
> +static mempool_t *rv_signal_task_work_pool;
> +
> +static void rv_signal_force_sig(int signal, const char *message)
> +{
> + /* The message already contains a subsystem prefix, so use raw
> printk() */
> + printk(KERN_WARNING "%s", message);
> + pr_warn("Killing PID %d with signal %d", task_pid_nr(current),
> signal);
> + force_sig(signal);
> +}
> +
> +static void rv_signal_task_work(struct callback_head *cbh)
> +{
> + struct rv_signal_work *work = container_of_const(cbh, struct
> rv_signal_work, twork);
> +
> + rv_signal_force_sig(work->signal, work->message);
> +
> + mempool_free(work, rv_signal_task_work_pool);
> +}
> +
> +static void rv_reaction_signal(int signal, const char *fmt, va_list args)
> +{
> + struct rv_signal_work *work;
> + char message[256];
> +
> + work = mempool_alloc_preallocated(rv_signal_task_work_pool);
> + if (!work) {
> + pr_warn_ratelimited("Unable to signal through task_work,
> sending directly\n");
> + vsnprintf(message, sizeof(message), fmt, args);
> + rv_signal_force_sig(signal, message);
> + return;
> + }
Why do you use the task_work at all instead of signalling directly?
If that's something not safe from a (any) tracepoint because it can sleep you
should definitely not call it if allocation fails.
> +
> + init_task_work(&work->twork, rv_signal_task_work);
> + work->signal = signal;
> + vsnprintf(work->message, sizeof(work->message), fmt, args);
> +
> + /*
> + * The reactor can be called from any context through tracepoints.
> + * To avoid any locking or other operations not usable from all
> contexts, use TWA_RESUME.
> + * The signal might be delayed, but that shouldn't be an issue.
> + */
> + task_work_add(current, &work->twork, TWA_RESUME);
> +}
> +
> +__printf(1, 2)
> +static void rv_reaction_sigbus(const char *fmt, ...)
> +{
> + va_list args;
> +
> + va_start(args, fmt);
> + rv_reaction_signal(SIGBUS, fmt, args);
> + va_end(args);
> +}
> +
> +static struct rv_reactor rv_sigbus = {
> + .name = "sigbus",
> + .description = "Kill the current task with SIGBUS",
> + .react = rv_reaction_sigbus,
> +};
Let's be consistent and call this reactor "signal", you can use SIGBUS only in
the description until/if we allow different signals.
What do you think?
Thanks,
Gabriele
next prev parent reply other threads:[~2025-09-19 12:26 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-19 10:49 Thomas Weißschuh
2025-09-19 12:26 ` Gabriele Monaco [this message]
2025-09-22 16:29 ` Nam Cao
2025-09-23 7:42 ` Gabriele Monaco
2025-09-25 14:39 ` Thomas Weißschuh
2025-10-02 14:56 ` Nam Cao
2025-10-03 6:30 ` Gabriele Monaco
2025-10-06 10:10 ` Thomas Weißschuh
2025-10-06 15:19 ` Gabriele Monaco
2025-10-10 11:02 ` Thomas Weißschuh
2025-10-10 13:02 ` Gabriele Monaco
2025-10-10 12:12 ` Nam Cao
2025-09-30 14:18 ` Thomas Weißschuh
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=d0aaaf1f47f0d948b60b0575e179564e3c024188.camel@redhat.com \
--to=gmonaco@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=mathieu.desnoyers@efficios.com \
--cc=mhiramat@kernel.org \
--cc=namcao@linutronix.de \
--cc=rostedt@goodmis.org \
--cc=thomas.weissschuh@linutronix.de \
/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®