Merge tag 'drm-intel-gt-next-2022-09-16' of git://anongit.freedesktop.org/drm/drm...
[linux-block.git] / include / rv / da_monitor.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 2019-2022 Red Hat, Inc. Daniel Bristot de Oliveira <bristot@kernel.org>
4  *
5  * Deterministic automata (DA) monitor functions, to be used together
6  * with automata models in C generated by the dot2k tool.
7  *
8  * The dot2k tool is available at tools/verification/dot2k/
9  *
10  * For further information, see:
11  *   Documentation/trace/rv/da_monitor_synthesis.rst
12  */
13
14 #include <rv/automata.h>
15 #include <linux/rv.h>
16 #include <linux/bug.h>
17
18 #ifdef CONFIG_RV_REACTORS
19
20 #define DECLARE_RV_REACTING_HELPERS(name, type)                                                 \
21 static char REACT_MSG_##name[1024];                                                             \
22                                                                                                 \
23 static inline char *format_react_msg_##name(type curr_state, type event)                        \
24 {                                                                                               \
25         snprintf(REACT_MSG_##name, 1024,                                                        \
26                  "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         return REACT_MSG_##name;                                                                \
31 }                                                                                               \
32                                                                                                 \
33 static void cond_react_##name(char *msg)                                                        \
34 {                                                                                               \
35         if (rv_##name.react)                                                                    \
36                 rv_##name.react(msg);                                                           \
37 }                                                                                               \
38                                                                                                 \
39 static bool rv_reacting_on_##name(void)                                                         \
40 {                                                                                               \
41         return rv_reacting_on();                                                                \
42 }
43
44 #else /* CONFIG_RV_REACTOR */
45
46 #define DECLARE_RV_REACTING_HELPERS(name, type)                                                 \
47 static inline char *format_react_msg_##name(type curr_state, type event)                        \
48 {                                                                                               \
49         return NULL;                                                                            \
50 }                                                                                               \
51                                                                                                 \
52 static void cond_react_##name(char *msg)                                                        \
53 {                                                                                               \
54         return;                                                                                 \
55 }                                                                                               \
56                                                                                                 \
57 static bool rv_reacting_on_##name(void)                                                         \
58 {                                                                                               \
59         return 0;                                                                               \
60 }
61 #endif
62
63 /*
64  * Generic helpers for all types of deterministic automata monitors.
65  */
66 #define DECLARE_DA_MON_GENERIC_HELPERS(name, type)                                              \
67                                                                                                 \
68 DECLARE_RV_REACTING_HELPERS(name, type)                                                         \
69                                                                                                 \
70 /*                                                                                              \
71  * da_monitor_reset_##name - reset a monitor and setting it to init state                       \
72  */                                                                                             \
73 static inline void da_monitor_reset_##name(struct da_monitor *da_mon)                           \
74 {                                                                                               \
75         da_mon->monitoring = 0;                                                                 \
76         da_mon->curr_state = model_get_initial_state_##name();                                  \
77 }                                                                                               \
78                                                                                                 \
79 /*                                                                                              \
80  * da_monitor_curr_state_##name - return the current state                                      \
81  */                                                                                             \
82 static inline type da_monitor_curr_state_##name(struct da_monitor *da_mon)                      \
83 {                                                                                               \
84         return da_mon->curr_state;                                                              \
85 }                                                                                               \
86                                                                                                 \
87 /*                                                                                              \
88  * da_monitor_set_state_##name - set the new current state                                      \
89  */                                                                                             \
90 static inline void                                                                              \
91 da_monitor_set_state_##name(struct da_monitor *da_mon, enum states_##name state)                \
92 {                                                                                               \
93         da_mon->curr_state = state;                                                             \
94 }                                                                                               \
95                                                                                                 \
96 /*                                                                                              \
97  * da_monitor_start_##name - start monitoring                                                   \
98  *                                                                                              \
99  * The monitor will ignore all events until monitoring is set to true. This                     \
100  * function needs to be called to tell the monitor to start monitoring.                         \
101  */                                                                                             \
102 static inline void da_monitor_start_##name(struct da_monitor *da_mon)                           \
103 {                                                                                               \
104         da_mon->curr_state = model_get_initial_state_##name();                                  \
105         da_mon->monitoring = 1;                                                                 \
106 }                                                                                               \
107                                                                                                 \
108 /*                                                                                              \
109  * da_monitoring_##name - returns true if the monitor is processing events                      \
110  */                                                                                             \
111 static inline bool da_monitoring_##name(struct da_monitor *da_mon)                              \
112 {                                                                                               \
113         return da_mon->monitoring;                                                              \
114 }                                                                                               \
115                                                                                                 \
116 /*                                                                                              \
117  * da_monitor_enabled_##name - checks if the monitor is enabled                                 \
118  */                                                                                             \
119 static inline bool da_monitor_enabled_##name(void)                                              \
120 {                                                                                               \
121         /* global switch */                                                                     \
122         if (unlikely(!rv_monitoring_on()))                                                      \
123                 return 0;                                                                       \
124                                                                                                 \
125         /* monitor enabled */                                                                   \
126         if (unlikely(!rv_##name.enabled))                                                       \
127                 return 0;                                                                       \
128                                                                                                 \
129         return 1;                                                                               \
130 }                                                                                               \
131                                                                                                 \
132 /*                                                                                              \
133  * da_monitor_handling_event_##name - checks if the monitor is ready to handle events           \
134  */                                                                                             \
135 static inline bool da_monitor_handling_event_##name(struct da_monitor *da_mon)                  \
136 {                                                                                               \
137                                                                                                 \
138         if (!da_monitor_enabled_##name())                                                       \
139                 return 0;                                                                       \
140                                                                                                 \
141         /* monitor is actually monitoring */                                                    \
142         if (unlikely(!da_monitoring_##name(da_mon)))                                            \
143                 return 0;                                                                       \
144                                                                                                 \
145         return 1;                                                                               \
146 }
147
148 /*
149  * Event handler for implicit monitors. Implicit monitor is the one which the
150  * handler does not need to specify which da_monitor to manipulate. Examples
151  * of implicit monitor are the per_cpu or the global ones.
152  */
153 #define DECLARE_DA_MON_MODEL_HANDLER_IMPLICIT(name, type)                                       \
154                                                                                                 \
155 static inline bool                                                                              \
156 da_event_##name(struct da_monitor *da_mon, enum events_##name event)                            \
157 {                                                                                               \
158         type curr_state = da_monitor_curr_state_##name(da_mon);                                 \
159         type next_state = model_get_next_state_##name(curr_state, event);                       \
160                                                                                                 \
161         if (next_state != INVALID_STATE) {                                                      \
162                 da_monitor_set_state_##name(da_mon, next_state);                                \
163                                                                                                 \
164                 trace_event_##name(model_get_state_name_##name(curr_state),                     \
165                                    model_get_event_name_##name(event),                          \
166                                    model_get_state_name_##name(next_state),                     \
167                                    model_is_final_state_##name(next_state));                    \
168                                                                                                 \
169                 return true;                                                                    \
170         }                                                                                       \
171                                                                                                 \
172         if (rv_reacting_on_##name())                                                            \
173                 cond_react_##name(format_react_msg_##name(curr_state, event));                  \
174                                                                                                 \
175         trace_error_##name(model_get_state_name_##name(curr_state),                             \
176                            model_get_event_name_##name(event));                                 \
177                                                                                                 \
178         return false;                                                                           \
179 }                                                                                               \
180
181 /*
182  * Event handler for per_task monitors.
183  */
184 #define DECLARE_DA_MON_MODEL_HANDLER_PER_TASK(name, type)                                       \
185                                                                                                 \
186 static inline bool da_event_##name(struct da_monitor *da_mon, struct task_struct *tsk,          \
187                                    enum events_##name event)                                    \
188 {                                                                                               \
189         type curr_state = da_monitor_curr_state_##name(da_mon);                                 \
190         type next_state = model_get_next_state_##name(curr_state, event);                       \
191                                                                                                 \
192         if (next_state != INVALID_STATE) {                                                      \
193                 da_monitor_set_state_##name(da_mon, next_state);                                \
194                                                                                                 \
195                 trace_event_##name(tsk->pid,                                                    \
196                                    model_get_state_name_##name(curr_state),                     \
197                                    model_get_event_name_##name(event),                          \
198                                    model_get_state_name_##name(next_state),                     \
199                                    model_is_final_state_##name(next_state));                    \
200                                                                                                 \
201                 return true;                                                                    \
202         }                                                                                       \
203                                                                                                 \
204         if (rv_reacting_on_##name())                                                            \
205                 cond_react_##name(format_react_msg_##name(curr_state, event));                  \
206                                                                                                 \
207         trace_error_##name(tsk->pid,                                                            \
208                            model_get_state_name_##name(curr_state),                             \
209                            model_get_event_name_##name(event));                                 \
210                                                                                                 \
211         return false;                                                                           \
212 }
213
214 /*
215  * Functions to define, init and get a global monitor.
216  */
217 #define DECLARE_DA_MON_INIT_GLOBAL(name, type)                                                  \
218                                                                                                 \
219 /*                                                                                              \
220  * global monitor (a single variable)                                                           \
221  */                                                                                             \
222 static struct da_monitor da_mon_##name;                                                         \
223                                                                                                 \
224 /*                                                                                              \
225  * da_get_monitor_##name - return the global monitor address                                    \
226  */                                                                                             \
227 static struct da_monitor *da_get_monitor_##name(void)                                           \
228 {                                                                                               \
229         return &da_mon_##name;                                                                  \
230 }                                                                                               \
231                                                                                                 \
232 /*                                                                                              \
233  * da_monitor_reset_all_##name - reset the single monitor                                       \
234  */                                                                                             \
235 static void da_monitor_reset_all_##name(void)                                                   \
236 {                                                                                               \
237         da_monitor_reset_##name(da_get_monitor_##name());                                       \
238 }                                                                                               \
239                                                                                                 \
240 /*                                                                                              \
241  * da_monitor_init_##name - initialize a monitor                                                \
242  */                                                                                             \
243 static inline int da_monitor_init_##name(void)                                                  \
244 {                                                                                               \
245         da_monitor_reset_all_##name();                                                          \
246         return 0;                                                                               \
247 }                                                                                               \
248                                                                                                 \
249 /*                                                                                              \
250  * da_monitor_destroy_##name - destroy the monitor                                              \
251  */                                                                                             \
252 static inline void da_monitor_destroy_##name(void)                                              \
253 {                                                                                               \
254         return;                                                                                 \
255 }
256
257 /*
258  * Functions to define, init and get a per-cpu monitor.
259  */
260 #define DECLARE_DA_MON_INIT_PER_CPU(name, type)                                                 \
261                                                                                                 \
262 /*                                                                                              \
263  * per-cpu monitor variables                                                                    \
264  */                                                                                             \
265 DEFINE_PER_CPU(struct da_monitor, da_mon_##name);                                               \
266                                                                                                 \
267 /*                                                                                              \
268  * da_get_monitor_##name - return current CPU monitor address                                   \
269  */                                                                                             \
270 static struct da_monitor *da_get_monitor_##name(void)                                           \
271 {                                                                                               \
272         return this_cpu_ptr(&da_mon_##name);                                                    \
273 }                                                                                               \
274                                                                                                 \
275 /*                                                                                              \
276  * da_monitor_reset_all_##name - reset all CPUs' monitor                                        \
277  */                                                                                             \
278 static void da_monitor_reset_all_##name(void)                                                   \
279 {                                                                                               \
280         struct da_monitor *da_mon;                                                              \
281         int cpu;                                                                                \
282         for_each_cpu(cpu, cpu_online_mask) {                                                    \
283                 da_mon = per_cpu_ptr(&da_mon_##name, cpu);                                      \
284                 da_monitor_reset_##name(da_mon);                                                \
285         }                                                                                       \
286 }                                                                                               \
287                                                                                                 \
288 /*                                                                                              \
289  * da_monitor_init_##name - initialize all CPUs' monitor                                        \
290  */                                                                                             \
291 static inline int da_monitor_init_##name(void)                                                  \
292 {                                                                                               \
293         da_monitor_reset_all_##name();                                                          \
294         return 0;                                                                               \
295 }                                                                                               \
296                                                                                                 \
297 /*                                                                                              \
298  * da_monitor_destroy_##name - destroy the monitor                                              \
299  */                                                                                             \
300 static inline void da_monitor_destroy_##name(void)                                              \
301 {                                                                                               \
302         return;                                                                                 \
303 }
304
305 /*
306  * Functions to define, init and get a per-task monitor.
307  */
308 #define DECLARE_DA_MON_INIT_PER_TASK(name, type)                                                \
309                                                                                                 \
310 /*                                                                                              \
311  * The per-task monitor is stored a vector in the task struct. This variable                    \
312  * stores the position on the vector reserved for this monitor.                                 \
313  */                                                                                             \
314 static int task_mon_slot_##name = RV_PER_TASK_MONITOR_INIT;                                     \
315                                                                                                 \
316 /*                                                                                              \
317  * da_get_monitor_##name - return the monitor in the allocated slot for tsk                     \
318  */                                                                                             \
319 static inline struct da_monitor *da_get_monitor_##name(struct task_struct *tsk)                 \
320 {                                                                                               \
321         return &tsk->rv[task_mon_slot_##name].da_mon;                                           \
322 }                                                                                               \
323                                                                                                 \
324 static void da_monitor_reset_all_##name(void)                                                   \
325 {                                                                                               \
326         struct task_struct *g, *p;                                                              \
327                                                                                                 \
328         read_lock(&tasklist_lock);                                                              \
329         for_each_process_thread(g, p)                                                           \
330                 da_monitor_reset_##name(da_get_monitor_##name(p));                              \
331         read_unlock(&tasklist_lock);                                                            \
332 }                                                                                               \
333                                                                                                 \
334 /*                                                                                              \
335  * da_monitor_init_##name - initialize the per-task monitor                                     \
336  *                                                                                              \
337  * Try to allocate a slot in the task's vector of monitors. If there                            \
338  * is an available slot, use it and reset all task's monitor.                                   \
339  */                                                                                             \
340 static int da_monitor_init_##name(void)                                                         \
341 {                                                                                               \
342         int slot;                                                                               \
343                                                                                                 \
344         slot = rv_get_task_monitor_slot();                                                      \
345         if (slot < 0 || slot >= RV_PER_TASK_MONITOR_INIT)                                       \
346                 return slot;                                                                    \
347                                                                                                 \
348         task_mon_slot_##name = slot;                                                            \
349                                                                                                 \
350         da_monitor_reset_all_##name();                                                          \
351         return 0;                                                                               \
352 }                                                                                               \
353                                                                                                 \
354 /*                                                                                              \
355  * da_monitor_destroy_##name - return the allocated slot                                        \
356  */                                                                                             \
357 static inline void da_monitor_destroy_##name(void)                                              \
358 {                                                                                               \
359         if (task_mon_slot_##name == RV_PER_TASK_MONITOR_INIT) {                                 \
360                 WARN_ONCE(1, "Disabling a disabled monitor: " #name);                           \
361                 return;                                                                         \
362         }                                                                                       \
363         rv_put_task_monitor_slot(task_mon_slot_##name);                                         \
364         task_mon_slot_##name = RV_PER_TASK_MONITOR_INIT;                                        \
365         return;                                                                                 \
366 }
367
368 /*
369  * Handle event for implicit monitor: da_get_monitor_##name() will figure out
370  * the monitor.
371  */
372 #define DECLARE_DA_MON_MONITOR_HANDLER_IMPLICIT(name, type)                                     \
373                                                                                                 \
374 static inline void __da_handle_event_##name(struct da_monitor *da_mon,                          \
375                                             enum events_##name event)                           \
376 {                                                                                               \
377         bool retval;                                                                            \
378                                                                                                 \
379         retval = da_event_##name(da_mon, event);                                                \
380         if (!retval)                                                                            \
381                 da_monitor_reset_##name(da_mon);                                                \
382 }                                                                                               \
383                                                                                                 \
384 /*                                                                                              \
385  * da_handle_event_##name - handle an event                                                     \
386  */                                                                                             \
387 static inline void da_handle_event_##name(enum events_##name event)                             \
388 {                                                                                               \
389         struct da_monitor *da_mon = da_get_monitor_##name();                                    \
390         bool retval;                                                                            \
391                                                                                                 \
392         retval = da_monitor_handling_event_##name(da_mon);                                      \
393         if (!retval)                                                                            \
394                 return;                                                                         \
395                                                                                                 \
396         __da_handle_event_##name(da_mon, event);                                                \
397 }                                                                                               \
398                                                                                                 \
399 /*                                                                                              \
400  * da_handle_start_event_##name - start monitoring or handle event                              \
401  *                                                                                              \
402  * This function is used to notify the monitor that the system is returning                     \
403  * to the initial state, so the monitor can start monitoring in the next event.                 \
404  * Thus:                                                                                        \
405  *                                                                                              \
406  * If the monitor already started, handle the event.                                            \
407  * If the monitor did not start yet, start the monitor but skip the event.                      \
408  */                                                                                             \
409 static inline bool da_handle_start_event_##name(enum events_##name event)                       \
410 {                                                                                               \
411         struct da_monitor *da_mon;                                                              \
412                                                                                                 \
413         if (!da_monitor_enabled_##name())                                                       \
414                 return 0;                                                                       \
415                                                                                                 \
416         da_mon = da_get_monitor_##name();                                                       \
417                                                                                                 \
418         if (unlikely(!da_monitoring_##name(da_mon))) {                                          \
419                 da_monitor_start_##name(da_mon);                                                \
420                 return 0;                                                                       \
421         }                                                                                       \
422                                                                                                 \
423         __da_handle_event_##name(da_mon, event);                                                \
424                                                                                                 \
425         return 1;                                                                               \
426 }                                                                                               \
427                                                                                                 \
428 /*                                                                                              \
429  * da_handle_start_run_event_##name - start monitoring and handle event                         \
430  *                                                                                              \
431  * This function is used to notify the monitor that the system is in the                        \
432  * initial state, so the monitor can start monitoring and handling event.                       \
433  */                                                                                             \
434 static inline bool da_handle_start_run_event_##name(enum events_##name event)                   \
435 {                                                                                               \
436         struct da_monitor *da_mon;                                                              \
437                                                                                                 \
438         if (!da_monitor_enabled_##name())                                                       \
439                 return 0;                                                                       \
440                                                                                                 \
441         da_mon = da_get_monitor_##name();                                                       \
442                                                                                                 \
443         if (unlikely(!da_monitoring_##name(da_mon)))                                            \
444                 da_monitor_start_##name(da_mon);                                                \
445                                                                                                 \
446         __da_handle_event_##name(da_mon, event);                                                \
447                                                                                                 \
448         return 1;                                                                               \
449 }
450
451 /*
452  * Handle event for per task.
453  */
454 #define DECLARE_DA_MON_MONITOR_HANDLER_PER_TASK(name, type)                                     \
455                                                                                                 \
456 static inline void                                                                              \
457 __da_handle_event_##name(struct da_monitor *da_mon, struct task_struct *tsk,                    \
458                          enum events_##name event)                                              \
459 {                                                                                               \
460         bool retval;                                                                            \
461                                                                                                 \
462         retval = da_event_##name(da_mon, tsk, event);                                           \
463         if (!retval)                                                                            \
464                 da_monitor_reset_##name(da_mon);                                                \
465 }                                                                                               \
466                                                                                                 \
467 /*                                                                                              \
468  * da_handle_event_##name - handle an event                                                     \
469  */                                                                                             \
470 static inline void                                                                              \
471 da_handle_event_##name(struct task_struct *tsk, enum events_##name event)                       \
472 {                                                                                               \
473         struct da_monitor *da_mon = da_get_monitor_##name(tsk);                                 \
474         bool retval;                                                                            \
475                                                                                                 \
476         retval = da_monitor_handling_event_##name(da_mon);                                      \
477         if (!retval)                                                                            \
478                 return;                                                                         \
479                                                                                                 \
480         __da_handle_event_##name(da_mon, tsk, event);                                           \
481 }                                                                                               \
482                                                                                                 \
483 /*                                                                                              \
484  * da_handle_start_event_##name - start monitoring or handle event                              \
485  *                                                                                              \
486  * This function is used to notify the monitor that the system is returning                     \
487  * to the initial state, so the monitor can start monitoring in the next event.                 \
488  * Thus:                                                                                        \
489  *                                                                                              \
490  * If the monitor already started, handle the event.                                            \
491  * If the monitor did not start yet, start the monitor but skip the event.                      \
492  */                                                                                             \
493 static inline bool                                                                              \
494 da_handle_start_event_##name(struct task_struct *tsk, enum events_##name event)                 \
495 {                                                                                               \
496         struct da_monitor *da_mon;                                                              \
497                                                                                                 \
498         if (!da_monitor_enabled_##name())                                                       \
499                 return 0;                                                                       \
500                                                                                                 \
501         da_mon = da_get_monitor_##name(tsk);                                                    \
502                                                                                                 \
503         if (unlikely(!da_monitoring_##name(da_mon))) {                                          \
504                 da_monitor_start_##name(da_mon);                                                \
505                 return 0;                                                                       \
506         }                                                                                       \
507                                                                                                 \
508         __da_handle_event_##name(da_mon, tsk, event);                                           \
509                                                                                                 \
510         return 1;                                                                               \
511 }
512
513 /*
514  * Entry point for the global monitor.
515  */
516 #define DECLARE_DA_MON_GLOBAL(name, type)                                                       \
517                                                                                                 \
518 DECLARE_AUTOMATA_HELPERS(name, type)                                                            \
519 DECLARE_DA_MON_GENERIC_HELPERS(name, type)                                                      \
520 DECLARE_DA_MON_MODEL_HANDLER_IMPLICIT(name, type)                                               \
521 DECLARE_DA_MON_INIT_GLOBAL(name, type)                                                          \
522 DECLARE_DA_MON_MONITOR_HANDLER_IMPLICIT(name, type)
523
524 /*
525  * Entry point for the per-cpu monitor.
526  */
527 #define DECLARE_DA_MON_PER_CPU(name, type)                                                      \
528                                                                                                 \
529 DECLARE_AUTOMATA_HELPERS(name, type)                                                            \
530 DECLARE_DA_MON_GENERIC_HELPERS(name, type)                                                      \
531 DECLARE_DA_MON_MODEL_HANDLER_IMPLICIT(name, type)                                               \
532 DECLARE_DA_MON_INIT_PER_CPU(name, type)                                                         \
533 DECLARE_DA_MON_MONITOR_HANDLER_IMPLICIT(name, type)
534
535 /*
536  * Entry point for the per-task monitor.
537  */
538 #define DECLARE_DA_MON_PER_TASK(name, type)                                                     \
539                                                                                                 \
540 DECLARE_AUTOMATA_HELPERS(name, type)                                                            \
541 DECLARE_DA_MON_GENERIC_HELPERS(name, type)                                                      \
542 DECLARE_DA_MON_MODEL_HANDLER_PER_TASK(name, type)                                               \
543 DECLARE_DA_MON_INIT_PER_TASK(name, type)                                                        \
544 DECLARE_DA_MON_MONITOR_HANDLER_PER_TASK(name, type)