xref: /linux/include/rv/da_monitor.h (revision 8da2a88383658dac97769ed8f807ef6100a69480)
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 rvgen tool.
7  *
8  * The rvgen tool is available at tools/verification/rvgen/
9  *
10  * For further information, see:
11  *   Documentation/trace/rv/monitor_synthesis.rst
12  */
13 
14 #ifndef _RV_DA_MONITOR_H
15 #define _RV_DA_MONITOR_H
16 
17 #include <rv/automata.h>
18 #include <linux/rv.h>
19 #include <linux/stringify.h>
20 #include <linux/bug.h>
21 #include <linux/sched.h>
22 #include <linux/slab.h>
23 #include <linux/hashtable.h>
24 
25 /*
26  * Per-cpu variables require a unique name although static in some
27  * configurations (e.g. CONFIG_DEBUG_FORCE_WEAK_PER_CPU or alpha modules).
28  */
29 #define DA_MON_NAME CONCATENATE(da_mon_, MONITOR_NAME)
30 
31 static struct rv_monitor rv_this;
32 
33 /*
34  * Hook to allow the implementation of hybrid automata: define it with a
35  * function that takes curr_state, event and next_state and returns true if the
36  * environment constraints (e.g. timing) are satisfied, false otherwise.
37  */
38 #ifndef da_monitor_event_hook
39 #define da_monitor_event_hook(...) true
40 #endif
41 
42 /*
43  * Hook to allow the implementation of hybrid automata: define it with a
44  * function that takes the da_monitor and performs further initialisation
45  * (e.g. reset set up timers).
46  */
47 #ifndef da_monitor_init_hook
48 #define da_monitor_init_hook(da_mon)
49 #endif
50 
51 /*
52  * Hook to allow the implementation of hybrid automata: define it with a
53  * function that takes the da_monitor and performs further reset (e.g. reset
54  * all clocks).
55  */
56 #ifndef da_monitor_reset_hook
57 #define da_monitor_reset_hook(da_mon)
58 #endif
59 
60 /*
61  * Hook to allow the implementation of hybrid automata: define it with a
62  * function that waits for the termination of all monitors background
63  * activities (e.g. all timers). This hook can sleep.
64  */
65 #ifndef da_monitor_sync_hook
66 #define da_monitor_sync_hook()
67 #endif
68 
69 /*
70  * Type for the target id, default to int but can be overridden.
71  * A long type can work as hash table key (PER_OBJ) but will be downgraded to
72  * int in the event tracepoint.
73  * Unused for implicit monitors.
74  */
75 #ifndef da_id_type
76 #define da_id_type int
77 #endif
78 
79 static void react(enum states curr_state, enum events event)
80 {
81 	rv_react(&rv_this,
82 		 "rv: monitor %s does not allow event %s on state %s\n",
83 		 __stringify(MONITOR_NAME),
84 		 model_get_event_name(event),
85 		 model_get_state_name(curr_state));
86 }
87 
88 /*
89  * da_monitor_reset_state - reset a monitor and setting it to init state
90  */
91 static inline void da_monitor_reset_state(struct da_monitor *da_mon)
92 {
93 	WRITE_ONCE(da_mon->monitoring, 0);
94 	/* Pair with load in __ha_monitor_timer_callback */
95 	smp_store_release(&da_mon->curr_state, model_get_initial_state());
96 }
97 
98 /*
99  * da_monitor_reset - reset a monitor and setting it to init state
100  */
101 static inline void da_monitor_reset(struct da_monitor *da_mon)
102 {
103 	da_monitor_reset_hook(da_mon);
104 	da_monitor_reset_state(da_mon);
105 }
106 
107 /*
108  * da_monitor_start - start monitoring
109  *
110  * The monitor will ignore all events until monitoring is set to true. This
111  * function needs to be called to tell the monitor to start monitoring.
112  */
113 static inline void da_monitor_start(struct da_monitor *da_mon)
114 {
115 	da_mon->curr_state = model_get_initial_state();
116 	da_monitor_init_hook(da_mon);
117 	/* Pairs with smp_load_acquire in da_monitoring(). */
118 	smp_store_release(&da_mon->monitoring, 1);
119 }
120 
121 /*
122  * da_monitoring - returns true if the monitor is processing events
123  */
124 static inline bool da_monitoring(struct da_monitor *da_mon)
125 {
126 	/* Pairs with smp_store_release in da_monitor_start(). */
127 	return smp_load_acquire(&da_mon->monitoring);
128 }
129 
130 /*
131  * da_monitor_enabled - checks if the monitor is enabled
132  */
133 static inline bool da_monitor_enabled(void)
134 {
135 	/* global switch */
136 	if (unlikely(!rv_monitoring_on()))
137 		return 0;
138 
139 	/* monitor enabled */
140 	if (unlikely(!rv_this.enabled))
141 		return 0;
142 
143 	return 1;
144 }
145 
146 /*
147  * da_monitor_handling_event - checks if the monitor is ready to handle events
148  */
149 static inline bool da_monitor_handling_event(struct da_monitor *da_mon)
150 {
151 	if (!da_monitor_enabled())
152 		return 0;
153 
154 	/* monitor is actually monitoring */
155 	if (unlikely(!da_monitoring(da_mon)))
156 		return 0;
157 
158 	return 1;
159 }
160 
161 #if RV_MON_TYPE == RV_MON_GLOBAL
162 /*
163  * Functions to define, init and get a global monitor.
164  */
165 
166 /*
167  * global monitor (a single variable)
168  */
169 static struct da_monitor DA_MON_NAME;
170 
171 /*
172  * da_get_monitor - return the global monitor address
173  */
174 static struct da_monitor *da_get_monitor(void)
175 {
176 	return &DA_MON_NAME;
177 }
178 
179 /*
180  * __da_monitor_reset_all - reset the single monitor
181  */
182 static void __da_monitor_reset_all(void (*reset)(struct da_monitor *))
183 {
184 	reset(da_get_monitor());
185 }
186 
187 /*
188  * da_monitor_reset_all - reset the single monitor
189  */
190 static void da_monitor_reset_all(void)
191 {
192 	__da_monitor_reset_all(da_monitor_reset);
193 }
194 
195 /*
196  * da_monitor_reset_state_all - reset the single monitor
197  */
198 static inline void da_monitor_reset_state_all(void)
199 {
200 	__da_monitor_reset_all(da_monitor_reset_state);
201 }
202 
203 /*
204  * da_monitor_init - initialize a monitor
205  */
206 static inline int da_monitor_init(void)
207 {
208 	da_monitor_reset_state_all();
209 	return 0;
210 }
211 
212 /*
213  * da_monitor_destroy - destroy the monitor
214  */
215 static inline void da_monitor_destroy(void)
216 {
217 	da_monitor_reset_all();
218 	da_monitor_sync_hook();
219 }
220 
221 #ifndef da_implicit_guard
222 #define da_implicit_guard()
223 #endif
224 
225 #elif RV_MON_TYPE == RV_MON_PER_CPU
226 /*
227  * Functions to define, init and get a per-cpu monitor.
228  */
229 
230 /*
231  * per-cpu monitor variables
232  */
233 static DEFINE_PER_CPU(struct da_monitor, DA_MON_NAME);
234 
235 /*
236  * da_get_monitor - return current CPU monitor address
237  */
238 static struct da_monitor *da_get_monitor(void)
239 {
240 	return this_cpu_ptr(&DA_MON_NAME);
241 }
242 
243 /*
244  * __da_monitor_reset_all - reset all CPUs' monitor
245  */
246 static void __da_monitor_reset_all(void (*reset)(struct da_monitor *))
247 {
248 	struct da_monitor *da_mon;
249 	int cpu;
250 
251 	for_each_cpu(cpu, cpu_online_mask) {
252 		da_mon = per_cpu_ptr(&DA_MON_NAME, cpu);
253 		reset(da_mon);
254 	}
255 }
256 
257 /*
258  * da_monitor_reset_all - reset all CPUs' monitor
259  */
260 static void da_monitor_reset_all(void)
261 {
262 	__da_monitor_reset_all(da_monitor_reset);
263 }
264 
265 /*
266  * da_monitor_reset_state_all - reset all CPUs' monitor
267  */
268 static inline void da_monitor_reset_state_all(void)
269 {
270 	__da_monitor_reset_all(da_monitor_reset_state);
271 }
272 
273 /*
274  * da_monitor_init - initialize all CPUs' monitor
275  */
276 static inline int da_monitor_init(void)
277 {
278 	da_monitor_reset_state_all();
279 	return 0;
280 }
281 
282 /*
283  * da_monitor_destroy - destroy the monitor
284  */
285 static inline void da_monitor_destroy(void)
286 {
287 	da_monitor_reset_all();
288 	da_monitor_sync_hook();
289 }
290 
291 #ifndef da_implicit_guard
292 #define da_implicit_guard() guard(migrate)()
293 #endif
294 
295 #elif RV_MON_TYPE == RV_MON_PER_TASK
296 /*
297  * Functions to define, init and get a per-task monitor.
298  */
299 
300 /*
301  * The per-task monitor is stored a vector in the task struct. This variable
302  * stores the position on the vector reserved for this monitor.
303  */
304 static int task_mon_slot = RV_PER_TASK_MONITOR_INIT;
305 
306 /*
307  * da_get_monitor - return the monitor in the allocated slot for tsk
308  */
309 static inline struct da_monitor *da_get_monitor(struct task_struct *tsk)
310 {
311 	return &tsk->rv[task_mon_slot].da_mon;
312 }
313 
314 static inline void da_reset(struct task_struct *tsk)
315 {
316 	da_monitor_reset(da_get_monitor(tsk));
317 }
318 
319 /*
320  * da_get_target - return the task associated to the monitor
321  */
322 static inline struct task_struct *da_get_target(struct da_monitor *da_mon)
323 {
324 	return container_of(da_mon, struct task_struct, rv[task_mon_slot].da_mon);
325 }
326 
327 /*
328  * da_get_id - return the id associated to the monitor
329  *
330  * For per-task monitors, the id is the task's PID.
331  */
332 static inline da_id_type da_get_id(struct da_monitor *da_mon)
333 {
334 	return da_get_target(da_mon)->pid;
335 }
336 
337 static void __da_monitor_reset_all(void (*reset)(struct da_monitor *))
338 {
339 	struct task_struct *g, *p;
340 	int cpu;
341 
342 	scoped_guard(read_lock, &tasklist_lock) {
343 		for_each_process_thread(g, p)
344 			reset(da_get_monitor(p));
345 	}
346 	for_each_present_cpu(cpu)
347 		reset(da_get_monitor(idle_task(cpu)));
348 }
349 
350 static void da_monitor_reset_all(void)
351 {
352 	__da_monitor_reset_all(da_monitor_reset);
353 }
354 
355 static inline void da_monitor_reset_state_all(void)
356 {
357 	__da_monitor_reset_all(da_monitor_reset_state);
358 }
359 
360 /*
361  * da_monitor_init - initialize the per-task monitor
362  *
363  * Try to allocate a slot in the task's vector of monitors. If there
364  * is an available slot, use it and reset all task's monitor.
365  */
366 static int da_monitor_init(void)
367 {
368 	int slot;
369 
370 	slot = rv_get_task_monitor_slot();
371 	if (slot < 0 || slot >= RV_PER_TASK_MONITOR_INIT)
372 		return slot;
373 
374 	task_mon_slot = slot;
375 
376 	da_monitor_reset_state_all();
377 	return 0;
378 }
379 
380 /*
381  * da_monitor_destroy - return the allocated slot
382  *
383  * Wait for all in-flight handlers before returning the slot to avoid
384  * out-of-bound accesses.
385  */
386 static inline void da_monitor_destroy(void)
387 {
388 	if (task_mon_slot == RV_PER_TASK_MONITOR_INIT) {
389 		WARN_ONCE(1, "Disabling a disabled monitor: " __stringify(MONITOR_NAME));
390 		return;
391 	}
392 
393 	tracepoint_synchronize_unregister();
394 	da_monitor_reset_all();
395 	da_monitor_sync_hook();
396 
397 	rv_put_task_monitor_slot(task_mon_slot);
398 	task_mon_slot = RV_PER_TASK_MONITOR_INIT;
399 }
400 
401 #elif RV_MON_TYPE == RV_MON_PER_OBJ
402 /*
403  * Functions to define, init and get a per-object monitor.
404  */
405 
406 struct da_monitor_storage {
407 	da_id_type id;
408 	monitor_target target;
409 	union rv_task_monitor rv;
410 	struct hlist_node node;
411 	struct rcu_head rcu;
412 };
413 
414 #ifndef DA_MONITOR_HT_BITS
415 #define DA_MONITOR_HT_BITS 10
416 #endif
417 static DEFINE_HASHTABLE(da_monitor_ht, DA_MONITOR_HT_BITS);
418 
419 /*
420  * da_create_empty_storage - pre-allocate an empty storage
421  */
422 static inline struct da_monitor_storage *da_create_empty_storage(da_id_type id)
423 {
424 	struct da_monitor_storage *mon_storage;
425 
426 	mon_storage = kmalloc_nolock(sizeof(struct da_monitor_storage),
427 				     __GFP_ZERO, NUMA_NO_NODE);
428 	if (!mon_storage)
429 		return NULL;
430 
431 	hash_add_rcu(da_monitor_ht, &mon_storage->node, id);
432 	mon_storage->id = id;
433 	return mon_storage;
434 }
435 
436 /*
437  * da_create_storage - create the per-object storage
438  *
439  * The caller is responsible to synchronise writers, either with locks or
440  * implicitly. For instance, if da_create_storage is only called from a single
441  * event for target (e.g. sched_switch), it's safe to call this without locks.
442  */
443 static inline struct da_monitor *da_create_storage(da_id_type id,
444 						   monitor_target target,
445 						   struct da_monitor *da_mon)
446 {
447 	struct da_monitor_storage *mon_storage;
448 
449 	if (da_mon)
450 		return da_mon;
451 
452 	mon_storage = da_create_empty_storage(id);
453 	if (!mon_storage)
454 		return NULL;
455 
456 	mon_storage->target = target;
457 	return &mon_storage->rv.da_mon;
458 }
459 
460 /*
461  * __da_get_mon_storage - get the monitor storage from the hash table
462  */
463 static inline struct da_monitor_storage *__da_get_mon_storage(da_id_type id)
464 {
465 	struct da_monitor_storage *mon_storage;
466 
467 	lockdep_assert_in_rcu_read_lock();
468 	hash_for_each_possible_rcu(da_monitor_ht, mon_storage, node, id) {
469 		if (mon_storage->id == id)
470 			return mon_storage;
471 	}
472 
473 	return NULL;
474 }
475 
476 /*
477  * da_get_monitor - return the monitor for target
478  */
479 static struct da_monitor *da_get_monitor(da_id_type id, monitor_target target)
480 {
481 	struct da_monitor_storage *mon_storage;
482 
483 	mon_storage = __da_get_mon_storage(id);
484 	return mon_storage ? &mon_storage->rv.da_mon : NULL;
485 }
486 
487 /*
488  * da_get_target - return the object associated to the monitor
489  */
490 static inline monitor_target da_get_target(struct da_monitor *da_mon)
491 {
492 	return container_of(da_mon, struct da_monitor_storage, rv.da_mon)->target;
493 }
494 
495 /*
496  * da_get_id - return the id associated to the monitor
497  */
498 static inline da_id_type da_get_id(struct da_monitor *da_mon)
499 {
500 	return container_of(da_mon, struct da_monitor_storage, rv.da_mon)->id;
501 }
502 
503 /*
504  * da_create_or_get - create the per-object storage if not already there
505  *
506  * This needs a lookup so should be guarded by RCU, the condition is checked
507  * directly in da_create_storage()
508  */
509 static inline void da_create_or_get(da_id_type id, monitor_target target)
510 {
511 	guard(rcu)();
512 	da_create_storage(id, target, da_get_monitor(id, target));
513 }
514 
515 /*
516  * da_fill_empty_storage - store the target in a pre-allocated storage
517  *
518  * Can be used as a substitute of da_create_storage when starting a monitor in
519  * an environment where allocation is unsafe.
520  */
521 static inline struct da_monitor *da_fill_empty_storage(da_id_type id,
522 						       monitor_target target,
523 						       struct da_monitor *da_mon)
524 {
525 	if (unlikely(da_mon && !da_get_target(da_mon)))
526 		container_of(da_mon, struct da_monitor_storage, rv.da_mon)->target = target;
527 	return da_mon;
528 }
529 
530 /*
531  * da_get_target_by_id - return the object associated to the id
532  */
533 static inline monitor_target da_get_target_by_id(da_id_type id)
534 {
535 	struct da_monitor_storage *mon_storage;
536 
537 	guard(rcu)();
538 	mon_storage = __da_get_mon_storage(id);
539 
540 	if (unlikely(!mon_storage))
541 		return NULL;
542 	return mon_storage->target;
543 }
544 
545 /*
546  * da_destroy_storage - destroy the per-object storage
547  *
548  * The caller is responsible to synchronise writers, either with locks or
549  * implicitly. For instance, if da_destroy_storage is called at sched_exit and
550  * da_create_storage can never occur after that, it's safe to call this without
551  * locks.
552  * This function includes an RCU read-side critical section to synchronise
553  * against da_monitor_destroy().
554  */
555 static inline void da_destroy_storage(da_id_type id)
556 {
557 	struct da_monitor_storage *mon_storage;
558 
559 	guard(rcu)();
560 	mon_storage = __da_get_mon_storage(id);
561 
562 	if (!mon_storage)
563 		return;
564 	da_monitor_reset_hook(&mon_storage->rv.da_mon);
565 	hash_del_rcu(&mon_storage->node);
566 	kfree_rcu(mon_storage, rcu);
567 }
568 
569 static void __da_monitor_reset_all(void (*reset)(struct da_monitor *))
570 {
571 	struct da_monitor_storage *mon_storage;
572 	int bkt;
573 
574 	guard(rcu)();
575 	hash_for_each_rcu(da_monitor_ht, bkt, mon_storage, node)
576 		reset(&mon_storage->rv.da_mon);
577 }
578 
579 static void da_monitor_reset_all(void)
580 {
581 	__da_monitor_reset_all(da_monitor_reset);
582 }
583 
584 static inline void da_monitor_reset_state_all(void)
585 {
586 	__da_monitor_reset_all(da_monitor_reset_state);
587 }
588 
589 static inline int da_monitor_init(void)
590 {
591 	hash_init(da_monitor_ht);
592 	return 0;
593 }
594 
595 static inline void da_monitor_destroy(void)
596 {
597 	struct da_monitor_storage *mon_storage;
598 	struct hlist_node *tmp;
599 	int bkt;
600 
601 	tracepoint_synchronize_unregister();
602 	da_monitor_reset_all();
603 	da_monitor_sync_hook();
604 	/*
605 	 * This function is called after all probes are disabled and no longer
606 	 * pending, we can safely assume no concurrent user.
607 	 */
608 	hash_for_each_safe(da_monitor_ht, bkt, tmp, mon_storage, node) {
609 		hash_del_rcu(&mon_storage->node);
610 		kfree(mon_storage);
611 	}
612 }
613 
614 /*
615  * Allow the per-object monitors to run allocation manually, necessary if the
616  * start condition is in a context problematic for allocation (e.g. scheduling).
617  * In such case, if the storage was pre-allocated without a target, set it now.
618  */
619 #ifdef DA_SKIP_AUTO_ALLOC
620 #define da_prepare_storage da_fill_empty_storage
621 #else
622 #define da_prepare_storage da_create_storage
623 #endif /* DA_SKIP_AUTO_ALLOC */
624 
625 #endif /* RV_MON_TYPE */
626 
627 #if RV_MON_TYPE == RV_MON_GLOBAL || RV_MON_TYPE == RV_MON_PER_CPU
628 /*
629  * Trace events for implicit monitors. Implicit monitor is the one which the
630  * handler does not need to specify which da_monitor to manipulate. Examples
631  * of implicit monitor are the per_cpu or the global ones.
632  */
633 
634 static inline void da_trace_event(struct da_monitor *da_mon,
635 				  char *curr_state, char *event,
636 				  char *next_state, bool is_final,
637 				  da_id_type id)
638 {
639 	CONCATENATE(trace_event_, MONITOR_NAME)(curr_state, event, next_state,
640 						is_final);
641 }
642 
643 static inline void da_trace_error(struct da_monitor *da_mon,
644 				  char *curr_state, char *event,
645 				  da_id_type id)
646 {
647 	CONCATENATE(trace_error_, MONITOR_NAME)(curr_state, event);
648 }
649 
650 /*
651  * da_get_id - unused for implicit monitors
652  */
653 static inline da_id_type da_get_id(struct da_monitor *da_mon)
654 {
655 	return 0;
656 }
657 
658 #elif RV_MON_TYPE == RV_MON_PER_TASK || RV_MON_TYPE == RV_MON_PER_OBJ
659 /*
660  * Trace events for per_task/per_object monitors, report the target id.
661  */
662 
663 static inline void da_trace_event(struct da_monitor *da_mon,
664 				  char *curr_state, char *event,
665 				  char *next_state, bool is_final,
666 				  da_id_type id)
667 {
668 	CONCATENATE(trace_event_, MONITOR_NAME)(id, curr_state, event,
669 						next_state, is_final);
670 }
671 
672 static inline void da_trace_error(struct da_monitor *da_mon,
673 				  char *curr_state, char *event,
674 				  da_id_type id)
675 {
676 	CONCATENATE(trace_error_, MONITOR_NAME)(id, curr_state, event);
677 }
678 #endif /* RV_MON_TYPE */
679 
680 /*
681  * da_event - handle an event for the da_mon
682  *
683  * This function is valid for both implicit and id monitors.
684  * Retry in case there is a race between getting and setting the next state,
685  * warn and reset the monitor if it runs out of retries. The monitor should be
686  * able to handle various orders.
687  */
688 static inline bool da_event(struct da_monitor *da_mon, enum events event, da_id_type id)
689 {
690 	enum states curr_state, next_state;
691 
692 	curr_state = READ_ONCE(da_mon->curr_state);
693 	for (int i = 0; i < MAX_DA_RETRY_RACING_EVENTS; i++) {
694 		next_state = model_get_next_state(curr_state, event);
695 		if (next_state == INVALID_STATE) {
696 			react(curr_state, event);
697 			da_trace_error(da_mon, model_get_state_name(curr_state),
698 				       model_get_event_name(event), id);
699 			return false;
700 		}
701 		if (likely(try_cmpxchg(&da_mon->curr_state, &curr_state, next_state))) {
702 			if (!da_monitor_event_hook(da_mon, curr_state, event, next_state, id))
703 				return false;
704 			da_trace_event(da_mon, model_get_state_name(curr_state),
705 				       model_get_event_name(event),
706 				       model_get_state_name(next_state),
707 				       model_is_final_state(next_state), id);
708 			return true;
709 		}
710 	}
711 
712 	trace_rv_retries_error(__stringify(MONITOR_NAME), model_get_event_name(event));
713 	pr_warn("rv: " __stringify(MAX_DA_RETRY_RACING_EVENTS)
714 		" retries reached for event %s, resetting monitor %s",
715 		model_get_event_name(event), __stringify(MONITOR_NAME));
716 	return false;
717 }
718 
719 static inline void __da_handle_event_common(struct da_monitor *da_mon,
720 					    enum events event, da_id_type id)
721 {
722 	if (!da_event(da_mon, event, id))
723 		da_monitor_reset(da_mon);
724 }
725 
726 static inline void __da_handle_event(struct da_monitor *da_mon,
727 				     enum events event, da_id_type id)
728 {
729 	if (da_monitor_handling_event(da_mon))
730 		__da_handle_event_common(da_mon, event, id);
731 }
732 
733 static inline bool __da_handle_start_event(struct da_monitor *da_mon,
734 					   enum events event, da_id_type id)
735 {
736 	if (!da_monitor_enabled())
737 		return 0;
738 	if (unlikely(!da_monitoring(da_mon))) {
739 		da_monitor_start(da_mon);
740 		return 0;
741 	}
742 
743 	__da_handle_event_common(da_mon, event, id);
744 
745 	return 1;
746 }
747 
748 static inline bool __da_handle_start_run_event(struct da_monitor *da_mon,
749 					       enum events event, da_id_type id)
750 {
751 	if (!da_monitor_enabled())
752 		return 0;
753 	if (unlikely(!da_monitoring(da_mon)))
754 		da_monitor_start(da_mon);
755 
756 	__da_handle_event_common(da_mon, event, id);
757 
758 	return 1;
759 }
760 
761 #if RV_MON_TYPE == RV_MON_GLOBAL || RV_MON_TYPE == RV_MON_PER_CPU
762 /*
763  * Handle event for implicit monitor: da_get_monitor() will figure out
764  * the monitor.
765  */
766 
767 /*
768  * da_handle_event - handle an event
769  */
770 static inline void da_handle_event(enum events event)
771 {
772 	da_implicit_guard();
773 	__da_handle_event(da_get_monitor(), event, 0);
774 }
775 
776 /*
777  * da_handle_start_event - start monitoring or handle event
778  *
779  * This function is used to notify the monitor that the system is returning
780  * to the initial state, so the monitor can start monitoring in the next event.
781  * Thus:
782  *
783  * If the monitor already started, handle the event.
784  * If the monitor did not start yet, start the monitor but skip the event.
785  */
786 static inline bool da_handle_start_event(enum events event)
787 {
788 	da_implicit_guard();
789 	return __da_handle_start_event(da_get_monitor(), event, 0);
790 }
791 
792 /*
793  * da_handle_start_run_event - start monitoring and handle event
794  *
795  * This function is used to notify the monitor that the system is in the
796  * initial state, so the monitor can start monitoring and handling event.
797  */
798 static inline bool da_handle_start_run_event(enum events event)
799 {
800 	da_implicit_guard();
801 	return __da_handle_start_run_event(da_get_monitor(), event, 0);
802 }
803 
804 #elif RV_MON_TYPE == RV_MON_PER_TASK
805 /*
806  * Handle event for per task.
807  */
808 
809 /*
810  * da_handle_event - handle an event
811  */
812 static inline void da_handle_event(struct task_struct *tsk, enum events event)
813 {
814 	__da_handle_event(da_get_monitor(tsk), event, tsk->pid);
815 }
816 
817 /*
818  * da_handle_start_event - start monitoring or handle event
819  *
820  * This function is used to notify the monitor that the system is returning
821  * to the initial state, so the monitor can start monitoring in the next event.
822  * Thus:
823  *
824  * If the monitor already started, handle the event.
825  * If the monitor did not start yet, start the monitor but skip the event.
826  */
827 static inline bool da_handle_start_event(struct task_struct *tsk,
828 					 enum events event)
829 {
830 	return __da_handle_start_event(da_get_monitor(tsk), event, tsk->pid);
831 }
832 
833 /*
834  * da_handle_start_run_event - start monitoring and handle event
835  *
836  * This function is used to notify the monitor that the system is in the
837  * initial state, so the monitor can start monitoring and handling event.
838  */
839 static inline bool da_handle_start_run_event(struct task_struct *tsk,
840 					     enum events event)
841 {
842 	return __da_handle_start_run_event(da_get_monitor(tsk), event, tsk->pid);
843 }
844 
845 #elif RV_MON_TYPE == RV_MON_PER_OBJ
846 /*
847  * Handle event for per object.
848  */
849 
850 /*
851  * da_handle_event - handle an event
852  */
853 static inline void da_handle_event(da_id_type id, monitor_target target, enum events event)
854 {
855 	struct da_monitor *da_mon;
856 
857 	guard(rcu)();
858 	da_mon = da_get_monitor(id, target);
859 	if (likely(da_mon))
860 		__da_handle_event(da_mon, event, id);
861 }
862 
863 /*
864  * da_handle_start_event - start monitoring or handle event
865  *
866  * This function is used to notify the monitor that the system is returning
867  * to the initial state, so the monitor can start monitoring in the next event.
868  * Thus:
869  *
870  * If the monitor already started, handle the event.
871  * If the monitor did not start yet, start the monitor but skip the event.
872  */
873 static inline bool da_handle_start_event(da_id_type id, monitor_target target,
874 					 enum events event)
875 {
876 	struct da_monitor *da_mon;
877 
878 	guard(rcu)();
879 	da_mon = da_get_monitor(id, target);
880 	da_mon = da_prepare_storage(id, target, da_mon);
881 	if (unlikely(!da_mon))
882 		return 0;
883 	return __da_handle_start_event(da_mon, event, id);
884 }
885 
886 /*
887  * da_handle_start_run_event - start monitoring and handle event
888  *
889  * This function is used to notify the monitor that the system is in the
890  * initial state, so the monitor can start monitoring and handling event.
891  */
892 static inline bool da_handle_start_run_event(da_id_type id, monitor_target target,
893 					     enum events event)
894 {
895 	struct da_monitor *da_mon;
896 
897 	guard(rcu)();
898 	da_mon = da_get_monitor(id, target);
899 	da_mon = da_prepare_storage(id, target, da_mon);
900 	if (unlikely(!da_mon))
901 		return 0;
902 	return __da_handle_start_run_event(da_mon, event, id);
903 }
904 
905 static inline void da_reset(da_id_type id, monitor_target target)
906 {
907 	struct da_monitor *da_mon;
908 
909 	guard(rcu)();
910 	da_mon = da_get_monitor(id, target);
911 	if (likely(da_mon))
912 		da_monitor_reset(da_mon);
913 }
914 #endif /* RV_MON_TYPE */
915 
916 #if IS_ENABLED(CONFIG_RV_MONITORS_KUNIT_TEST)
917 #if RV_MON_TYPE == RV_MON_PER_TASK
918 #define RV_MON_OPS_INIT() {             \
919 	.rv_this = &rv_this,            \
920 	.is_per_task = true,            \
921 	.task_slot = &task_mon_slot,    \
922 	.task_reset = da_reset,         \
923 }
924 #else
925 #define RV_MON_OPS_INIT() {                     \
926 	.rv_this = &rv_this,                    \
927 	.monitor_init = da_monitor_init,        \
928 	.monitor_destroy = da_monitor_destroy,  \
929 }
930 #endif /* RV_MON_TYPE */
931 #endif /* CONFIG_RV_MONITORS_KUNIT_TEST */
932 
933 #endif
934