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