[RFC PATCH 0/9] rv: Add monitors to validate task switch

Gabriele Monaco
2025-04-04T08:45:59Z

This series adds two monitors to the sched collection that imply two
previously existing monitors:

tss => sts:
Not only prove that switches occur in scheduling context but also that
each call to the scheduler implies a switch (also a vain one) and
disables interrupts doing so.

srs => snroc:
Describe different types of switches and their requirements, e.g.:
* preemption requires need resched which is cleared by any switch
* suspension requires setting the task to sleepable and, after the
switch occurs, the task requires a wakeup to come back to runnable
The monitor implies setting the task state occurs only when the task is
running, which is what snroc was guaranteeing.

We also include some minor cleanup patches (1-4) tracepoints (5) and
preparatory fixes (6-7) covering some corner cases:

Patch 1 fixes the behaviour of the rv tool with -s and idle tasks.

Patch 2 allows the rv tool to gracefully terminate with SIGTERM

Patch 3 adds da_handle_start_run_event_ also to per-task monitors

Patch 4 removes a trailing whitespace from the rv tracepoint string

Patch 5 adds the need_resched and switch_vain tracepoints

Patch 6 treats scheduling out sleepable tasks with pending signals as
wakeup (with appropriate tracepoint calls and changing the state)

Patch 7 detects race conditions when rv monitors run concurrently and
retries applying the events

Patch 8 adds the sts monitor

Patch 9 adds the srs monitor

NOTES

The srs monitor is quite complex and there are a few things that I
cannot fully explain:

* A sleeping task requires to set the state to sleepable, but in case of
a task sleeping on an rtlock, the set sleepable and wakeup events race
and we don't always see the right order:

5d..2. 107.488369: event: 639: sleepable x set_sleepable -> sleepable
4d..5. 107.488369: event: 639: sleepable x wakeup -> running (final)
5d..3. 107.488385: error: 639: switch_suspend not expected in the state running

wakeup() set_state()
state=RUNNING
trace_set_state()
trace_wakeup()
state=SLEEPING

I added a special event (switch_block) but there may be a better way.
Changing the order between tracepoints and setting the state doesn't
change, we can still be out of sync.

* I consider preemption any scheduling with preempt==true and assume
this can happen only if need resched is set (either via tif or
preemption count). The tracepoint tracks only when the tif is set and
I added a special event with a schedule entry with (preempt &&
!tif_need_resched() && test_preempt_need_resched()) to account for
preemptions where the tif was not set (perhaps there's a better way).
Nevertheless, I still rarely see some preemptions without either set.
Not sure if it's a glitch in the model or a case I didn't consider.

To: Ingo Molnar <mingo@redhat.com>
To: Peter Zijlstra <peterz@infradead.org>
To: Steven Rostedt <rostedt@goodmis.org>
Cc: Tomas Glozar <tglozar@redhat.com>
Cc: Juri Lelli <jlelli@redhat.com>

Gabriele Monaco (9):
tools/rv: Do not skip idle in trace
tools/rv: Stop gracefully also on SIGTERM
rv: Add da_handle_start_run_event_ to per-task monitors
rv: Remove trailing whitespace from tracepoint string
sched: Add sched tracepoints for RV task model
sched: Treat try_to_block_task with pending signal as wakeup
rv: Retry when da monitor detects race conditions
rv: Replace tss monitor with more complete sts
rv: Add srs per-task monitor

Documentation/trace/rv/monitor_sched.rst | 237 +++++++++++++++---
include/linux/rv.h | 3 +-
include/linux/sched.h | 7 +-
include/rv/da_monitor.h | 75 +++++-
include/trace/events/sched.h | 8 +
kernel/sched/core.c | 20 +-
kernel/trace/rv/Kconfig | 4 +-
kernel/trace/rv/Makefile | 4 +-
kernel/trace/rv/monitors/snroc/snroc.c | 85 -------
kernel/trace/rv/monitors/snroc/snroc.h | 47 ----
.../trace/rv/monitors/{snroc => srs}/Kconfig | 8 +-
kernel/trace/rv/monitors/srs/srs.c | 135 ++++++++++
kernel/trace/rv/monitors/srs/srs.h | 87 +++++++
.../{snroc/snroc_trace.h => srs/srs_trace.h} | 8 +-
kernel/trace/rv/monitors/sts/Kconfig | 18 ++
kernel/trace/rv/monitors/sts/sts.c | 118 +++++++++
kernel/trace/rv/monitors/sts/sts.h | 62 +++++
.../{tss/tss_trace.h => sts/sts_trace.h} | 8 +-
kernel/trace/rv/monitors/tss/Kconfig | 14 --
kernel/trace/rv/monitors/tss/tss.c | 91 -------
kernel/trace/rv/monitors/tss/tss.h | 47 ----
kernel/trace/rv/rv_trace.h | 12 +-
tools/verification/models/sched/snroc.dot | 18 --
tools/verification/models/sched/srs.dot | 61 +++++
tools/verification/models/sched/sts.dot | 29 +++
tools/verification/models/sched/tss.dot | 18 --
tools/verification/rv/src/in_kernel.c | 2 +-
tools/verification/rv/src/rv.c | 1 +
28 files changed, 828 insertions(+), 399 deletions(-)
delete mode 100644 kernel/trace/rv/monitors/snroc/snroc.c
delete mode 100644 kernel/trace/rv/monitors/snroc/snroc.h
rename kernel/trace/rv/monitors/{snroc => srs}/Kconfig (52%)
create mode 100644 kernel/trace/rv/monitors/srs/srs.c
create mode 100644 kernel/trace/rv/monitors/srs/srs.h
rename kernel/trace/rv/monitors/{snroc/snroc_trace.h => srs/srs_trace.h} (67%)
create mode 100644 kernel/trace/rv/monitors/sts/Kconfig
create mode 100644 kernel/trace/rv/monitors/sts/sts.c
create mode 100644 kernel/trace/rv/monitors/sts/sts.h
rename kernel/trace/rv/monitors/{tss/tss_trace.h => sts/sts_trace.h} (67%)
delete mode 100644 kernel/trace/rv/monitors/tss/Kconfig
delete mode 100644 kernel/trace/rv/monitors/tss/tss.c
delete mode 100644 kernel/trace/rv/monitors/tss/tss.h
delete mode 100644 tools/verification/models/sched/snroc.dot
create mode 100644 tools/verification/models/sched/srs.dot
create mode 100644 tools/verification/models/sched/sts.dot
delete mode 100644 tools/verification/models/sched/tss.dot

base-commit: e48e99b6edf41c69c5528aa7ffb2daf3c59ee105
--
2.49.0