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