xref: /linux/include/rv/da_monitor.h (revision a1c613ae4c322ddd58d5a8539dbfba2a0380a8c0)
179257534SDaniel Bristot de Oliveira /* SPDX-License-Identifier: GPL-2.0 */
279257534SDaniel Bristot de Oliveira /*
379257534SDaniel Bristot de Oliveira  * Copyright (C) 2019-2022 Red Hat, Inc. Daniel Bristot de Oliveira <bristot@kernel.org>
479257534SDaniel Bristot de Oliveira  *
579257534SDaniel Bristot de Oliveira  * Deterministic automata (DA) monitor functions, to be used together
679257534SDaniel Bristot de Oliveira  * with automata models in C generated by the dot2k tool.
779257534SDaniel Bristot de Oliveira  *
879257534SDaniel Bristot de Oliveira  * The dot2k tool is available at tools/verification/dot2k/
9d57aff24SDaniel Bristot de Oliveira  *
10d57aff24SDaniel Bristot de Oliveira  * For further information, see:
11d57aff24SDaniel Bristot de Oliveira  *   Documentation/trace/rv/da_monitor_synthesis.rst
1279257534SDaniel Bristot de Oliveira  */
1379257534SDaniel Bristot de Oliveira 
1479257534SDaniel Bristot de Oliveira #include <rv/automata.h>
1579257534SDaniel Bristot de Oliveira #include <linux/rv.h>
1679257534SDaniel Bristot de Oliveira #include <linux/bug.h>
1779257534SDaniel Bristot de Oliveira 
1879257534SDaniel Bristot de Oliveira #ifdef CONFIG_RV_REACTORS
1979257534SDaniel Bristot de Oliveira 
2079257534SDaniel Bristot de Oliveira #define DECLARE_RV_REACTING_HELPERS(name, type)							\
2179257534SDaniel Bristot de Oliveira static char REACT_MSG_##name[1024];								\
2279257534SDaniel Bristot de Oliveira 												\
2379257534SDaniel Bristot de Oliveira static inline char *format_react_msg_##name(type curr_state, type event)			\
2479257534SDaniel Bristot de Oliveira {												\
2579257534SDaniel Bristot de Oliveira 	snprintf(REACT_MSG_##name, 1024,							\
2679257534SDaniel Bristot de Oliveira 		 "rv: monitor %s does not allow event %s on state %s\n",			\
2779257534SDaniel Bristot de Oliveira 		 #name,										\
2879257534SDaniel Bristot de Oliveira 		 model_get_event_name_##name(event),						\
2979257534SDaniel Bristot de Oliveira 		 model_get_state_name_##name(curr_state));					\
3079257534SDaniel Bristot de Oliveira 	return REACT_MSG_##name;								\
3179257534SDaniel Bristot de Oliveira }												\
3279257534SDaniel Bristot de Oliveira 												\
3379257534SDaniel Bristot de Oliveira static void cond_react_##name(char *msg)							\
3479257534SDaniel Bristot de Oliveira {												\
3579257534SDaniel Bristot de Oliveira 	if (rv_##name.react)									\
3679257534SDaniel Bristot de Oliveira 		rv_##name.react(msg);								\
3779257534SDaniel Bristot de Oliveira }												\
3879257534SDaniel Bristot de Oliveira 												\
3979257534SDaniel Bristot de Oliveira static bool rv_reacting_on_##name(void)								\
4079257534SDaniel Bristot de Oliveira {												\
4179257534SDaniel Bristot de Oliveira 	return rv_reacting_on();								\
4279257534SDaniel Bristot de Oliveira }
4379257534SDaniel Bristot de Oliveira 
4479257534SDaniel Bristot de Oliveira #else /* CONFIG_RV_REACTOR */
4579257534SDaniel Bristot de Oliveira 
4679257534SDaniel Bristot de Oliveira #define DECLARE_RV_REACTING_HELPERS(name, type)							\
4779257534SDaniel Bristot de Oliveira static inline char *format_react_msg_##name(type curr_state, type event)			\
4879257534SDaniel Bristot de Oliveira {												\
4979257534SDaniel Bristot de Oliveira 	return NULL;										\
5079257534SDaniel Bristot de Oliveira }												\
5179257534SDaniel Bristot de Oliveira 												\
5279257534SDaniel Bristot de Oliveira static void cond_react_##name(char *msg)							\
5379257534SDaniel Bristot de Oliveira {												\
5479257534SDaniel Bristot de Oliveira 	return;											\
5579257534SDaniel Bristot de Oliveira }												\
5679257534SDaniel Bristot de Oliveira 												\
5779257534SDaniel Bristot de Oliveira static bool rv_reacting_on_##name(void)								\
5879257534SDaniel Bristot de Oliveira {												\
5979257534SDaniel Bristot de Oliveira 	return 0;										\
6079257534SDaniel Bristot de Oliveira }
6179257534SDaniel Bristot de Oliveira #endif
6279257534SDaniel Bristot de Oliveira 
6379257534SDaniel Bristot de Oliveira /*
6479257534SDaniel Bristot de Oliveira  * Generic helpers for all types of deterministic automata monitors.
6579257534SDaniel Bristot de Oliveira  */
6679257534SDaniel Bristot de Oliveira #define DECLARE_DA_MON_GENERIC_HELPERS(name, type)						\
6779257534SDaniel Bristot de Oliveira 												\
6879257534SDaniel Bristot de Oliveira DECLARE_RV_REACTING_HELPERS(name, type)								\
6979257534SDaniel Bristot de Oliveira 												\
7079257534SDaniel Bristot de Oliveira /*												\
7179257534SDaniel Bristot de Oliveira  * da_monitor_reset_##name - reset a monitor and setting it to init state			\
7279257534SDaniel Bristot de Oliveira  */												\
7379257534SDaniel Bristot de Oliveira static inline void da_monitor_reset_##name(struct da_monitor *da_mon)				\
7479257534SDaniel Bristot de Oliveira {												\
7579257534SDaniel Bristot de Oliveira 	da_mon->monitoring = 0;									\
7679257534SDaniel Bristot de Oliveira 	da_mon->curr_state = model_get_initial_state_##name();					\
7779257534SDaniel Bristot de Oliveira }												\
7879257534SDaniel Bristot de Oliveira 												\
7979257534SDaniel Bristot de Oliveira /*												\
8079257534SDaniel Bristot de Oliveira  * da_monitor_curr_state_##name - return the current state					\
8179257534SDaniel Bristot de Oliveira  */												\
8279257534SDaniel Bristot de Oliveira static inline type da_monitor_curr_state_##name(struct da_monitor *da_mon)			\
8379257534SDaniel Bristot de Oliveira {												\
8479257534SDaniel Bristot de Oliveira 	return da_mon->curr_state;								\
8579257534SDaniel Bristot de Oliveira }												\
8679257534SDaniel Bristot de Oliveira 												\
8779257534SDaniel Bristot de Oliveira /*												\
8879257534SDaniel Bristot de Oliveira  * da_monitor_set_state_##name - set the new current state					\
8979257534SDaniel Bristot de Oliveira  */												\
9079257534SDaniel Bristot de Oliveira static inline void										\
9179257534SDaniel Bristot de Oliveira da_monitor_set_state_##name(struct da_monitor *da_mon, enum states_##name state)		\
9279257534SDaniel Bristot de Oliveira {												\
9379257534SDaniel Bristot de Oliveira 	da_mon->curr_state = state;								\
9479257534SDaniel Bristot de Oliveira }												\
9579257534SDaniel Bristot de Oliveira 												\
9679257534SDaniel Bristot de Oliveira /*												\
9779257534SDaniel Bristot de Oliveira  * da_monitor_start_##name - start monitoring							\
9879257534SDaniel Bristot de Oliveira  *												\
9979257534SDaniel Bristot de Oliveira  * The monitor will ignore all events until monitoring is set to true. This			\
10079257534SDaniel Bristot de Oliveira  * function needs to be called to tell the monitor to start monitoring.				\
10179257534SDaniel Bristot de Oliveira  */												\
10279257534SDaniel Bristot de Oliveira static inline void da_monitor_start_##name(struct da_monitor *da_mon)				\
10379257534SDaniel Bristot de Oliveira {												\
10479257534SDaniel Bristot de Oliveira 	da_mon->curr_state = model_get_initial_state_##name();					\
10579257534SDaniel Bristot de Oliveira 	da_mon->monitoring = 1;									\
10679257534SDaniel Bristot de Oliveira }												\
10779257534SDaniel Bristot de Oliveira 												\
10879257534SDaniel Bristot de Oliveira /*												\
10979257534SDaniel Bristot de Oliveira  * da_monitoring_##name - returns true if the monitor is processing events			\
11079257534SDaniel Bristot de Oliveira  */												\
11179257534SDaniel Bristot de Oliveira static inline bool da_monitoring_##name(struct da_monitor *da_mon)				\
11279257534SDaniel Bristot de Oliveira {												\
11379257534SDaniel Bristot de Oliveira 	return da_mon->monitoring;								\
11479257534SDaniel Bristot de Oliveira }												\
11579257534SDaniel Bristot de Oliveira 												\
11679257534SDaniel Bristot de Oliveira /*												\
11779257534SDaniel Bristot de Oliveira  * da_monitor_enabled_##name - checks if the monitor is enabled					\
11879257534SDaniel Bristot de Oliveira  */												\
11979257534SDaniel Bristot de Oliveira static inline bool da_monitor_enabled_##name(void)						\
12079257534SDaniel Bristot de Oliveira {												\
12179257534SDaniel Bristot de Oliveira 	/* global switch */									\
12279257534SDaniel Bristot de Oliveira 	if (unlikely(!rv_monitoring_on()))							\
12379257534SDaniel Bristot de Oliveira 		return 0;									\
12479257534SDaniel Bristot de Oliveira 												\
12579257534SDaniel Bristot de Oliveira 	/* monitor enabled */									\
12679257534SDaniel Bristot de Oliveira 	if (unlikely(!rv_##name.enabled))							\
12779257534SDaniel Bristot de Oliveira 		return 0;									\
12879257534SDaniel Bristot de Oliveira 												\
12979257534SDaniel Bristot de Oliveira 	return 1;										\
13079257534SDaniel Bristot de Oliveira }												\
13179257534SDaniel Bristot de Oliveira 												\
13279257534SDaniel Bristot de Oliveira /*												\
13379257534SDaniel Bristot de Oliveira  * da_monitor_handling_event_##name - checks if the monitor is ready to handle events		\
13479257534SDaniel Bristot de Oliveira  */												\
13579257534SDaniel Bristot de Oliveira static inline bool da_monitor_handling_event_##name(struct da_monitor *da_mon)			\
13679257534SDaniel Bristot de Oliveira {												\
13779257534SDaniel Bristot de Oliveira 												\
13879257534SDaniel Bristot de Oliveira 	if (!da_monitor_enabled_##name())							\
13979257534SDaniel Bristot de Oliveira 		return 0;									\
14079257534SDaniel Bristot de Oliveira 												\
14179257534SDaniel Bristot de Oliveira 	/* monitor is actually monitoring */							\
14279257534SDaniel Bristot de Oliveira 	if (unlikely(!da_monitoring_##name(da_mon)))						\
14379257534SDaniel Bristot de Oliveira 		return 0;									\
14479257534SDaniel Bristot de Oliveira 												\
14579257534SDaniel Bristot de Oliveira 	return 1;										\
14679257534SDaniel Bristot de Oliveira }
14779257534SDaniel Bristot de Oliveira 
14879257534SDaniel Bristot de Oliveira /*
14979257534SDaniel Bristot de Oliveira  * Event handler for implicit monitors. Implicit monitor is the one which the
15079257534SDaniel Bristot de Oliveira  * handler does not need to specify which da_monitor to manipulate. Examples
15179257534SDaniel Bristot de Oliveira  * of implicit monitor are the per_cpu or the global ones.
15279257534SDaniel Bristot de Oliveira  */
15379257534SDaniel Bristot de Oliveira #define DECLARE_DA_MON_MODEL_HANDLER_IMPLICIT(name, type)					\
15479257534SDaniel Bristot de Oliveira 												\
15579257534SDaniel Bristot de Oliveira static inline bool										\
15679257534SDaniel Bristot de Oliveira da_event_##name(struct da_monitor *da_mon, enum events_##name event)				\
15779257534SDaniel Bristot de Oliveira {												\
15879257534SDaniel Bristot de Oliveira 	type curr_state = da_monitor_curr_state_##name(da_mon);					\
15979257534SDaniel Bristot de Oliveira 	type next_state = model_get_next_state_##name(curr_state, event);			\
16079257534SDaniel Bristot de Oliveira 												\
16179257534SDaniel Bristot de Oliveira 	if (next_state != INVALID_STATE) {							\
16279257534SDaniel Bristot de Oliveira 		da_monitor_set_state_##name(da_mon, next_state);				\
16379257534SDaniel Bristot de Oliveira 												\
16479257534SDaniel Bristot de Oliveira 		trace_event_##name(model_get_state_name_##name(curr_state),			\
16579257534SDaniel Bristot de Oliveira 				   model_get_event_name_##name(event),				\
16679257534SDaniel Bristot de Oliveira 				   model_get_state_name_##name(next_state),			\
16779257534SDaniel Bristot de Oliveira 				   model_is_final_state_##name(next_state));			\
16879257534SDaniel Bristot de Oliveira 												\
16979257534SDaniel Bristot de Oliveira 		return true;									\
17079257534SDaniel Bristot de Oliveira 	}											\
17179257534SDaniel Bristot de Oliveira 												\
17279257534SDaniel Bristot de Oliveira 	if (rv_reacting_on_##name())								\
17379257534SDaniel Bristot de Oliveira 		cond_react_##name(format_react_msg_##name(curr_state, event));			\
17479257534SDaniel Bristot de Oliveira 												\
17579257534SDaniel Bristot de Oliveira 	trace_error_##name(model_get_state_name_##name(curr_state),				\
17679257534SDaniel Bristot de Oliveira 			   model_get_event_name_##name(event));					\
17779257534SDaniel Bristot de Oliveira 												\
17879257534SDaniel Bristot de Oliveira 	return false;										\
17979257534SDaniel Bristot de Oliveira }												\
18079257534SDaniel Bristot de Oliveira 
18179257534SDaniel Bristot de Oliveira /*
18279257534SDaniel Bristot de Oliveira  * Event handler for per_task monitors.
18379257534SDaniel Bristot de Oliveira  */
18479257534SDaniel Bristot de Oliveira #define DECLARE_DA_MON_MODEL_HANDLER_PER_TASK(name, type)					\
18579257534SDaniel Bristot de Oliveira 												\
18679257534SDaniel Bristot de Oliveira static inline bool da_event_##name(struct da_monitor *da_mon, struct task_struct *tsk,		\
18779257534SDaniel Bristot de Oliveira 				   enum events_##name event)					\
18879257534SDaniel Bristot de Oliveira {												\
18979257534SDaniel Bristot de Oliveira 	type curr_state = da_monitor_curr_state_##name(da_mon);					\
19079257534SDaniel Bristot de Oliveira 	type next_state = model_get_next_state_##name(curr_state, event);			\
19179257534SDaniel Bristot de Oliveira 												\
19279257534SDaniel Bristot de Oliveira 	if (next_state != INVALID_STATE) {							\
19379257534SDaniel Bristot de Oliveira 		da_monitor_set_state_##name(da_mon, next_state);				\
19479257534SDaniel Bristot de Oliveira 												\
19579257534SDaniel Bristot de Oliveira 		trace_event_##name(tsk->pid,							\
19679257534SDaniel Bristot de Oliveira 				   model_get_state_name_##name(curr_state),			\
19779257534SDaniel Bristot de Oliveira 				   model_get_event_name_##name(event),				\
19879257534SDaniel Bristot de Oliveira 				   model_get_state_name_##name(next_state),			\
19979257534SDaniel Bristot de Oliveira 				   model_is_final_state_##name(next_state));			\
20079257534SDaniel Bristot de Oliveira 												\
20179257534SDaniel Bristot de Oliveira 		return true;									\
20279257534SDaniel Bristot de Oliveira 	}											\
20379257534SDaniel Bristot de Oliveira 												\
20479257534SDaniel Bristot de Oliveira 	if (rv_reacting_on_##name())								\
20579257534SDaniel Bristot de Oliveira 		cond_react_##name(format_react_msg_##name(curr_state, event));			\
20679257534SDaniel Bristot de Oliveira 												\
20779257534SDaniel Bristot de Oliveira 	trace_error_##name(tsk->pid,								\
20879257534SDaniel Bristot de Oliveira 			   model_get_state_name_##name(curr_state),				\
20979257534SDaniel Bristot de Oliveira 			   model_get_event_name_##name(event));					\
21079257534SDaniel Bristot de Oliveira 												\
21179257534SDaniel Bristot de Oliveira 	return false;										\
21279257534SDaniel Bristot de Oliveira }
21379257534SDaniel Bristot de Oliveira 
21479257534SDaniel Bristot de Oliveira /*
21579257534SDaniel Bristot de Oliveira  * Functions to define, init and get a global monitor.
21679257534SDaniel Bristot de Oliveira  */
21779257534SDaniel Bristot de Oliveira #define DECLARE_DA_MON_INIT_GLOBAL(name, type)							\
21879257534SDaniel Bristot de Oliveira 												\
21979257534SDaniel Bristot de Oliveira /*												\
22079257534SDaniel Bristot de Oliveira  * global monitor (a single variable)								\
22179257534SDaniel Bristot de Oliveira  */												\
22279257534SDaniel Bristot de Oliveira static struct da_monitor da_mon_##name;								\
22379257534SDaniel Bristot de Oliveira 												\
22479257534SDaniel Bristot de Oliveira /*												\
22579257534SDaniel Bristot de Oliveira  * da_get_monitor_##name - return the global monitor address					\
22679257534SDaniel Bristot de Oliveira  */												\
22779257534SDaniel Bristot de Oliveira static struct da_monitor *da_get_monitor_##name(void)						\
22879257534SDaniel Bristot de Oliveira {												\
22979257534SDaniel Bristot de Oliveira 	return &da_mon_##name;									\
23079257534SDaniel Bristot de Oliveira }												\
23179257534SDaniel Bristot de Oliveira 												\
23279257534SDaniel Bristot de Oliveira /*												\
23379257534SDaniel Bristot de Oliveira  * da_monitor_reset_all_##name - reset the single monitor					\
23479257534SDaniel Bristot de Oliveira  */												\
23579257534SDaniel Bristot de Oliveira static void da_monitor_reset_all_##name(void)							\
23679257534SDaniel Bristot de Oliveira {												\
23779257534SDaniel Bristot de Oliveira 	da_monitor_reset_##name(da_get_monitor_##name());					\
23879257534SDaniel Bristot de Oliveira }												\
23979257534SDaniel Bristot de Oliveira 												\
24079257534SDaniel Bristot de Oliveira /*												\
24179257534SDaniel Bristot de Oliveira  * da_monitor_init_##name - initialize a monitor						\
24279257534SDaniel Bristot de Oliveira  */												\
24379257534SDaniel Bristot de Oliveira static inline int da_monitor_init_##name(void)							\
24479257534SDaniel Bristot de Oliveira {												\
24579257534SDaniel Bristot de Oliveira 	da_monitor_reset_all_##name();								\
24679257534SDaniel Bristot de Oliveira 	return 0;										\
24779257534SDaniel Bristot de Oliveira }												\
24879257534SDaniel Bristot de Oliveira 												\
24979257534SDaniel Bristot de Oliveira /*												\
25079257534SDaniel Bristot de Oliveira  * da_monitor_destroy_##name - destroy the monitor						\
25179257534SDaniel Bristot de Oliveira  */												\
25279257534SDaniel Bristot de Oliveira static inline void da_monitor_destroy_##name(void)						\
25379257534SDaniel Bristot de Oliveira {												\
25479257534SDaniel Bristot de Oliveira 	return;											\
25579257534SDaniel Bristot de Oliveira }
25679257534SDaniel Bristot de Oliveira 
25779257534SDaniel Bristot de Oliveira /*
25879257534SDaniel Bristot de Oliveira  * Functions to define, init and get a per-cpu monitor.
25979257534SDaniel Bristot de Oliveira  */
26079257534SDaniel Bristot de Oliveira #define DECLARE_DA_MON_INIT_PER_CPU(name, type)							\
26179257534SDaniel Bristot de Oliveira 												\
26279257534SDaniel Bristot de Oliveira /*												\
26379257534SDaniel Bristot de Oliveira  * per-cpu monitor variables									\
26479257534SDaniel Bristot de Oliveira  */												\
265*0e19543bSYu Liao static DEFINE_PER_CPU(struct da_monitor, da_mon_##name);					\
26679257534SDaniel Bristot de Oliveira 												\
26779257534SDaniel Bristot de Oliveira /*												\
26879257534SDaniel Bristot de Oliveira  * da_get_monitor_##name - return current CPU monitor address					\
26979257534SDaniel Bristot de Oliveira  */												\
27079257534SDaniel Bristot de Oliveira static struct da_monitor *da_get_monitor_##name(void)						\
27179257534SDaniel Bristot de Oliveira {												\
27279257534SDaniel Bristot de Oliveira 	return this_cpu_ptr(&da_mon_##name);							\
27379257534SDaniel Bristot de Oliveira }												\
27479257534SDaniel Bristot de Oliveira 												\
27579257534SDaniel Bristot de Oliveira /*												\
27679257534SDaniel Bristot de Oliveira  * da_monitor_reset_all_##name - reset all CPUs' monitor					\
27779257534SDaniel Bristot de Oliveira  */												\
27879257534SDaniel Bristot de Oliveira static void da_monitor_reset_all_##name(void)							\
27979257534SDaniel Bristot de Oliveira {												\
28079257534SDaniel Bristot de Oliveira 	struct da_monitor *da_mon;								\
28179257534SDaniel Bristot de Oliveira 	int cpu;										\
28279257534SDaniel Bristot de Oliveira 	for_each_cpu(cpu, cpu_online_mask) {							\
28379257534SDaniel Bristot de Oliveira 		da_mon = per_cpu_ptr(&da_mon_##name, cpu);					\
28479257534SDaniel Bristot de Oliveira 		da_monitor_reset_##name(da_mon);						\
28579257534SDaniel Bristot de Oliveira 	}											\
28679257534SDaniel Bristot de Oliveira }												\
28779257534SDaniel Bristot de Oliveira 												\
28879257534SDaniel Bristot de Oliveira /*												\
28979257534SDaniel Bristot de Oliveira  * da_monitor_init_##name - initialize all CPUs' monitor					\
29079257534SDaniel Bristot de Oliveira  */												\
29179257534SDaniel Bristot de Oliveira static inline int da_monitor_init_##name(void)							\
29279257534SDaniel Bristot de Oliveira {												\
29379257534SDaniel Bristot de Oliveira 	da_monitor_reset_all_##name();								\
29479257534SDaniel Bristot de Oliveira 	return 0;										\
29579257534SDaniel Bristot de Oliveira }												\
29679257534SDaniel Bristot de Oliveira 												\
29779257534SDaniel Bristot de Oliveira /*												\
29879257534SDaniel Bristot de Oliveira  * da_monitor_destroy_##name - destroy the monitor						\
29979257534SDaniel Bristot de Oliveira  */												\
30079257534SDaniel Bristot de Oliveira static inline void da_monitor_destroy_##name(void)						\
30179257534SDaniel Bristot de Oliveira {												\
30279257534SDaniel Bristot de Oliveira 	return;											\
30379257534SDaniel Bristot de Oliveira }
30479257534SDaniel Bristot de Oliveira 
30579257534SDaniel Bristot de Oliveira /*
30679257534SDaniel Bristot de Oliveira  * Functions to define, init and get a per-task monitor.
30779257534SDaniel Bristot de Oliveira  */
30879257534SDaniel Bristot de Oliveira #define DECLARE_DA_MON_INIT_PER_TASK(name, type)						\
30979257534SDaniel Bristot de Oliveira 												\
31079257534SDaniel Bristot de Oliveira /*												\
31179257534SDaniel Bristot de Oliveira  * The per-task monitor is stored a vector in the task struct. This variable			\
31279257534SDaniel Bristot de Oliveira  * stores the position on the vector reserved for this monitor.					\
31379257534SDaniel Bristot de Oliveira  */												\
31479257534SDaniel Bristot de Oliveira static int task_mon_slot_##name = RV_PER_TASK_MONITOR_INIT;					\
31579257534SDaniel Bristot de Oliveira 												\
31679257534SDaniel Bristot de Oliveira /*												\
31779257534SDaniel Bristot de Oliveira  * da_get_monitor_##name - return the monitor in the allocated slot for tsk 			\
31879257534SDaniel Bristot de Oliveira  */												\
31979257534SDaniel Bristot de Oliveira static inline struct da_monitor *da_get_monitor_##name(struct task_struct *tsk)			\
32079257534SDaniel Bristot de Oliveira {												\
32179257534SDaniel Bristot de Oliveira 	return &tsk->rv[task_mon_slot_##name].da_mon;						\
32279257534SDaniel Bristot de Oliveira }												\
32379257534SDaniel Bristot de Oliveira 												\
32479257534SDaniel Bristot de Oliveira static void da_monitor_reset_all_##name(void)							\
32579257534SDaniel Bristot de Oliveira {												\
32679257534SDaniel Bristot de Oliveira 	struct task_struct *g, *p;								\
32779257534SDaniel Bristot de Oliveira 												\
32879257534SDaniel Bristot de Oliveira 	read_lock(&tasklist_lock);								\
32979257534SDaniel Bristot de Oliveira 	for_each_process_thread(g, p)								\
33079257534SDaniel Bristot de Oliveira 		da_monitor_reset_##name(da_get_monitor_##name(p));				\
33179257534SDaniel Bristot de Oliveira 	read_unlock(&tasklist_lock);								\
33279257534SDaniel Bristot de Oliveira }												\
33379257534SDaniel Bristot de Oliveira 												\
33479257534SDaniel Bristot de Oliveira /*												\
33579257534SDaniel Bristot de Oliveira  * da_monitor_init_##name - initialize the per-task monitor					\
33679257534SDaniel Bristot de Oliveira  *												\
33779257534SDaniel Bristot de Oliveira  * Try to allocate a slot in the task's vector of monitors. If there				\
33879257534SDaniel Bristot de Oliveira  * is an available slot, use it and reset all task's monitor.					\
33979257534SDaniel Bristot de Oliveira  */												\
34079257534SDaniel Bristot de Oliveira static int da_monitor_init_##name(void)								\
34179257534SDaniel Bristot de Oliveira {												\
34279257534SDaniel Bristot de Oliveira 	int slot;										\
34379257534SDaniel Bristot de Oliveira 												\
34479257534SDaniel Bristot de Oliveira 	slot = rv_get_task_monitor_slot();							\
34579257534SDaniel Bristot de Oliveira 	if (slot < 0 || slot >= RV_PER_TASK_MONITOR_INIT)					\
34679257534SDaniel Bristot de Oliveira 		return slot;									\
34779257534SDaniel Bristot de Oliveira 												\
34879257534SDaniel Bristot de Oliveira 	task_mon_slot_##name = slot;								\
34979257534SDaniel Bristot de Oliveira 												\
35079257534SDaniel Bristot de Oliveira 	da_monitor_reset_all_##name();								\
35179257534SDaniel Bristot de Oliveira 	return 0;										\
35279257534SDaniel Bristot de Oliveira }												\
35379257534SDaniel Bristot de Oliveira 												\
35479257534SDaniel Bristot de Oliveira /*												\
35579257534SDaniel Bristot de Oliveira  * da_monitor_destroy_##name - return the allocated slot					\
35679257534SDaniel Bristot de Oliveira  */												\
35779257534SDaniel Bristot de Oliveira static inline void da_monitor_destroy_##name(void)						\
35879257534SDaniel Bristot de Oliveira {												\
35979257534SDaniel Bristot de Oliveira 	if (task_mon_slot_##name == RV_PER_TASK_MONITOR_INIT) {					\
36079257534SDaniel Bristot de Oliveira 		WARN_ONCE(1, "Disabling a disabled monitor: " #name);				\
36179257534SDaniel Bristot de Oliveira 		return;										\
36279257534SDaniel Bristot de Oliveira 	}											\
36379257534SDaniel Bristot de Oliveira 	rv_put_task_monitor_slot(task_mon_slot_##name);						\
36479257534SDaniel Bristot de Oliveira 	task_mon_slot_##name = RV_PER_TASK_MONITOR_INIT;					\
36579257534SDaniel Bristot de Oliveira 	return;											\
36679257534SDaniel Bristot de Oliveira }
36779257534SDaniel Bristot de Oliveira 
36879257534SDaniel Bristot de Oliveira /*
36979257534SDaniel Bristot de Oliveira  * Handle event for implicit monitor: da_get_monitor_##name() will figure out
37079257534SDaniel Bristot de Oliveira  * the monitor.
37179257534SDaniel Bristot de Oliveira  */
37279257534SDaniel Bristot de Oliveira #define DECLARE_DA_MON_MONITOR_HANDLER_IMPLICIT(name, type)					\
37379257534SDaniel Bristot de Oliveira 												\
37479257534SDaniel Bristot de Oliveira static inline void __da_handle_event_##name(struct da_monitor *da_mon,				\
37579257534SDaniel Bristot de Oliveira 					    enum events_##name event)				\
37679257534SDaniel Bristot de Oliveira {												\
37779257534SDaniel Bristot de Oliveira 	bool retval;										\
37879257534SDaniel Bristot de Oliveira 												\
37979257534SDaniel Bristot de Oliveira 	retval = da_event_##name(da_mon, event);						\
38079257534SDaniel Bristot de Oliveira 	if (!retval)										\
38179257534SDaniel Bristot de Oliveira 		da_monitor_reset_##name(da_mon);						\
38279257534SDaniel Bristot de Oliveira }												\
38379257534SDaniel Bristot de Oliveira 												\
38479257534SDaniel Bristot de Oliveira /*												\
38579257534SDaniel Bristot de Oliveira  * da_handle_event_##name - handle an event							\
38679257534SDaniel Bristot de Oliveira  */												\
38779257534SDaniel Bristot de Oliveira static inline void da_handle_event_##name(enum events_##name event)				\
38879257534SDaniel Bristot de Oliveira {												\
38979257534SDaniel Bristot de Oliveira 	struct da_monitor *da_mon = da_get_monitor_##name();					\
39079257534SDaniel Bristot de Oliveira 	bool retval;										\
39179257534SDaniel Bristot de Oliveira 												\
39279257534SDaniel Bristot de Oliveira 	retval = da_monitor_handling_event_##name(da_mon);					\
39379257534SDaniel Bristot de Oliveira 	if (!retval)										\
39479257534SDaniel Bristot de Oliveira 		return;										\
39579257534SDaniel Bristot de Oliveira 												\
39679257534SDaniel Bristot de Oliveira 	__da_handle_event_##name(da_mon, event);						\
39779257534SDaniel Bristot de Oliveira }												\
39879257534SDaniel Bristot de Oliveira 												\
39979257534SDaniel Bristot de Oliveira /*												\
40079257534SDaniel Bristot de Oliveira  * da_handle_start_event_##name - start monitoring or handle event				\
40179257534SDaniel Bristot de Oliveira  *												\
40279257534SDaniel Bristot de Oliveira  * This function is used to notify the monitor that the system is returning			\
40379257534SDaniel Bristot de Oliveira  * to the initial state, so the monitor can start monitoring in the next event.			\
40479257534SDaniel Bristot de Oliveira  * Thus:											\
40579257534SDaniel Bristot de Oliveira  *												\
40679257534SDaniel Bristot de Oliveira  * If the monitor already started, handle the event.						\
40779257534SDaniel Bristot de Oliveira  * If the monitor did not start yet, start the monitor but skip the event.			\
40879257534SDaniel Bristot de Oliveira  */												\
40979257534SDaniel Bristot de Oliveira static inline bool da_handle_start_event_##name(enum events_##name event)			\
41079257534SDaniel Bristot de Oliveira {												\
41179257534SDaniel Bristot de Oliveira 	struct da_monitor *da_mon;								\
41279257534SDaniel Bristot de Oliveira 												\
41379257534SDaniel Bristot de Oliveira 	if (!da_monitor_enabled_##name())							\
41479257534SDaniel Bristot de Oliveira 		return 0;									\
41579257534SDaniel Bristot de Oliveira 												\
41679257534SDaniel Bristot de Oliveira 	da_mon = da_get_monitor_##name();							\
41779257534SDaniel Bristot de Oliveira 												\
41879257534SDaniel Bristot de Oliveira 	if (unlikely(!da_monitoring_##name(da_mon))) {						\
41979257534SDaniel Bristot de Oliveira 		da_monitor_start_##name(da_mon);						\
42079257534SDaniel Bristot de Oliveira 		return 0;									\
42179257534SDaniel Bristot de Oliveira 	}											\
42279257534SDaniel Bristot de Oliveira 												\
42379257534SDaniel Bristot de Oliveira 	__da_handle_event_##name(da_mon, event);						\
42479257534SDaniel Bristot de Oliveira 												\
42579257534SDaniel Bristot de Oliveira 	return 1;										\
42679257534SDaniel Bristot de Oliveira }												\
42779257534SDaniel Bristot de Oliveira 												\
42879257534SDaniel Bristot de Oliveira /*												\
42979257534SDaniel Bristot de Oliveira  * da_handle_start_run_event_##name - start monitoring and handle event				\
43079257534SDaniel Bristot de Oliveira  *												\
43179257534SDaniel Bristot de Oliveira  * This function is used to notify the monitor that the system is in the			\
43279257534SDaniel Bristot de Oliveira  * initial state, so the monitor can start monitoring and handling event.			\
43379257534SDaniel Bristot de Oliveira  */												\
43479257534SDaniel Bristot de Oliveira static inline bool da_handle_start_run_event_##name(enum events_##name event)			\
43579257534SDaniel Bristot de Oliveira {												\
43679257534SDaniel Bristot de Oliveira 	struct da_monitor *da_mon;								\
43779257534SDaniel Bristot de Oliveira 												\
43879257534SDaniel Bristot de Oliveira 	if (!da_monitor_enabled_##name())							\
43979257534SDaniel Bristot de Oliveira 		return 0;									\
44079257534SDaniel Bristot de Oliveira 												\
44179257534SDaniel Bristot de Oliveira 	da_mon = da_get_monitor_##name();							\
44279257534SDaniel Bristot de Oliveira 												\
44379257534SDaniel Bristot de Oliveira 	if (unlikely(!da_monitoring_##name(da_mon)))						\
44479257534SDaniel Bristot de Oliveira 		da_monitor_start_##name(da_mon);						\
44579257534SDaniel Bristot de Oliveira 												\
44679257534SDaniel Bristot de Oliveira 	__da_handle_event_##name(da_mon, event);						\
44779257534SDaniel Bristot de Oliveira 												\
44879257534SDaniel Bristot de Oliveira 	return 1;										\
44979257534SDaniel Bristot de Oliveira }
45079257534SDaniel Bristot de Oliveira 
45179257534SDaniel Bristot de Oliveira /*
45279257534SDaniel Bristot de Oliveira  * Handle event for per task.
45379257534SDaniel Bristot de Oliveira  */
45479257534SDaniel Bristot de Oliveira #define DECLARE_DA_MON_MONITOR_HANDLER_PER_TASK(name, type)					\
45579257534SDaniel Bristot de Oliveira 												\
45679257534SDaniel Bristot de Oliveira static inline void										\
45779257534SDaniel Bristot de Oliveira __da_handle_event_##name(struct da_monitor *da_mon, struct task_struct *tsk,			\
45879257534SDaniel Bristot de Oliveira 			 enum events_##name event)						\
45979257534SDaniel Bristot de Oliveira {												\
46079257534SDaniel Bristot de Oliveira 	bool retval;										\
46179257534SDaniel Bristot de Oliveira 												\
46279257534SDaniel Bristot de Oliveira 	retval = da_event_##name(da_mon, tsk, event);						\
46379257534SDaniel Bristot de Oliveira 	if (!retval)										\
46479257534SDaniel Bristot de Oliveira 		da_monitor_reset_##name(da_mon);						\
46579257534SDaniel Bristot de Oliveira }												\
46679257534SDaniel Bristot de Oliveira 												\
46779257534SDaniel Bristot de Oliveira /*												\
46879257534SDaniel Bristot de Oliveira  * da_handle_event_##name - handle an event							\
46979257534SDaniel Bristot de Oliveira  */												\
47079257534SDaniel Bristot de Oliveira static inline void										\
47179257534SDaniel Bristot de Oliveira da_handle_event_##name(struct task_struct *tsk, enum events_##name event)			\
47279257534SDaniel Bristot de Oliveira {												\
47379257534SDaniel Bristot de Oliveira 	struct da_monitor *da_mon = da_get_monitor_##name(tsk);					\
47479257534SDaniel Bristot de Oliveira 	bool retval;										\
47579257534SDaniel Bristot de Oliveira 												\
47679257534SDaniel Bristot de Oliveira 	retval = da_monitor_handling_event_##name(da_mon);					\
47779257534SDaniel Bristot de Oliveira 	if (!retval)										\
47879257534SDaniel Bristot de Oliveira 		return;										\
47979257534SDaniel Bristot de Oliveira 												\
48079257534SDaniel Bristot de Oliveira 	__da_handle_event_##name(da_mon, tsk, event);						\
48179257534SDaniel Bristot de Oliveira }												\
48279257534SDaniel Bristot de Oliveira 												\
48379257534SDaniel Bristot de Oliveira /*												\
48479257534SDaniel Bristot de Oliveira  * da_handle_start_event_##name - start monitoring or handle event				\
48579257534SDaniel Bristot de Oliveira  *												\
48679257534SDaniel Bristot de Oliveira  * This function is used to notify the monitor that the system is returning			\
48779257534SDaniel Bristot de Oliveira  * to the initial state, so the monitor can start monitoring in the next event.			\
48879257534SDaniel Bristot de Oliveira  * Thus:											\
48979257534SDaniel Bristot de Oliveira  *												\
49079257534SDaniel Bristot de Oliveira  * If the monitor already started, handle the event.						\
49179257534SDaniel Bristot de Oliveira  * If the monitor did not start yet, start the monitor but skip the event.			\
49279257534SDaniel Bristot de Oliveira  */												\
49379257534SDaniel Bristot de Oliveira static inline bool										\
49479257534SDaniel Bristot de Oliveira da_handle_start_event_##name(struct task_struct *tsk, enum events_##name event)			\
49579257534SDaniel Bristot de Oliveira {												\
49679257534SDaniel Bristot de Oliveira 	struct da_monitor *da_mon;								\
49779257534SDaniel Bristot de Oliveira 												\
49879257534SDaniel Bristot de Oliveira 	if (!da_monitor_enabled_##name())							\
49979257534SDaniel Bristot de Oliveira 		return 0;									\
50079257534SDaniel Bristot de Oliveira 												\
50179257534SDaniel Bristot de Oliveira 	da_mon = da_get_monitor_##name(tsk);							\
50279257534SDaniel Bristot de Oliveira 												\
50379257534SDaniel Bristot de Oliveira 	if (unlikely(!da_monitoring_##name(da_mon))) {						\
50479257534SDaniel Bristot de Oliveira 		da_monitor_start_##name(da_mon);						\
50579257534SDaniel Bristot de Oliveira 		return 0;									\
50679257534SDaniel Bristot de Oliveira 	}											\
50779257534SDaniel Bristot de Oliveira 												\
50879257534SDaniel Bristot de Oliveira 	__da_handle_event_##name(da_mon, tsk, event);						\
50979257534SDaniel Bristot de Oliveira 												\
51079257534SDaniel Bristot de Oliveira 	return 1;										\
51179257534SDaniel Bristot de Oliveira }
51279257534SDaniel Bristot de Oliveira 
51379257534SDaniel Bristot de Oliveira /*
51479257534SDaniel Bristot de Oliveira  * Entry point for the global monitor.
51579257534SDaniel Bristot de Oliveira  */
51679257534SDaniel Bristot de Oliveira #define DECLARE_DA_MON_GLOBAL(name, type)							\
51779257534SDaniel Bristot de Oliveira 												\
51879257534SDaniel Bristot de Oliveira DECLARE_AUTOMATA_HELPERS(name, type)								\
51979257534SDaniel Bristot de Oliveira DECLARE_DA_MON_GENERIC_HELPERS(name, type)							\
52079257534SDaniel Bristot de Oliveira DECLARE_DA_MON_MODEL_HANDLER_IMPLICIT(name, type)						\
52179257534SDaniel Bristot de Oliveira DECLARE_DA_MON_INIT_GLOBAL(name, type)								\
52279257534SDaniel Bristot de Oliveira DECLARE_DA_MON_MONITOR_HANDLER_IMPLICIT(name, type)
52379257534SDaniel Bristot de Oliveira 
52479257534SDaniel Bristot de Oliveira /*
52579257534SDaniel Bristot de Oliveira  * Entry point for the per-cpu monitor.
52679257534SDaniel Bristot de Oliveira  */
52779257534SDaniel Bristot de Oliveira #define DECLARE_DA_MON_PER_CPU(name, type)							\
52879257534SDaniel Bristot de Oliveira 												\
52979257534SDaniel Bristot de Oliveira DECLARE_AUTOMATA_HELPERS(name, type)								\
53079257534SDaniel Bristot de Oliveira DECLARE_DA_MON_GENERIC_HELPERS(name, type)							\
53179257534SDaniel Bristot de Oliveira DECLARE_DA_MON_MODEL_HANDLER_IMPLICIT(name, type)						\
53279257534SDaniel Bristot de Oliveira DECLARE_DA_MON_INIT_PER_CPU(name, type)								\
53379257534SDaniel Bristot de Oliveira DECLARE_DA_MON_MONITOR_HANDLER_IMPLICIT(name, type)
53479257534SDaniel Bristot de Oliveira 
53579257534SDaniel Bristot de Oliveira /*
53679257534SDaniel Bristot de Oliveira  * Entry point for the per-task monitor.
53779257534SDaniel Bristot de Oliveira  */
53879257534SDaniel Bristot de Oliveira #define DECLARE_DA_MON_PER_TASK(name, type)							\
53979257534SDaniel Bristot de Oliveira 												\
54079257534SDaniel Bristot de Oliveira DECLARE_AUTOMATA_HELPERS(name, type)								\
54179257534SDaniel Bristot de Oliveira DECLARE_DA_MON_GENERIC_HELPERS(name, type)							\
54279257534SDaniel Bristot de Oliveira DECLARE_DA_MON_MODEL_HANDLER_PER_TASK(name, type)						\
54379257534SDaniel Bristot de Oliveira DECLARE_DA_MON_INIT_PER_TASK(name, type)							\
54479257534SDaniel Bristot de Oliveira DECLARE_DA_MON_MONITOR_HANDLER_PER_TASK(name, type)
545