Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rv: Add snroc per-task monitor

Add a per-task monitor as part of the sched model:

* snroc: set non runnable on its own context
Monitor to ensure set_state happens only in the respective task's context

To: Ingo Molnar <mingo@redhat.com>
To: Peter Zijlstra <peterz@infradead.org>
Cc: Juri Lelli <juri.lelli@redhat.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: John Kacur <jkacur@redhat.com>
Cc: Clark Williams <williams@redhat.com>
Link: https://lore.kernel.org/20250305140406.350227-5-gmonaco@redhat.com
Signed-off-by: Gabriele Monaco <gmonaco@redhat.com>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>

authored by

Gabriele Monaco and committed by
Steven Rostedt (Google)
93bac9cf 9fd420ab

+182
+1
kernel/trace/rv/Kconfig
··· 30 30 source "kernel/trace/rv/monitors/sched/Kconfig" 31 31 source "kernel/trace/rv/monitors/tss/Kconfig" 32 32 source "kernel/trace/rv/monitors/sco/Kconfig" 33 + source "kernel/trace/rv/monitors/snroc/Kconfig" 33 34 # Add new monitors here 34 35 35 36 config RV_REACTORS
+1
kernel/trace/rv/Makefile
··· 8 8 obj-$(CONFIG_RV_MON_SCHED) += monitors/sched/sched.o 9 9 obj-$(CONFIG_RV_MON_TSS) += monitors/tss/tss.o 10 10 obj-$(CONFIG_RV_MON_SCO) += monitors/sco/sco.o 11 + obj-$(CONFIG_RV_MON_SNROC) += monitors/snroc/snroc.o 11 12 # Add new monitors here 12 13 obj-$(CONFIG_RV_REACTORS) += rv_reactors.o 13 14 obj-$(CONFIG_RV_REACT_PRINTK) += reactor_printk.o
+14
kernel/trace/rv/monitors/snroc/Kconfig
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + # 3 + config RV_MON_SNROC 4 + depends on RV 5 + depends on RV_MON_SCHED 6 + default y 7 + select DA_MON_EVENTS_ID 8 + bool "snroc monitor" 9 + help 10 + Monitor to ensure sched_set_state happens only in the respective task's context. 11 + This monitor is part of the sched monitors collection. 12 + 13 + For further information, see: 14 + Documentation/trace/rv/monitor_sched.rst
+85
kernel/trace/rv/monitors/snroc/snroc.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + #include <linux/ftrace.h> 3 + #include <linux/tracepoint.h> 4 + #include <linux/kernel.h> 5 + #include <linux/module.h> 6 + #include <linux/init.h> 7 + #include <linux/rv.h> 8 + #include <rv/instrumentation.h> 9 + #include <rv/da_monitor.h> 10 + 11 + #define MODULE_NAME "snroc" 12 + 13 + #include <trace/events/sched.h> 14 + #include <rv_trace.h> 15 + #include <monitors/sched/sched.h> 16 + 17 + #include "snroc.h" 18 + 19 + static struct rv_monitor rv_snroc; 20 + DECLARE_DA_MON_PER_TASK(snroc, unsigned char); 21 + 22 + static void handle_sched_set_state(void *data, struct task_struct *tsk, int state) 23 + { 24 + da_handle_event_snroc(tsk, sched_set_state_snroc); 25 + } 26 + 27 + static void handle_sched_switch(void *data, bool preempt, 28 + struct task_struct *prev, 29 + struct task_struct *next, 30 + unsigned int prev_state) 31 + { 32 + da_handle_start_event_snroc(prev, sched_switch_out_snroc); 33 + da_handle_event_snroc(next, sched_switch_in_snroc); 34 + } 35 + 36 + static int enable_snroc(void) 37 + { 38 + int retval; 39 + 40 + retval = da_monitor_init_snroc(); 41 + if (retval) 42 + return retval; 43 + 44 + rv_attach_trace_probe("snroc", sched_set_state_tp, handle_sched_set_state); 45 + rv_attach_trace_probe("snroc", sched_switch, handle_sched_switch); 46 + 47 + return 0; 48 + } 49 + 50 + static void disable_snroc(void) 51 + { 52 + rv_snroc.enabled = 0; 53 + 54 + rv_detach_trace_probe("snroc", sched_set_state_tp, handle_sched_set_state); 55 + rv_detach_trace_probe("snroc", sched_switch, handle_sched_switch); 56 + 57 + da_monitor_destroy_snroc(); 58 + } 59 + 60 + static struct rv_monitor rv_snroc = { 61 + .name = "snroc", 62 + .description = "set non runnable on its own context.", 63 + .enable = enable_snroc, 64 + .disable = disable_snroc, 65 + .reset = da_monitor_reset_all_snroc, 66 + .enabled = 0, 67 + }; 68 + 69 + static int __init register_snroc(void) 70 + { 71 + rv_register_monitor(&rv_snroc, &rv_sched); 72 + return 0; 73 + } 74 + 75 + static void __exit unregister_snroc(void) 76 + { 77 + rv_unregister_monitor(&rv_snroc); 78 + } 79 + 80 + module_init(register_snroc); 81 + module_exit(unregister_snroc); 82 + 83 + MODULE_LICENSE("GPL"); 84 + MODULE_AUTHOR("Gabriele Monaco <gmonaco@redhat.com>"); 85 + MODULE_DESCRIPTION("snroc: set non runnable on its own context.");
+47
kernel/trace/rv/monitors/snroc/snroc.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Automatically generated C representation of snroc automaton 4 + * For further information about this format, see kernel documentation: 5 + * Documentation/trace/rv/deterministic_automata.rst 6 + */ 7 + 8 + enum states_snroc { 9 + other_context_snroc = 0, 10 + own_context_snroc, 11 + state_max_snroc 12 + }; 13 + 14 + #define INVALID_STATE state_max_snroc 15 + 16 + enum events_snroc { 17 + sched_set_state_snroc = 0, 18 + sched_switch_in_snroc, 19 + sched_switch_out_snroc, 20 + event_max_snroc 21 + }; 22 + 23 + struct automaton_snroc { 24 + char *state_names[state_max_snroc]; 25 + char *event_names[event_max_snroc]; 26 + unsigned char function[state_max_snroc][event_max_snroc]; 27 + unsigned char initial_state; 28 + bool final_states[state_max_snroc]; 29 + }; 30 + 31 + static const struct automaton_snroc automaton_snroc = { 32 + .state_names = { 33 + "other_context", 34 + "own_context" 35 + }, 36 + .event_names = { 37 + "sched_set_state", 38 + "sched_switch_in", 39 + "sched_switch_out" 40 + }, 41 + .function = { 42 + { INVALID_STATE, own_context_snroc, INVALID_STATE }, 43 + { own_context_snroc, INVALID_STATE, other_context_snroc }, 44 + }, 45 + .initial_state = other_context_snroc, 46 + .final_states = { 1, 0 }, 47 + };
+15
kernel/trace/rv/monitors/snroc/snroc_trace.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + 3 + /* 4 + * Snippet to be included in rv_trace.h 5 + */ 6 + 7 + #ifdef CONFIG_RV_MON_SNROC 8 + DEFINE_EVENT(event_da_monitor_id, event_snroc, 9 + TP_PROTO(int id, char *state, char *event, char *next_state, bool final_state), 10 + TP_ARGS(id, state, event, next_state, final_state)); 11 + 12 + DEFINE_EVENT(error_da_monitor_id, error_snroc, 13 + TP_PROTO(int id, char *state, char *event), 14 + TP_ARGS(id, state, event)); 15 + #endif /* CONFIG_RV_MON_SNROC */
+1
kernel/trace/rv/rv_trace.h
··· 120 120 ); 121 121 122 122 #include <monitors/wwnr/wwnr_trace.h> 123 + #include <monitors/snroc/snroc_trace.h> 123 124 // Add new monitors based on CONFIG_DA_MON_EVENTS_ID here 124 125 125 126 #endif /* CONFIG_DA_MON_EVENTS_ID */
+18
tools/verification/models/sched/snroc.dot
··· 1 + digraph state_automaton { 2 + center = true; 3 + size = "7,11"; 4 + {node [shape = plaintext, style=invis, label=""] "__init_other_context"}; 5 + {node [shape = ellipse] "other_context"}; 6 + {node [shape = plaintext] "other_context"}; 7 + {node [shape = plaintext] "own_context"}; 8 + "__init_other_context" -> "other_context"; 9 + "other_context" [label = "other_context", color = green3]; 10 + "other_context" -> "own_context" [ label = "sched_switch_in" ]; 11 + "own_context" [label = "own_context"]; 12 + "own_context" -> "other_context" [ label = "sched_switch_out" ]; 13 + "own_context" -> "own_context" [ label = "sched_set_state" ]; 14 + { rank = min ; 15 + "__init_other_context"; 16 + "other_context"; 17 + } 18 + }