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. 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
react(enum states curr_state,enum events event)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 */
da_monitor_reset_state(struct da_monitor * da_mon)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 */
da_monitor_reset(struct da_monitor * da_mon)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 */
da_monitor_start(struct da_monitor * da_mon)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 */
da_monitoring(struct da_monitor * da_mon)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 */
da_monitor_enabled(void)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 */
da_monitor_handling_event(struct da_monitor * da_mon)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 */
da_get_monitor(void)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 */
__da_monitor_reset_all(void (* reset)(struct da_monitor *))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 */
da_monitor_reset_all(void)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 */
da_monitor_reset_state_all(void)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 */
da_monitor_init(void)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 */
da_monitor_destroy(void)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 */
da_get_monitor(void)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 */
__da_monitor_reset_all(void (* reset)(struct da_monitor *))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 */
da_monitor_reset_all(void)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 */
da_monitor_reset_state_all(void)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 */
da_monitor_init(void)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 */
da_monitor_destroy(void)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 */
da_get_monitor(struct task_struct * tsk)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
da_reset(struct task_struct * tsk)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 */
da_get_target(struct da_monitor * da_mon)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 */
da_get_id(struct da_monitor * da_mon)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
__da_monitor_reset_all(void (* reset)(struct da_monitor *))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
da_monitor_reset_all(void)351 static void da_monitor_reset_all(void)
352 {
353 __da_monitor_reset_all(da_monitor_reset);
354 }
355
da_monitor_reset_state_all(void)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 */
da_monitor_init(void)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 */
da_monitor_destroy(void)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 */
da_create_empty_storage(da_id_type id)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 */
da_create_storage(da_id_type id,monitor_target target,struct da_monitor * da_mon)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 */
__da_get_mon_storage(da_id_type id)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 */
da_get_monitor(da_id_type id,monitor_target target)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 */
da_get_target(struct da_monitor * da_mon)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 */
da_get_id(struct da_monitor * da_mon)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 */
da_create_or_get(da_id_type id,monitor_target target)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 */
da_fill_empty_storage(da_id_type id,monitor_target target,struct da_monitor * da_mon)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 */
da_get_target_by_id(da_id_type id)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 */
da_destroy_storage(da_id_type id)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
__da_monitor_reset_all(void (* reset)(struct da_monitor *))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
da_monitor_reset_all(void)580 static void da_monitor_reset_all(void)
581 {
582 __da_monitor_reset_all(da_monitor_reset);
583 }
584
da_monitor_reset_state_all(void)585 static inline void da_monitor_reset_state_all(void)
586 {
587 __da_monitor_reset_all(da_monitor_reset_state);
588 }
589
da_monitor_init(void)590 static inline int da_monitor_init(void)
591 {
592 hash_init(da_monitor_ht);
593 return 0;
594 }
595
da_monitor_destroy(void)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
da_trace_event(struct da_monitor * da_mon,char * curr_state,char * event,char * next_state,bool is_final,da_id_type id)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
da_trace_error(struct da_monitor * da_mon,char * curr_state,char * event,da_id_type id)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 */
da_get_id(struct da_monitor * da_mon)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
da_trace_event(struct da_monitor * da_mon,char * curr_state,char * event,char * next_state,bool is_final,da_id_type id)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
da_trace_error(struct da_monitor * da_mon,char * curr_state,char * event,da_id_type id)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 */
da_event(struct da_monitor * da_mon,enum events event,da_id_type id)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
__da_handle_event_common(struct da_monitor * da_mon,enum events event,da_id_type id)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
__da_handle_event(struct da_monitor * da_mon,enum events event,da_id_type id)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
__da_handle_start_event(struct da_monitor * da_mon,enum events event,da_id_type id)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
__da_handle_start_run_event(struct da_monitor * da_mon,enum events event,da_id_type id)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 */
da_handle_event(enum events event)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 */
da_handle_start_event(enum events event)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 */
da_handle_start_run_event(enum events event)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 */
da_handle_event(struct task_struct * tsk,enum events event)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 */
da_handle_start_event(struct task_struct * tsk,enum events event)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 */
da_handle_start_run_event(struct task_struct * tsk,enum events event)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 */
da_handle_event(da_id_type id,monitor_target target,enum events event)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 */
da_handle_start_event(da_id_type id,monitor_target target,enum events event)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 */
da_handle_start_run_event(da_id_type id,monitor_target target,enum events event)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
da_reset(da_id_type id,monitor_target target)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