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

Configure Feed

Select the types of activity you want to include in your feed.

rv: Pass va_list to reactors

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>

authored by

Thomas Weißschuh and committed by
Gabriele Monaco
4f739ed1 0c0cd931

+41 -51
+9 -2
include/linux/rv.h
··· 88 88 struct rv_reactor { 89 89 const char *name; 90 90 const char *description; 91 - __printf(1, 2) void (*react)(const char *msg, ...); 91 + __printf(1, 0) void (*react)(const char *msg, va_list args); 92 92 struct list_head list; 93 93 }; 94 94 #endif ··· 102 102 void (*reset)(void); 103 103 #ifdef CONFIG_RV_REACTORS 104 104 struct rv_reactor *reactor; 105 - __printf(1, 2) void (*react)(const char *msg, ...); 105 + __printf(1, 0) void (*react)(const char *msg, va_list args); 106 106 #endif 107 107 struct list_head list; 108 108 struct rv_monitor *parent; ··· 119 119 bool rv_reacting_on(void); 120 120 int rv_unregister_reactor(struct rv_reactor *reactor); 121 121 int rv_register_reactor(struct rv_reactor *reactor); 122 + __printf(2, 3) 123 + void rv_react(struct rv_monitor *monitor, const char *msg, ...); 122 124 #else 123 125 static inline bool rv_reacting_on(void) 124 126 { 125 127 return false; 128 + } 129 + 130 + __printf(2, 3) 131 + static inline void rv_react(struct rv_monitor *monitor, const char *msg, ...) 132 + { 126 133 } 127 134 #endif /* CONFIG_RV_REACTORS */ 128 135
+10 -25
include/rv/da_monitor.h
··· 16 16 #include <linux/bug.h> 17 17 #include <linux/sched.h> 18 18 19 - #ifdef CONFIG_RV_REACTORS 20 - 21 - #define DECLARE_RV_REACTING_HELPERS(name, type) \ 22 - static void cond_react_##name(type curr_state, type event) \ 23 - { \ 24 - if (!rv_reacting_on() || !rv_##name.react) \ 25 - return; \ 26 - rv_##name.react("rv: monitor %s does not allow event %s on state %s\n", \ 27 - #name, \ 28 - model_get_event_name_##name(event), \ 29 - model_get_state_name_##name(curr_state)); \ 30 - } 31 - 32 - #else /* CONFIG_RV_REACTOR */ 33 - 34 - #define DECLARE_RV_REACTING_HELPERS(name, type) \ 35 - static void cond_react_##name(type curr_state, type event) \ 36 - { \ 37 - return; \ 38 - } 39 - #endif 40 - 41 19 /* 42 20 * Generic helpers for all types of deterministic automata monitors. 43 21 */ 44 22 #define DECLARE_DA_MON_GENERIC_HELPERS(name, type) \ 45 23 \ 46 - DECLARE_RV_REACTING_HELPERS(name, type) \ 24 + static void react_##name(type curr_state, type event) \ 25 + { \ 26 + rv_react(&rv_##name, \ 27 + "rv: monitor %s does not allow event %s on state %s\n", \ 28 + #name, \ 29 + model_get_event_name_##name(event), \ 30 + model_get_state_name_##name(curr_state)); \ 31 + } \ 47 32 \ 48 33 /* \ 49 34 * da_monitor_reset_##name - reset a monitor and setting it to init state \ ··· 111 126 for (int i = 0; i < MAX_DA_RETRY_RACING_EVENTS; i++) { \ 112 127 next_state = model_get_next_state_##name(curr_state, event); \ 113 128 if (next_state == INVALID_STATE) { \ 114 - cond_react_##name(curr_state, event); \ 129 + react_##name(curr_state, event); \ 115 130 trace_error_##name(model_get_state_name_##name(curr_state), \ 116 131 model_get_event_name_##name(event)); \ 117 132 return false; \ ··· 150 165 for (int i = 0; i < MAX_DA_RETRY_RACING_EVENTS; i++) { \ 151 166 next_state = model_get_next_state_##name(curr_state, event); \ 152 167 if (next_state == INVALID_STATE) { \ 153 - cond_react_##name(curr_state, event); \ 168 + react_##name(curr_state, event); \ 154 169 trace_error_##name(tsk->pid, \ 155 170 model_get_state_name_##name(curr_state), \ 156 171 model_get_event_name_##name(event)); \
+5 -13
include/rv/ltl_monitor.h
··· 16 16 #error "Please include $(MODEL_NAME).h generated by rvgen" 17 17 #endif 18 18 19 - #ifdef CONFIG_RV_REACTORS 20 19 #define RV_MONITOR_NAME CONCATENATE(rv_, MONITOR_NAME) 21 - static struct rv_monitor RV_MONITOR_NAME; 22 20 23 - static void rv_cond_react(struct task_struct *task) 24 - { 25 - if (!rv_reacting_on() || !RV_MONITOR_NAME.react) 26 - return; 27 - RV_MONITOR_NAME.react("rv: "__stringify(MONITOR_NAME)": %s[%d]: violation detected\n", 28 - task->comm, task->pid); 29 - } 21 + #ifdef CONFIG_RV_REACTORS 22 + static struct rv_monitor RV_MONITOR_NAME; 30 23 #else 31 - static void rv_cond_react(struct task_struct *task) 32 - { 33 - } 24 + extern struct rv_monitor RV_MONITOR_NAME; 34 25 #endif 35 26 36 27 static int ltl_monitor_slot = RV_PER_TASK_MONITOR_INIT; ··· 89 98 static void ltl_illegal_state(struct task_struct *task, struct ltl_monitor *mon) 90 99 { 91 100 CONCATENATE(trace_error_, MONITOR_NAME)(task); 92 - rv_cond_react(task); 101 + rv_react(&RV_MONITOR_NAME, "rv: "__stringify(MONITOR_NAME)": %s[%d]: violation detected\n", 102 + task->comm, task->pid); 93 103 } 94 104 95 105 static void ltl_attempt_start(struct task_struct *task, struct ltl_monitor *mon)
+1 -5
kernel/trace/rv/reactor_panic.c
··· 13 13 #include <linux/init.h> 14 14 #include <linux/rv.h> 15 15 16 - __printf(1, 2) static void rv_panic_reaction(const char *msg, ...) 16 + __printf(1, 0) static void rv_panic_reaction(const char *msg, va_list args) 17 17 { 18 - va_list args; 19 - 20 - va_start(args, msg); 21 18 vpanic(msg, args); 22 - va_end(args); 23 19 } 24 20 25 21 static struct rv_reactor rv_panic = {
+1 -5
kernel/trace/rv/reactor_printk.c
··· 12 12 #include <linux/init.h> 13 13 #include <linux/rv.h> 14 14 15 - __printf(1, 2) static void rv_printk_reaction(const char *msg, ...) 15 + __printf(1, 0) static void rv_printk_reaction(const char *msg, va_list args) 16 16 { 17 - va_list args; 18 - 19 - va_start(args, msg); 20 17 vprintk_deferred(msg, args); 21 - va_end(args); 22 18 } 23 19 24 20 static struct rv_reactor rv_printk = {
+15 -1
kernel/trace/rv/rv_reactors.c
··· 438 438 /* 439 439 * Nop reactor register 440 440 */ 441 - __printf(1, 2) static void rv_nop_reaction(const char *msg, ...) 441 + __printf(1, 0) static void rv_nop_reaction(const char *msg, va_list args) 442 442 { 443 443 } 444 444 ··· 476 476 rv_remove(available); 477 477 out_err: 478 478 return -ENOMEM; 479 + } 480 + 481 + void rv_react(struct rv_monitor *monitor, const char *msg, ...) 482 + { 483 + va_list args; 484 + 485 + if (!rv_reacting_on() || !monitor->react) 486 + return; 487 + 488 + va_start(args, msg); 489 + 490 + monitor->react(msg, args); 491 + 492 + va_end(args); 479 493 }