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