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