xref: /linux/include/rv/da_monitor.h (revision 85339442de941e4d7ff5d53f51ae1413905e45ec)
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 /*
315  * da_get_target - return the task associated to the monitor
316  */
317 static inline struct task_struct *da_get_target(struct da_monitor *da_mon)
318 {
319 	return container_of(da_mon, struct task_struct, rv[task_mon_slot].da_mon);
320 }
321 
322 /*
323  * da_get_id - return the id associated to the monitor
324  *
325  * For per-task monitors, the id is the task's PID.
326  */
327 static inline da_id_type da_get_id(struct da_monitor *da_mon)
328 {
329 	return da_get_target(da_mon)->pid;
330 }
331 
332 static void __da_monitor_reset_all(void (*reset)(struct da_monitor *))
333 {
334 	struct task_struct *g, *p;
335 	int cpu;
336 
337 	read_lock(&tasklist_lock);
338 	for_each_process_thread(g, p)
339 		reset(da_get_monitor(p));
340 	for_each_present_cpu(cpu)
341 		reset(da_get_monitor(idle_task(cpu)));
342 	read_unlock(&tasklist_lock);
343 }
344 
345 static void da_monitor_reset_all(void)
346 {
347 	__da_monitor_reset_all(da_monitor_reset);
348 }
349 
350 static inline void da_monitor_reset_state_all(void)
351 {
352 	__da_monitor_reset_all(da_monitor_reset_state);
353 }
354 
355 /*
356  * da_monitor_init - initialize the per-task monitor
357  *
358  * Try to allocate a slot in the task's vector of monitors. If there
359  * is an available slot, use it and reset all task's monitor.
360  */
361 static int da_monitor_init(void)
362 {
363 	int slot;
364 
365 	slot = rv_get_task_monitor_slot();
366 	if (slot < 0 || slot >= RV_PER_TASK_MONITOR_INIT)
367 		return slot;
368 
369 	task_mon_slot = slot;
370 
371 	da_monitor_reset_state_all();
372 	return 0;
373 }
374 
375 /*
376  * da_monitor_destroy - return the allocated slot
377  *
378  * Wait for all in-flight handlers before returning the slot to avoid
379  * out-of-bound accesses.
380  */
381 static inline void da_monitor_destroy(void)
382 {
383 	if (task_mon_slot == RV_PER_TASK_MONITOR_INIT) {
384 		WARN_ONCE(1, "Disabling a disabled monitor: " __stringify(MONITOR_NAME));
385 		return;
386 	}
387 
388 	tracepoint_synchronize_unregister();
389 	da_monitor_reset_all();
390 	da_monitor_sync_hook();
391 
392 	rv_put_task_monitor_slot(task_mon_slot);
393 	task_mon_slot = RV_PER_TASK_MONITOR_INIT;
394 }
395 
396 #elif RV_MON_TYPE == RV_MON_PER_OBJ
397 /*
398  * Functions to define, init and get a per-object monitor.
399  */
400 
401 struct da_monitor_storage {
402 	da_id_type id;
403 	monitor_target target;
404 	union rv_task_monitor rv;
405 	struct hlist_node node;
406 	struct rcu_head rcu;
407 };
408 
409 #ifndef DA_MONITOR_HT_BITS
410 #define DA_MONITOR_HT_BITS 10
411 #endif
412 static DEFINE_HASHTABLE(da_monitor_ht, DA_MONITOR_HT_BITS);
413 
414 /*
415  * da_create_empty_storage - pre-allocate an empty storage
416  */
417 static inline struct da_monitor_storage *da_create_empty_storage(da_id_type id)
418 {
419 	struct da_monitor_storage *mon_storage;
420 
421 	mon_storage = kmalloc_nolock(sizeof(struct da_monitor_storage),
422 				     __GFP_ZERO, NUMA_NO_NODE);
423 	if (!mon_storage)
424 		return NULL;
425 
426 	hash_add_rcu(da_monitor_ht, &mon_storage->node, id);
427 	mon_storage->id = id;
428 	return mon_storage;
429 }
430 
431 /*
432  * da_create_storage - create the per-object storage
433  *
434  * The caller is responsible to synchronise writers, either with locks or
435  * implicitly. For instance, if da_create_storage is only called from a single
436  * event for target (e.g. sched_switch), it's safe to call this without locks.
437  */
438 static inline struct da_monitor *da_create_storage(da_id_type id,
439 						   monitor_target target,
440 						   struct da_monitor *da_mon)
441 {
442 	struct da_monitor_storage *mon_storage;
443 
444 	if (da_mon)
445 		return da_mon;
446 
447 	mon_storage = da_create_empty_storage(id);
448 	if (!mon_storage)
449 		return NULL;
450 
451 	mon_storage->target = target;
452 	return &mon_storage->rv.da_mon;
453 }
454 
455 /*
456  * __da_get_mon_storage - get the monitor storage from the hash table
457  */
458 static inline struct da_monitor_storage *__da_get_mon_storage(da_id_type id)
459 {
460 	struct da_monitor_storage *mon_storage;
461 
462 	lockdep_assert_in_rcu_read_lock();
463 	hash_for_each_possible_rcu(da_monitor_ht, mon_storage, node, id) {
464 		if (mon_storage->id == id)
465 			return mon_storage;
466 	}
467 
468 	return NULL;
469 }
470 
471 /*
472  * da_get_monitor - return the monitor for target
473  */
474 static struct da_monitor *da_get_monitor(da_id_type id, monitor_target target)
475 {
476 	struct da_monitor_storage *mon_storage;
477 
478 	mon_storage = __da_get_mon_storage(id);
479 	return mon_storage ? &mon_storage->rv.da_mon : NULL;
480 }
481 
482 /*
483  * da_get_target - return the object associated to the monitor
484  */
485 static inline monitor_target da_get_target(struct da_monitor *da_mon)
486 {
487 	return container_of(da_mon, struct da_monitor_storage, rv.da_mon)->target;
488 }
489 
490 /*
491  * da_get_id - return the id associated to the monitor
492  */
493 static inline da_id_type da_get_id(struct da_monitor *da_mon)
494 {
495 	return container_of(da_mon, struct da_monitor_storage, rv.da_mon)->id;
496 }
497 
498 /*
499  * da_create_or_get - create the per-object storage if not already there
500  *
501  * This needs a lookup so should be guarded by RCU, the condition is checked
502  * directly in da_create_storage()
503  */
504 static inline void da_create_or_get(da_id_type id, monitor_target target)
505 {
506 	guard(rcu)();
507 	da_create_storage(id, target, da_get_monitor(id, target));
508 }
509 
510 /*
511  * da_fill_empty_storage - store the target in a pre-allocated storage
512  *
513  * Can be used as a substitute of da_create_storage when starting a monitor in
514  * an environment where allocation is unsafe.
515  */
516 static inline struct da_monitor *da_fill_empty_storage(da_id_type id,
517 						       monitor_target target,
518 						       struct da_monitor *da_mon)
519 {
520 	if (unlikely(da_mon && !da_get_target(da_mon)))
521 		container_of(da_mon, struct da_monitor_storage, rv.da_mon)->target = target;
522 	return da_mon;
523 }
524 
525 /*
526  * da_get_target_by_id - return the object associated to the id
527  */
528 static inline monitor_target da_get_target_by_id(da_id_type id)
529 {
530 	struct da_monitor_storage *mon_storage;
531 
532 	guard(rcu)();
533 	mon_storage = __da_get_mon_storage(id);
534 
535 	if (unlikely(!mon_storage))
536 		return NULL;
537 	return mon_storage->target;
538 }
539 
540 /*
541  * da_destroy_storage - destroy the per-object storage
542  *
543  * The caller is responsible to synchronise writers, either with locks or
544  * implicitly. For instance, if da_destroy_storage is called at sched_exit and
545  * da_create_storage can never occur after that, it's safe to call this without
546  * locks.
547  * This function includes an RCU read-side critical section to synchronise
548  * against da_monitor_destroy().
549  */
550 static inline void da_destroy_storage(da_id_type id)
551 {
552 	struct da_monitor_storage *mon_storage;
553 
554 	guard(rcu)();
555 	mon_storage = __da_get_mon_storage(id);
556 
557 	if (!mon_storage)
558 		return;
559 	da_monitor_reset_hook(&mon_storage->rv.da_mon);
560 	hash_del_rcu(&mon_storage->node);
561 	kfree_rcu(mon_storage, rcu);
562 }
563 
564 static void __da_monitor_reset_all(void (*reset)(struct da_monitor *))
565 {
566 	struct da_monitor_storage *mon_storage;
567 	int bkt;
568 
569 	guard(rcu)();
570 	hash_for_each_rcu(da_monitor_ht, bkt, mon_storage, node)
571 		reset(&mon_storage->rv.da_mon);
572 }
573 
574 static void da_monitor_reset_all(void)
575 {
576 	__da_monitor_reset_all(da_monitor_reset);
577 }
578 
579 static inline void da_monitor_reset_state_all(void)
580 {
581 	__da_monitor_reset_all(da_monitor_reset_state);
582 }
583 
584 static inline int da_monitor_init(void)
585 {
586 	hash_init(da_monitor_ht);
587 	return 0;
588 }
589 
590 static inline void da_monitor_destroy(void)
591 {
592 	struct da_monitor_storage *mon_storage;
593 	struct hlist_node *tmp;
594 	int bkt;
595 
596 	tracepoint_synchronize_unregister();
597 	da_monitor_reset_all();
598 	da_monitor_sync_hook();
599 	/*
600 	 * This function is called after all probes are disabled and no longer
601 	 * pending, we can safely assume no concurrent user.
602 	 */
603 	hash_for_each_safe(da_monitor_ht, bkt, tmp, mon_storage, node) {
604 		hash_del_rcu(&mon_storage->node);
605 		kfree(mon_storage);
606 	}
607 }
608 
609 /*
610  * Allow the per-object monitors to run allocation manually, necessary if the
611  * start condition is in a context problematic for allocation (e.g. scheduling).
612  * In such case, if the storage was pre-allocated without a target, set it now.
613  */
614 #ifdef DA_SKIP_AUTO_ALLOC
615 #define da_prepare_storage da_fill_empty_storage
616 #else
617 #define da_prepare_storage da_create_storage
618 #endif /* DA_SKIP_AUTO_ALLOC */
619 
620 #endif /* RV_MON_TYPE */
621 
622 #if RV_MON_TYPE == RV_MON_GLOBAL || RV_MON_TYPE == RV_MON_PER_CPU
623 /*
624  * Trace events for implicit monitors. Implicit monitor is the one which the
625  * handler does not need to specify which da_monitor to manipulate. Examples
626  * of implicit monitor are the per_cpu or the global ones.
627  */
628 
629 static inline void da_trace_event(struct da_monitor *da_mon,
630 				  char *curr_state, char *event,
631 				  char *next_state, bool is_final,
632 				  da_id_type id)
633 {
634 	CONCATENATE(trace_event_, MONITOR_NAME)(curr_state, event, next_state,
635 						is_final);
636 }
637 
638 static inline void da_trace_error(struct da_monitor *da_mon,
639 				  char *curr_state, char *event,
640 				  da_id_type id)
641 {
642 	CONCATENATE(trace_error_, MONITOR_NAME)(curr_state, event);
643 }
644 
645 /*
646  * da_get_id - unused for implicit monitors
647  */
648 static inline da_id_type da_get_id(struct da_monitor *da_mon)
649 {
650 	return 0;
651 }
652 
653 #elif RV_MON_TYPE == RV_MON_PER_TASK || RV_MON_TYPE == RV_MON_PER_OBJ
654 /*
655  * Trace events for per_task/per_object monitors, report the target id.
656  */
657 
658 static inline void da_trace_event(struct da_monitor *da_mon,
659 				  char *curr_state, char *event,
660 				  char *next_state, bool is_final,
661 				  da_id_type id)
662 {
663 	CONCATENATE(trace_event_, MONITOR_NAME)(id, curr_state, event,
664 						next_state, is_final);
665 }
666 
667 static inline void da_trace_error(struct da_monitor *da_mon,
668 				  char *curr_state, char *event,
669 				  da_id_type id)
670 {
671 	CONCATENATE(trace_error_, MONITOR_NAME)(id, curr_state, event);
672 }
673 #endif /* RV_MON_TYPE */
674 
675 /*
676  * da_event - handle an event for the da_mon
677  *
678  * This function is valid for both implicit and id monitors.
679  * Retry in case there is a race between getting and setting the next state,
680  * warn and reset the monitor if it runs out of retries. The monitor should be
681  * able to handle various orders.
682  */
683 static inline bool da_event(struct da_monitor *da_mon, enum events event, da_id_type id)
684 {
685 	enum states curr_state, next_state;
686 
687 	curr_state = READ_ONCE(da_mon->curr_state);
688 	for (int i = 0; i < MAX_DA_RETRY_RACING_EVENTS; i++) {
689 		next_state = model_get_next_state(curr_state, event);
690 		if (next_state == INVALID_STATE) {
691 			react(curr_state, event);
692 			da_trace_error(da_mon, model_get_state_name(curr_state),
693 				       model_get_event_name(event), id);
694 			return false;
695 		}
696 		if (likely(try_cmpxchg(&da_mon->curr_state, &curr_state, next_state))) {
697 			if (!da_monitor_event_hook(da_mon, curr_state, event, next_state, id))
698 				return false;
699 			da_trace_event(da_mon, model_get_state_name(curr_state),
700 				       model_get_event_name(event),
701 				       model_get_state_name(next_state),
702 				       model_is_final_state(next_state), id);
703 			return true;
704 		}
705 	}
706 
707 	trace_rv_retries_error(__stringify(MONITOR_NAME), model_get_event_name(event));
708 	pr_warn("rv: " __stringify(MAX_DA_RETRY_RACING_EVENTS)
709 		" retries reached for event %s, resetting monitor %s",
710 		model_get_event_name(event), __stringify(MONITOR_NAME));
711 	return false;
712 }
713 
714 static inline void __da_handle_event_common(struct da_monitor *da_mon,
715 					    enum events event, da_id_type id)
716 {
717 	if (!da_event(da_mon, event, id))
718 		da_monitor_reset(da_mon);
719 }
720 
721 static inline void __da_handle_event(struct da_monitor *da_mon,
722 				     enum events event, da_id_type id)
723 {
724 	if (da_monitor_handling_event(da_mon))
725 		__da_handle_event_common(da_mon, event, id);
726 }
727 
728 static inline bool __da_handle_start_event(struct da_monitor *da_mon,
729 					   enum events event, da_id_type id)
730 {
731 	if (!da_monitor_enabled())
732 		return 0;
733 	if (unlikely(!da_monitoring(da_mon))) {
734 		da_monitor_start(da_mon);
735 		return 0;
736 	}
737 
738 	__da_handle_event_common(da_mon, event, id);
739 
740 	return 1;
741 }
742 
743 static inline bool __da_handle_start_run_event(struct da_monitor *da_mon,
744 					       enum events event, da_id_type id)
745 {
746 	if (!da_monitor_enabled())
747 		return 0;
748 	if (unlikely(!da_monitoring(da_mon)))
749 		da_monitor_start(da_mon);
750 
751 	__da_handle_event_common(da_mon, event, id);
752 
753 	return 1;
754 }
755 
756 #if RV_MON_TYPE == RV_MON_GLOBAL || RV_MON_TYPE == RV_MON_PER_CPU
757 /*
758  * Handle event for implicit monitor: da_get_monitor() will figure out
759  * the monitor.
760  */
761 
762 /*
763  * da_handle_event - handle an event
764  */
765 static inline void da_handle_event(enum events event)
766 {
767 	da_implicit_guard();
768 	__da_handle_event(da_get_monitor(), event, 0);
769 }
770 
771 /*
772  * da_handle_start_event - start monitoring or handle event
773  *
774  * This function is used to notify the monitor that the system is returning
775  * to the initial state, so the monitor can start monitoring in the next event.
776  * Thus:
777  *
778  * If the monitor already started, handle the event.
779  * If the monitor did not start yet, start the monitor but skip the event.
780  */
781 static inline bool da_handle_start_event(enum events event)
782 {
783 	da_implicit_guard();
784 	return __da_handle_start_event(da_get_monitor(), event, 0);
785 }
786 
787 /*
788  * da_handle_start_run_event - start monitoring and handle event
789  *
790  * This function is used to notify the monitor that the system is in the
791  * initial state, so the monitor can start monitoring and handling event.
792  */
793 static inline bool da_handle_start_run_event(enum events event)
794 {
795 	da_implicit_guard();
796 	return __da_handle_start_run_event(da_get_monitor(), event, 0);
797 }
798 
799 #elif RV_MON_TYPE == RV_MON_PER_TASK
800 /*
801  * Handle event for per task.
802  */
803 
804 /*
805  * da_handle_event - handle an event
806  */
807 static inline void da_handle_event(struct task_struct *tsk, enum events event)
808 {
809 	__da_handle_event(da_get_monitor(tsk), event, tsk->pid);
810 }
811 
812 /*
813  * da_handle_start_event - start monitoring or handle event
814  *
815  * This function is used to notify the monitor that the system is returning
816  * to the initial state, so the monitor can start monitoring in the next event.
817  * Thus:
818  *
819  * If the monitor already started, handle the event.
820  * If the monitor did not start yet, start the monitor but skip the event.
821  */
822 static inline bool da_handle_start_event(struct task_struct *tsk,
823 					 enum events event)
824 {
825 	return __da_handle_start_event(da_get_monitor(tsk), event, tsk->pid);
826 }
827 
828 /*
829  * da_handle_start_run_event - start monitoring and handle event
830  *
831  * This function is used to notify the monitor that the system is in the
832  * initial state, so the monitor can start monitoring and handling event.
833  */
834 static inline bool da_handle_start_run_event(struct task_struct *tsk,
835 					     enum events event)
836 {
837 	return __da_handle_start_run_event(da_get_monitor(tsk), event, tsk->pid);
838 }
839 
840 #elif RV_MON_TYPE == RV_MON_PER_OBJ
841 /*
842  * Handle event for per object.
843  */
844 
845 /*
846  * da_handle_event - handle an event
847  */
848 static inline void da_handle_event(da_id_type id, monitor_target target, enum events event)
849 {
850 	struct da_monitor *da_mon;
851 
852 	guard(rcu)();
853 	da_mon = da_get_monitor(id, target);
854 	if (likely(da_mon))
855 		__da_handle_event(da_mon, event, id);
856 }
857 
858 /*
859  * da_handle_start_event - start monitoring or handle event
860  *
861  * This function is used to notify the monitor that the system is returning
862  * to the initial state, so the monitor can start monitoring in the next event.
863  * Thus:
864  *
865  * If the monitor already started, handle the event.
866  * If the monitor did not start yet, start the monitor but skip the event.
867  */
868 static inline bool da_handle_start_event(da_id_type id, monitor_target target,
869 					 enum events event)
870 {
871 	struct da_monitor *da_mon;
872 
873 	guard(rcu)();
874 	da_mon = da_get_monitor(id, target);
875 	da_mon = da_prepare_storage(id, target, da_mon);
876 	if (unlikely(!da_mon))
877 		return 0;
878 	return __da_handle_start_event(da_mon, event, id);
879 }
880 
881 /*
882  * da_handle_start_run_event - start monitoring and handle event
883  *
884  * This function is used to notify the monitor that the system is in the
885  * initial state, so the monitor can start monitoring and handling event.
886  */
887 static inline bool da_handle_start_run_event(da_id_type id, monitor_target target,
888 					     enum events event)
889 {
890 	struct da_monitor *da_mon;
891 
892 	guard(rcu)();
893 	da_mon = da_get_monitor(id, target);
894 	da_mon = da_prepare_storage(id, target, da_mon);
895 	if (unlikely(!da_mon))
896 		return 0;
897 	return __da_handle_start_run_event(da_mon, event, id);
898 }
899 
900 static inline void da_reset(da_id_type id, monitor_target target)
901 {
902 	struct da_monitor *da_mon;
903 
904 	guard(rcu)();
905 	da_mon = da_get_monitor(id, target);
906 	if (likely(da_mon))
907 		da_monitor_reset(da_mon);
908 }
909 #endif /* RV_MON_TYPE */
910 
911 #endif
912