* [for-next][PATCH 1/5] selftest/ftrace: Generalise ftracetest to use with RV
2025-11-12 22:19 [for-next][PATCH 0/5] rv: Updates for v6.19 Steven Rostedt
@ 2025-11-12 22:19 ` Steven Rostedt
2025-11-12 22:19 ` [for-next][PATCH 2/5] selftests/verification: Add initial RV tests Steven Rostedt
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Steven Rostedt @ 2025-11-12 22:19 UTC (permalink / raw)
To: linux-kernel; +Cc: Gabriele Monaco, Nam Cao, Thomas Weißschuh
From: Gabriele Monaco <gmonaco@redhat.com>
The ftracetest script is a fairly complete test framework for tracefs-like
subsystem, but it can only be used for ftrace selftests.
If OPT_TEST_DIR is provided and includes a function file, use that as
test directory going forward rather than just grabbing tests from it.
Generalise function names like initialize_ftrace to initialize_system.
Add the --rv argument to set up the test for rv, basically changing the
trace directory to $TRACING_DIR/rv and displaying an error if that
cannot be found.
This prepares for rv selftests inclusion.
Link: https://lore.kernel.org/r/20251017115203.140080-2-gmonaco@redhat.com
Signed-off-by: Gabriele Monaco <gmonaco@redhat.com>
---
tools/testing/selftests/ftrace/ftracetest | 34 +++++++++++++------
.../ftrace/test.d/00basic/mount_options.tc | 2 +-
.../testing/selftests/ftrace/test.d/functions | 6 ++--
3 files changed, 28 insertions(+), 14 deletions(-)
diff --git a/tools/testing/selftests/ftrace/ftracetest b/tools/testing/selftests/ftrace/ftracetest
index cce72f8b03dc..3230bd54dba8 100755
--- a/tools/testing/selftests/ftrace/ftracetest
+++ b/tools/testing/selftests/ftrace/ftracetest
@@ -22,6 +22,7 @@ echo " --fail-unresolved Treat UNRESOLVED as a failure"
echo " -d|--debug Debug mode (trace all shell commands)"
echo " -l|--logdir <dir> Save logs on the <dir>"
echo " If <dir> is -, all logs output in console only"
+echo " --rv Run RV selftests instead of ftrace ones"
exit $1
}
@@ -133,6 +134,10 @@ parse_opts() { # opts
LINK_PTR=
shift 2
;;
+ --rv)
+ RV_TEST=1
+ shift 1
+ ;;
*.tc)
if [ -f "$1" ]; then
OPT_TEST_CASES="$OPT_TEST_CASES `abspath $1`"
@@ -152,9 +157,13 @@ parse_opts() { # opts
;;
esac
done
- if [ ! -z "$OPT_TEST_CASES" ]; then
+ if [ -n "$OPT_TEST_CASES" ]; then
TEST_CASES=$OPT_TEST_CASES
fi
+ if [ -n "$OPT_TEST_DIR" -a -f "$OPT_TEST_DIR"/test.d/functions ]; then
+ TOP_DIR=$OPT_TEST_DIR
+ TEST_DIR=$TOP_DIR/test.d
+ fi
}
# Parameters
@@ -190,10 +199,6 @@ fi
TOP_DIR=`absdir $0`
TEST_DIR=$TOP_DIR/test.d
TEST_CASES=`find_testcases $TEST_DIR`
-LOG_TOP_DIR=$TOP_DIR/logs
-LOG_DATE=`date +%Y%m%d-%H%M%S`
-LOG_DIR=$LOG_TOP_DIR/$LOG_DATE/
-LINK_PTR=$LOG_TOP_DIR/latest
KEEP_LOG=0
KTAP=0
DEBUG=0
@@ -201,14 +206,23 @@ VERBOSE=0
UNSUPPORTED_RESULT=0
UNRESOLVED_RESULT=0
STOP_FAILURE=0
+RV_TEST=0
# Parse command-line options
parse_opts $*
+LOG_TOP_DIR=$TOP_DIR/logs
+LOG_DATE=`date +%Y%m%d-%H%M%S`
+LOG_DIR=$LOG_TOP_DIR/$LOG_DATE/
+LINK_PTR=$LOG_TOP_DIR/latest
+
[ $DEBUG -ne 0 ] && set -x
-# Verify parameters
-if [ -z "$TRACING_DIR" -o ! -d "$TRACING_DIR" ]; then
- errexit "No ftrace directory found"
+if [ $RV_TEST -ne 0 ]; then
+ TRACING_DIR=$TRACING_DIR/rv
+ if [ ! -d "$TRACING_DIR" ]; then
+ err_ret=$err_skip
+ errexit "rv is not configured in this kernel"
+ fi
fi
# Preparing logs
@@ -419,7 +433,7 @@ trap 'SIG_RESULT=$XFAIL' $SIG_XFAIL
__run_test() { # testfile
# setup PID and PPID, $$ is not updated.
(cd $TRACING_DIR; read PID _ < /proc/self/stat; set -e; set -x;
- checkreq $1; initialize_ftrace; . $1)
+ checkreq $1; initialize_system; . $1)
[ $? -ne 0 ] && kill -s $SIG_FAIL $SIG_PID
}
@@ -496,7 +510,7 @@ for t in $TEST_CASES; do
exit 1
fi
done
-(cd $TRACING_DIR; finish_ftrace) # for cleanup
+(cd $TRACING_DIR; finish_system) # for cleanup
prlog ""
prlog "# of passed: " `echo $PASSED_CASES | wc -w`
diff --git a/tools/testing/selftests/ftrace/test.d/00basic/mount_options.tc b/tools/testing/selftests/ftrace/test.d/00basic/mount_options.tc
index 8a7ce647a60d..318939451caf 100644
--- a/tools/testing/selftests/ftrace/test.d/00basic/mount_options.tc
+++ b/tools/testing/selftests/ftrace/test.d/00basic/mount_options.tc
@@ -28,7 +28,7 @@ unmount_tracefs() {
local mount_point="$1"
# Need to make sure the mount isn't busy so that we can umount it
- (cd $mount_point; finish_ftrace;)
+ (cd $mount_point; finish_system;)
cleanup
}
diff --git a/tools/testing/selftests/ftrace/test.d/functions b/tools/testing/selftests/ftrace/test.d/functions
index a1052bf460fc..e8e718139294 100644
--- a/tools/testing/selftests/ftrace/test.d/functions
+++ b/tools/testing/selftests/ftrace/test.d/functions
@@ -104,7 +104,7 @@ clear_dynamic_events() { # reset all current dynamic events
done
}
-initialize_ftrace() { # Reset ftrace to initial-state
+initialize_system() { # Reset ftrace to initial-state
# As the initial state, ftrace will be set to nop tracer,
# no events, no triggers, no filters, no function filters,
# no probes, and tracing on.
@@ -134,8 +134,8 @@ initialize_ftrace() { # Reset ftrace to initial-state
enable_tracing
}
-finish_ftrace() {
- initialize_ftrace
+finish_system() {
+ initialize_system
# And recover it to default.
[ -f options/pause-on-trace ] && echo 0 > options/pause-on-trace
}
--
2.51.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [for-next][PATCH 2/5] selftests/verification: Add initial RV tests
2025-11-12 22:19 [for-next][PATCH 0/5] rv: Updates for v6.19 Steven Rostedt
2025-11-12 22:19 ` [for-next][PATCH 1/5] selftest/ftrace: Generalise ftracetest to use with RV Steven Rostedt
@ 2025-11-12 22:19 ` Steven Rostedt
2025-11-12 22:19 ` [for-next][PATCH 3/5] rv: Pass va_list to reactors Steven Rostedt
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Steven Rostedt @ 2025-11-12 22:19 UTC (permalink / raw)
To: linux-kernel; +Cc: Gabriele Monaco, Nam Cao, Thomas Weißschuh
From: Gabriele Monaco <gmonaco@redhat.com>
Add a series of tests to validate the RV tracefs API and basic
functionality.
* available monitors:
Check that all monitors (from the monitors folder) appear as
available and have a description. Works with nested monitors.
* enable/disable:
Enable and disable all monitors and validate both the enabled file
and the enabled_monitors. Check that enabling container monitors
enables all nested monitors.
* reactors:
Set all reactors and validate the setting, also for nested monitors.
* wwnr with printk:
wwnr is broken on purpose, run it with a load and check that the
printk reactor works. Also validate disabling reacting_on or
monitoring_on prevents reactions.
These tests use the ftracetest suite.
Acked-by: Nam Cao <namcao@linutronix.de>
Link: https://lore.kernel.org/r/20251017115203.140080-3-gmonaco@redhat.com
Signed-off-by: Gabriele Monaco <gmonaco@redhat.com>
---
MAINTAINERS | 1 +
.../testing/selftests/verification/.gitignore | 2 +
tools/testing/selftests/verification/Makefile | 8 ++
tools/testing/selftests/verification/config | 1 +
tools/testing/selftests/verification/settings | 1 +
.../selftests/verification/test.d/functions | 39 ++++++++++
.../test.d/rv_monitor_enable_disable.tc | 75 +++++++++++++++++++
.../verification/test.d/rv_monitor_reactor.tc | 68 +++++++++++++++++
.../test.d/rv_monitors_available.tc | 18 +++++
.../verification/test.d/rv_wwnr_printk.tc | 30 ++++++++
.../verification/verificationtest-ktap | 8 ++
11 files changed, 251 insertions(+)
create mode 100644 tools/testing/selftests/verification/.gitignore
create mode 100644 tools/testing/selftests/verification/Makefile
create mode 100644 tools/testing/selftests/verification/config
create mode 100644 tools/testing/selftests/verification/settings
create mode 100644 tools/testing/selftests/verification/test.d/functions
create mode 100644 tools/testing/selftests/verification/test.d/rv_monitor_enable_disable.tc
create mode 100644 tools/testing/selftests/verification/test.d/rv_monitor_reactor.tc
create mode 100644 tools/testing/selftests/verification/test.d/rv_monitors_available.tc
create mode 100644 tools/testing/selftests/verification/test.d/rv_wwnr_printk.tc
create mode 100755 tools/testing/selftests/verification/verificationtest-ktap
diff --git a/MAINTAINERS b/MAINTAINERS
index ddecf1ef3bed..95c32cd3b524 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22498,6 +22498,7 @@ F: Documentation/trace/rv/
F: include/linux/rv.h
F: include/rv/
F: kernel/trace/rv/
+F: tools/testing/selftests/verification/
F: tools/verification/
RUST
diff --git a/tools/testing/selftests/verification/.gitignore b/tools/testing/selftests/verification/.gitignore
new file mode 100644
index 000000000000..2659417cb2c7
--- /dev/null
+++ b/tools/testing/selftests/verification/.gitignore
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+logs
diff --git a/tools/testing/selftests/verification/Makefile b/tools/testing/selftests/verification/Makefile
new file mode 100644
index 000000000000..aa8790c22a71
--- /dev/null
+++ b/tools/testing/selftests/verification/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0
+all:
+
+TEST_PROGS := verificationtest-ktap
+TEST_FILES := test.d settings
+EXTRA_CLEAN := $(OUTPUT)/logs/*
+
+include ../lib.mk
diff --git a/tools/testing/selftests/verification/config b/tools/testing/selftests/verification/config
new file mode 100644
index 000000000000..43072c1c38f4
--- /dev/null
+++ b/tools/testing/selftests/verification/config
@@ -0,0 +1 @@
+CONFIG_RV=y
diff --git a/tools/testing/selftests/verification/settings b/tools/testing/selftests/verification/settings
new file mode 100644
index 000000000000..e7b9417537fb
--- /dev/null
+++ b/tools/testing/selftests/verification/settings
@@ -0,0 +1 @@
+timeout=0
diff --git a/tools/testing/selftests/verification/test.d/functions b/tools/testing/selftests/verification/test.d/functions
new file mode 100644
index 000000000000..ec36a092f56e
--- /dev/null
+++ b/tools/testing/selftests/verification/test.d/functions
@@ -0,0 +1,39 @@
+check_requires() { # Check required files, monitors and reactors
+ for i in "$@" ; do
+ p=${i%:program}
+ m=${i%:monitor}
+ r=${i%:reactor}
+ if [ $p != $i ]; then
+ if ! which $p ; then
+ echo "Required program $p is not found."
+ exit_unresolved
+ fi
+ elif [ $m != $i ]; then
+ if ! grep -wq $m available_monitors ; then
+ echo "Required monitor $m is not configured."
+ exit_unsupported
+ fi
+ elif [ $r != $i ]; then
+ if ! grep -wq $r available_reactors ; then
+ echo "Required reactor $r is not configured."
+ exit_unsupported
+ fi
+ elif [ ! -e $i ]; then
+ echo "Required feature interface $i doesn't exist."
+ exit_unsupported
+ fi
+ done
+}
+
+initialize_system() { # Reset RV to initial-state
+ echo > enabled_monitors
+ for m in monitors/*; do
+ echo nop > $m/reactors || true
+ done
+ echo 1 > monitoring_on
+ echo 1 > reacting_on || true
+}
+
+finish_system() {
+ initialize_system
+}
diff --git a/tools/testing/selftests/verification/test.d/rv_monitor_enable_disable.tc b/tools/testing/selftests/verification/test.d/rv_monitor_enable_disable.tc
new file mode 100644
index 000000000000..f29236defb5a
--- /dev/null
+++ b/tools/testing/selftests/verification/test.d/rv_monitor_enable_disable.tc
@@ -0,0 +1,75 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0-or-later
+# description: Test monitor enable/disable
+
+test_simple_monitor() {
+ local monitor="$1"
+ local prefix="$2" # nested monitors
+
+ echo 1 > "monitors/$prefix$monitor/enable"
+ grep -q "$monitor$" enabled_monitors
+
+ echo 0 > "monitors/$prefix$monitor/enable"
+ ! grep -q "$monitor$" enabled_monitors
+
+ echo "$monitor" >> enabled_monitors
+ grep -q 1 "monitors/$prefix$monitor/enable"
+
+ echo "!$monitor" >> enabled_monitors
+ grep -q 0 "monitors/$prefix$monitor/enable"
+}
+
+test_container_monitor() {
+ local monitor="$1"
+ local nested
+
+ echo 1 > "monitors/$monitor/enable"
+ grep -q "^$monitor$" enabled_monitors
+
+ for nested_dir in "monitors/$monitor"/*; do
+ [ -d "$nested_dir" ] || continue
+ nested=$(basename "$nested_dir")
+ grep -q "^$monitor:$nested$" enabled_monitors
+ done
+ test -n "$nested"
+
+ echo 0 > "monitors/$monitor/enable"
+ ! grep -q "^$monitor$" enabled_monitors
+
+ for nested_dir in "monitors/$monitor"/*; do
+ [ -d "$nested_dir" ] || continue
+ nested=$(basename "$nested_dir")
+ ! grep -q "^$monitor:$nested$" enabled_monitors
+ done
+
+ echo "$monitor" >> enabled_monitors
+ grep -q 1 "monitors/$monitor/enable"
+
+ for nested_dir in "monitors/$monitor"/*; do
+ [ -d "$nested_dir" ] || continue
+ nested=$(basename "$nested_dir")
+ grep -q "^$monitor:$nested$" enabled_monitors
+ done
+
+ echo "!$monitor" >> enabled_monitors
+ grep -q 0 "monitors/$monitor/enable"
+
+ for nested_dir in "monitors/$monitor"/*; do
+ [ -d "$nested_dir" ] || continue
+ nested=$(basename "$nested_dir")
+ test_simple_monitor "$nested" "$monitor/"
+ done
+}
+
+for monitor_dir in monitors/*; do
+ monitor=$(basename "$monitor_dir")
+
+ if find "$monitor_dir" -mindepth 1 -type d | grep -q .; then
+ test_container_monitor "$monitor"
+ else
+ test_simple_monitor "$monitor"
+ fi
+done
+
+! echo non_existent_monitor > enabled_monitors
+! grep -q "^non_existent_monitor$" enabled_monitors
diff --git a/tools/testing/selftests/verification/test.d/rv_monitor_reactor.tc b/tools/testing/selftests/verification/test.d/rv_monitor_reactor.tc
new file mode 100644
index 000000000000..2958bf849338
--- /dev/null
+++ b/tools/testing/selftests/verification/test.d/rv_monitor_reactor.tc
@@ -0,0 +1,68 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0-or-later
+# description: Test monitor reactor setting
+# requires: available_reactors
+
+test_monitor_reactor() {
+ local monitor="$1"
+ local prefix="$2" # nested monitors
+
+ while read -r reactor; do
+ [ "$reactor" = nop ] && continue
+
+ echo "$reactor" > "monitors/$prefix$monitor/reactors"
+ grep -q "\\[$reactor\\]" "monitors/$prefix$monitor/reactors"
+ done < available_reactors
+
+ echo nop > "monitors/$prefix$monitor/reactors"
+ grep -q "\\[nop\\]" "monitors/$prefix$monitor/reactors"
+}
+
+test_container_monitor() {
+ local monitor="$1"
+ local nested
+
+ while read -r reactor; do
+ [ "$reactor" = nop ] && continue
+
+ echo "$reactor" > "monitors/$monitor/reactors"
+ grep -q "\\[$reactor\\]" "monitors/$monitor/reactors"
+
+ for nested_dir in "monitors/$monitor"/*; do
+ [ -d "$nested_dir" ] || continue
+ nested=$(basename "$nested_dir")
+ grep -q "\\[$reactor\\]" "monitors/$monitor/$nested/reactors"
+ done
+ done < available_reactors
+ test -n "$nested"
+
+ echo nop > "monitors/$monitor/reactors"
+ grep -q "\\[nop\\]" "monitors/$monitor/reactors"
+
+ for nested_dir in "monitors/$monitor"/*; do
+ [ -d "$nested_dir" ] || continue
+ nested=$(basename "$nested_dir")
+ grep -q "\\[nop\\]" "monitors/$monitor/$nested/reactors"
+ done
+
+ for nested_dir in "monitors/$monitor"/*; do
+ [ -d "$nested_dir" ] || continue
+ nested=$(basename "$nested_dir")
+ test_monitor_reactor "$nested" "$monitor/"
+ done
+}
+
+for monitor_dir in monitors/*; do
+ monitor=$(basename "$monitor_dir")
+
+ if find "$monitor_dir" -mindepth 1 -type d | grep -q .; then
+ test_container_monitor "$monitor"
+ else
+ test_monitor_reactor "$monitor"
+ fi
+done
+
+monitor=$(ls /sys/kernel/tracing/rv/monitors -1 | head -n 1)
+test -f "monitors/$monitor/reactors"
+! echo non_existent_reactor > "monitors/$monitor/reactors"
+! grep -q "\\[non_existent_reactor\\]" "monitors/$monitor/reactors"
diff --git a/tools/testing/selftests/verification/test.d/rv_monitors_available.tc b/tools/testing/selftests/verification/test.d/rv_monitors_available.tc
new file mode 100644
index 000000000000..e6a4a1410690
--- /dev/null
+++ b/tools/testing/selftests/verification/test.d/rv_monitors_available.tc
@@ -0,0 +1,18 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0-or-later
+# description: Check available monitors
+
+for monitor_dir in monitors/*; do
+ monitor=$(basename "$monitor_dir")
+
+ grep -q "^$monitor$" available_monitors
+ grep -q . "$monitor_dir"/desc
+
+ for nested_dir in "$monitor_dir"/*; do
+ [ -d "$nested_dir" ] || continue
+ nested=$(basename "$nested_dir")
+
+ grep -q "^$monitor:$nested$" available_monitors
+ grep -q . "$nested_dir"/desc
+ done
+done
diff --git a/tools/testing/selftests/verification/test.d/rv_wwnr_printk.tc b/tools/testing/selftests/verification/test.d/rv_wwnr_printk.tc
new file mode 100644
index 000000000000..5a59432b1d93
--- /dev/null
+++ b/tools/testing/selftests/verification/test.d/rv_wwnr_printk.tc
@@ -0,0 +1,30 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0-or-later
+# description: Test wwnr monitor with printk reactor
+# requires: available_reactors wwnr:monitor printk:reactor stress-ng:program
+
+load() { # returns true if there was a reaction
+ local lines_before num
+ num=$((($(nproc) + 1) / 2))
+ lines_before=$(dmesg | wc -l)
+ stress-ng --cpu-sched "$num" --timer "$num" -t 5 -q
+ dmesg | tail -n $((lines_before + 1)) | grep -q "rv: monitor wwnr does not allow event"
+}
+
+echo 1 > monitors/wwnr/enable
+echo printk > monitors/wwnr/reactors
+
+load
+
+echo 0 > monitoring_on
+! load
+echo 1 > monitoring_on
+
+load
+
+echo 0 > reacting_on
+! load
+echo 1 > reacting_on
+
+echo nop > monitors/wwnr/reactors
+echo 0 > monitors/wwnr/enable
diff --git a/tools/testing/selftests/verification/verificationtest-ktap b/tools/testing/selftests/verification/verificationtest-ktap
new file mode 100755
index 000000000000..18f7fe324e2f
--- /dev/null
+++ b/tools/testing/selftests/verification/verificationtest-ktap
@@ -0,0 +1,8 @@
+#!/bin/sh -e
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# ftracetest-ktap: Wrapper to integrate ftracetest with the kselftest runner
+#
+# Copyright (C) Arm Ltd., 2023
+
+../ftrace/ftracetest -K -v --rv ../verification
--
2.51.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [for-next][PATCH 3/5] rv: Pass va_list to reactors
2025-11-12 22:19 [for-next][PATCH 0/5] rv: Updates for v6.19 Steven Rostedt
2025-11-12 22:19 ` [for-next][PATCH 1/5] selftest/ftrace: Generalise ftracetest to use with RV Steven Rostedt
2025-11-12 22:19 ` [for-next][PATCH 2/5] selftests/verification: Add initial RV tests Steven Rostedt
@ 2025-11-12 22:19 ` Steven Rostedt
2025-11-12 22:19 ` [for-next][PATCH 4/5] rv: Make rv_reacting_on() static Steven Rostedt
2025-11-12 22:19 ` [for-next][PATCH 5/5] rv: Add explicit lockdep context for reactors Steven Rostedt
4 siblings, 0 replies; 6+ messages in thread
From: Steven Rostedt @ 2025-11-12 22:19 UTC (permalink / raw)
To: linux-kernel; +Cc: Gabriele Monaco, Nam Cao, Thomas Weißschuh
From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= <thomas.weissschuh@linutronix.de>
The only thing the reactors can do with the passed in varargs is to
convert it into a va_list. Do that in a central helper instead.
It simplifies the reactors, removes some hairy macro-generated code
and introduces a convenient hook point to modify reactor behavior.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Link: https://lore.kernel.org/r/20251014-rv-lockdep-v1-1-0b9e51919ea8@linutronix.de
Signed-off-by: Gabriele Monaco <gmonaco@redhat.com>
---
include/linux/rv.h | 11 ++++++++--
include/rv/da_monitor.h | 35 +++++++++-----------------------
include/rv/ltl_monitor.h | 18 +++++-----------
kernel/trace/rv/reactor_panic.c | 6 +-----
kernel/trace/rv/reactor_printk.c | 6 +-----
kernel/trace/rv/rv_reactors.c | 16 ++++++++++++++-
6 files changed, 41 insertions(+), 51 deletions(-)
diff --git a/include/linux/rv.h b/include/linux/rv.h
index 9520aab34bcb..b567b0191e67 100644
--- a/include/linux/rv.h
+++ b/include/linux/rv.h
@@ -88,7 +88,7 @@ union rv_task_monitor {
struct rv_reactor {
const char *name;
const char *description;
- __printf(1, 2) void (*react)(const char *msg, ...);
+ __printf(1, 0) void (*react)(const char *msg, va_list args);
struct list_head list;
};
#endif
@@ -102,7 +102,7 @@ struct rv_monitor {
void (*reset)(void);
#ifdef CONFIG_RV_REACTORS
struct rv_reactor *reactor;
- __printf(1, 2) void (*react)(const char *msg, ...);
+ __printf(1, 0) void (*react)(const char *msg, va_list args);
#endif
struct list_head list;
struct rv_monitor *parent;
@@ -119,11 +119,18 @@ void rv_put_task_monitor_slot(int slot);
bool rv_reacting_on(void);
int rv_unregister_reactor(struct rv_reactor *reactor);
int rv_register_reactor(struct rv_reactor *reactor);
+__printf(2, 3)
+void rv_react(struct rv_monitor *monitor, const char *msg, ...);
#else
static inline bool rv_reacting_on(void)
{
return false;
}
+
+__printf(2, 3)
+static inline void rv_react(struct rv_monitor *monitor, const char *msg, ...)
+{
+}
#endif /* CONFIG_RV_REACTORS */
#endif /* CONFIG_RV */
diff --git a/include/rv/da_monitor.h b/include/rv/da_monitor.h
index 17fa4f6e5ea6..0cef64366538 100644
--- a/include/rv/da_monitor.h
+++ b/include/rv/da_monitor.h
@@ -16,34 +16,19 @@
#include <linux/bug.h>
#include <linux/sched.h>
-#ifdef CONFIG_RV_REACTORS
-
-#define DECLARE_RV_REACTING_HELPERS(name, type) \
-static void cond_react_##name(type curr_state, type event) \
-{ \
- if (!rv_reacting_on() || !rv_##name.react) \
- return; \
- rv_##name.react("rv: monitor %s does not allow event %s on state %s\n", \
- #name, \
- model_get_event_name_##name(event), \
- model_get_state_name_##name(curr_state)); \
-}
-
-#else /* CONFIG_RV_REACTOR */
-
-#define DECLARE_RV_REACTING_HELPERS(name, type) \
-static void cond_react_##name(type curr_state, type event) \
-{ \
- return; \
-}
-#endif
-
/*
* Generic helpers for all types of deterministic automata monitors.
*/
#define DECLARE_DA_MON_GENERIC_HELPERS(name, type) \
\
-DECLARE_RV_REACTING_HELPERS(name, type) \
+static void react_##name(type curr_state, type event) \
+{ \
+ rv_react(&rv_##name, \
+ "rv: monitor %s does not allow event %s on state %s\n", \
+ #name, \
+ model_get_event_name_##name(event), \
+ model_get_state_name_##name(curr_state)); \
+} \
\
/* \
* da_monitor_reset_##name - reset a monitor and setting it to init state \
@@ -126,7 +111,7 @@ da_event_##name(struct da_monitor *da_mon, enum events_##name event) \
for (int i = 0; i < MAX_DA_RETRY_RACING_EVENTS; i++) { \
next_state = model_get_next_state_##name(curr_state, event); \
if (next_state == INVALID_STATE) { \
- cond_react_##name(curr_state, event); \
+ react_##name(curr_state, event); \
trace_error_##name(model_get_state_name_##name(curr_state), \
model_get_event_name_##name(event)); \
return false; \
@@ -165,7 +150,7 @@ static inline bool da_event_##name(struct da_monitor *da_mon, struct task_struct
for (int i = 0; i < MAX_DA_RETRY_RACING_EVENTS; i++) { \
next_state = model_get_next_state_##name(curr_state, event); \
if (next_state == INVALID_STATE) { \
- cond_react_##name(curr_state, event); \
+ react_##name(curr_state, event); \
trace_error_##name(tsk->pid, \
model_get_state_name_##name(curr_state), \
model_get_event_name_##name(event)); \
diff --git a/include/rv/ltl_monitor.h b/include/rv/ltl_monitor.h
index 5368cf5fd623..00c42b36f961 100644
--- a/include/rv/ltl_monitor.h
+++ b/include/rv/ltl_monitor.h
@@ -16,21 +16,12 @@
#error "Please include $(MODEL_NAME).h generated by rvgen"
#endif
-#ifdef CONFIG_RV_REACTORS
#define RV_MONITOR_NAME CONCATENATE(rv_, MONITOR_NAME)
-static struct rv_monitor RV_MONITOR_NAME;
-static void rv_cond_react(struct task_struct *task)
-{
- if (!rv_reacting_on() || !RV_MONITOR_NAME.react)
- return;
- RV_MONITOR_NAME.react("rv: "__stringify(MONITOR_NAME)": %s[%d]: violation detected\n",
- task->comm, task->pid);
-}
+#ifdef CONFIG_RV_REACTORS
+static struct rv_monitor RV_MONITOR_NAME;
#else
-static void rv_cond_react(struct task_struct *task)
-{
-}
+extern struct rv_monitor RV_MONITOR_NAME;
#endif
static int ltl_monitor_slot = RV_PER_TASK_MONITOR_INIT;
@@ -98,7 +89,8 @@ static void ltl_monitor_destroy(void)
static void ltl_illegal_state(struct task_struct *task, struct ltl_monitor *mon)
{
CONCATENATE(trace_error_, MONITOR_NAME)(task);
- rv_cond_react(task);
+ rv_react(&RV_MONITOR_NAME, "rv: "__stringify(MONITOR_NAME)": %s[%d]: violation detected\n",
+ task->comm, task->pid);
}
static void ltl_attempt_start(struct task_struct *task, struct ltl_monitor *mon)
diff --git a/kernel/trace/rv/reactor_panic.c b/kernel/trace/rv/reactor_panic.c
index 74c6bcc2c749..76537b8a4343 100644
--- a/kernel/trace/rv/reactor_panic.c
+++ b/kernel/trace/rv/reactor_panic.c
@@ -13,13 +13,9 @@
#include <linux/init.h>
#include <linux/rv.h>
-__printf(1, 2) static void rv_panic_reaction(const char *msg, ...)
+__printf(1, 0) static void rv_panic_reaction(const char *msg, va_list args)
{
- va_list args;
-
- va_start(args, msg);
vpanic(msg, args);
- va_end(args);
}
static struct rv_reactor rv_panic = {
diff --git a/kernel/trace/rv/reactor_printk.c b/kernel/trace/rv/reactor_printk.c
index 2dae2916c05f..48c934e315b3 100644
--- a/kernel/trace/rv/reactor_printk.c
+++ b/kernel/trace/rv/reactor_printk.c
@@ -12,13 +12,9 @@
#include <linux/init.h>
#include <linux/rv.h>
-__printf(1, 2) static void rv_printk_reaction(const char *msg, ...)
+__printf(1, 0) static void rv_printk_reaction(const char *msg, va_list args)
{
- va_list args;
-
- va_start(args, msg);
vprintk_deferred(msg, args);
- va_end(args);
}
static struct rv_reactor rv_printk = {
diff --git a/kernel/trace/rv/rv_reactors.c b/kernel/trace/rv/rv_reactors.c
index d32859fec238..cb1a5968055a 100644
--- a/kernel/trace/rv/rv_reactors.c
+++ b/kernel/trace/rv/rv_reactors.c
@@ -438,7 +438,7 @@ int reactor_populate_monitor(struct rv_monitor *mon)
/*
* Nop reactor register
*/
-__printf(1, 2) static void rv_nop_reaction(const char *msg, ...)
+__printf(1, 0) static void rv_nop_reaction(const char *msg, va_list args)
{
}
@@ -477,3 +477,17 @@ int init_rv_reactors(struct dentry *root_dir)
out_err:
return -ENOMEM;
}
+
+void rv_react(struct rv_monitor *monitor, const char *msg, ...)
+{
+ va_list args;
+
+ if (!rv_reacting_on() || !monitor->react)
+ return;
+
+ va_start(args, msg);
+
+ monitor->react(msg, args);
+
+ va_end(args);
+}
--
2.51.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [for-next][PATCH 4/5] rv: Make rv_reacting_on() static
2025-11-12 22:19 [for-next][PATCH 0/5] rv: Updates for v6.19 Steven Rostedt
` (2 preceding siblings ...)
2025-11-12 22:19 ` [for-next][PATCH 3/5] rv: Pass va_list to reactors Steven Rostedt
@ 2025-11-12 22:19 ` Steven Rostedt
2025-11-12 22:19 ` [for-next][PATCH 5/5] rv: Add explicit lockdep context for reactors Steven Rostedt
4 siblings, 0 replies; 6+ messages in thread
From: Steven Rostedt @ 2025-11-12 22:19 UTC (permalink / raw)
To: linux-kernel; +Cc: Gabriele Monaco, Nam Cao, Thomas Weißschuh
From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= <thomas.weissschuh@linutronix.de>
There are no external users left.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Link: https://lore.kernel.org/r/20251014-rv-lockdep-v1-2-0b9e51919ea8@linutronix.de
Signed-off-by: Gabriele Monaco <gmonaco@redhat.com>
---
include/linux/rv.h | 6 ------
kernel/trace/rv/rv_reactors.c | 2 +-
2 files changed, 1 insertion(+), 7 deletions(-)
diff --git a/include/linux/rv.h b/include/linux/rv.h
index b567b0191e67..92fd467547e7 100644
--- a/include/linux/rv.h
+++ b/include/linux/rv.h
@@ -116,17 +116,11 @@ int rv_get_task_monitor_slot(void);
void rv_put_task_monitor_slot(int slot);
#ifdef CONFIG_RV_REACTORS
-bool rv_reacting_on(void);
int rv_unregister_reactor(struct rv_reactor *reactor);
int rv_register_reactor(struct rv_reactor *reactor);
__printf(2, 3)
void rv_react(struct rv_monitor *monitor, const char *msg, ...);
#else
-static inline bool rv_reacting_on(void)
-{
- return false;
-}
-
__printf(2, 3)
static inline void rv_react(struct rv_monitor *monitor, const char *msg, ...)
{
diff --git a/kernel/trace/rv/rv_reactors.c b/kernel/trace/rv/rv_reactors.c
index cb1a5968055a..8c02426bc3bd 100644
--- a/kernel/trace/rv/rv_reactors.c
+++ b/kernel/trace/rv/rv_reactors.c
@@ -347,7 +347,7 @@ static bool __read_mostly reacting_on;
*
* Returns 1 if on, 0 otherwise.
*/
-bool rv_reacting_on(void)
+static bool rv_reacting_on(void)
{
/* Ensures that concurrent monitors read consistent reacting_on */
smp_rmb();
--
2.51.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [for-next][PATCH 5/5] rv: Add explicit lockdep context for reactors
2025-11-12 22:19 [for-next][PATCH 0/5] rv: Updates for v6.19 Steven Rostedt
` (3 preceding siblings ...)
2025-11-12 22:19 ` [for-next][PATCH 4/5] rv: Make rv_reacting_on() static Steven Rostedt
@ 2025-11-12 22:19 ` Steven Rostedt
4 siblings, 0 replies; 6+ messages in thread
From: Steven Rostedt @ 2025-11-12 22:19 UTC (permalink / raw)
To: linux-kernel; +Cc: Gabriele Monaco, Nam Cao, Thomas Weißschuh
From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= <thomas.weissschuh@linutronix.de>
Reactors can be called from any context through tracepoints.
When developing reactors care needs to be taken to only call APIs which
are safe. As the tracepoints used during testing may not actually be
called from restrictive contexts lockdep may not be helpful.
Add explicit overrides to help lockdep find invalid code patterns.
The usage of LD_WAIT_FREE will trigger lockdep warnings in the panic
reactor. These are indeed valid warnings but they are out of scope for
RV and will instead be fixed by the printk subsystem.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Acked-by: Nam Cao <namcao@linutronix.de>
Link: https://lore.kernel.org/r/20251014-rv-lockdep-v1-3-0b9e51919ea8@linutronix.de
Signed-off-by: Gabriele Monaco <gmonaco@redhat.com>
---
kernel/trace/rv/rv_reactors.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/kernel/trace/rv/rv_reactors.c b/kernel/trace/rv/rv_reactors.c
index 8c02426bc3bd..d9d335ae9bad 100644
--- a/kernel/trace/rv/rv_reactors.c
+++ b/kernel/trace/rv/rv_reactors.c
@@ -61,6 +61,7 @@
* printk
*/
+#include <linux/lockdep.h>
#include <linux/slab.h>
#include "rv.h"
@@ -480,6 +481,7 @@ int init_rv_reactors(struct dentry *root_dir)
void rv_react(struct rv_monitor *monitor, const char *msg, ...)
{
+ static DEFINE_WAIT_OVERRIDE_MAP(rv_react_map, LD_WAIT_FREE);
va_list args;
if (!rv_reacting_on() || !monitor->react)
@@ -487,7 +489,9 @@ void rv_react(struct rv_monitor *monitor, const char *msg, ...)
va_start(args, msg);
+ lock_map_acquire_try(&rv_react_map);
monitor->react(msg, args);
+ lock_map_release(&rv_react_map);
va_end(args);
}
--
2.51.0
^ permalink raw reply related [flat|nested] 6+ messages in thread