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 23 /* 24 * Per-cpu variables require a unique name although static in some 25 * configurations (e.g. CONFIG_DEBUG_FORCE_WEAK_PER_CPU or alpha modules). 26 */ 27 #define DA_MON_NAME CONCATENATE(da_mon_, MONITOR_NAME) 28 29 static struct rv_monitor rv_this; 30 31 /* 32 * Hook to allow the implementation of hybrid automata: define it with a 33 * function that takes curr_state, event and next_state and returns true if the 34 * environment constraints (e.g. timing) are satisfied, false otherwise. 35 */ 36 #ifndef da_monitor_event_hook 37 #define da_monitor_event_hook(...) true 38 #endif 39 40 /* 41 * Hook to allow the implementation of hybrid automata: define it with a 42 * function that takes the da_monitor and performs further initialisation 43 * (e.g. reset set up timers). 44 */ 45 #ifndef da_monitor_init_hook 46 #define da_monitor_init_hook(da_mon) 47 #endif 48 49 /* 50 * Hook to allow the implementation of hybrid automata: define it with a 51 * function that takes the da_monitor and performs further reset (e.g. reset 52 * all clocks). 53 */ 54 #ifndef da_monitor_reset_hook 55 #define da_monitor_reset_hook(da_mon) 56 #endif 57 58 /* 59 * Type for the target id, default to int but can be overridden. 60 */ 61 #ifndef da_id_type 62 #define da_id_type int 63 #endif 64 65 static void react(enum states curr_state, enum events event) 66 { 67 rv_react(&rv_this, 68 "rv: monitor %s does not allow event %s on state %s\n", 69 __stringify(MONITOR_NAME), 70 model_get_event_name(event), 71 model_get_state_name(curr_state)); 72 } 73 74 /* 75 * da_monitor_reset - reset a monitor and setting it to init state 76 */ 77 static inline void da_monitor_reset(struct da_monitor *da_mon) 78 { 79 da_monitor_reset_hook(da_mon); 80 da_mon->monitoring = 0; 81 da_mon->curr_state = model_get_initial_state(); 82 } 83 84 /* 85 * da_monitor_start - start monitoring 86 * 87 * The monitor will ignore all events until monitoring is set to true. This 88 * function needs to be called to tell the monitor to start monitoring. 89 */ 90 static inline void da_monitor_start(struct da_monitor *da_mon) 91 { 92 da_mon->curr_state = model_get_initial_state(); 93 da_mon->monitoring = 1; 94 da_monitor_init_hook(da_mon); 95 } 96 97 /* 98 * da_monitoring - returns true if the monitor is processing events 99 */ 100 static inline bool da_monitoring(struct da_monitor *da_mon) 101 { 102 return da_mon->monitoring; 103 } 104 105 /* 106 * da_monitor_enabled - checks if the monitor is enabled 107 */ 108 static inline bool da_monitor_enabled(void) 109 { 110 /* global switch */ 111 if (unlikely(!rv_monitoring_on())) 112 return 0; 113 114 /* monitor enabled */ 115 if (unlikely(!rv_this.enabled)) 116 return 0; 117 118 return 1; 119 } 120 121 /* 122 * da_monitor_handling_event - checks if the monitor is ready to handle events 123 */ 124 static inline bool da_monitor_handling_event(struct da_monitor *da_mon) 125 { 126 if (!da_monitor_enabled()) 127 return 0; 128 129 /* monitor is actually monitoring */ 130 if (unlikely(!da_monitoring(da_mon))) 131 return 0; 132 133 return 1; 134 } 135 136 #if RV_MON_TYPE == RV_MON_GLOBAL 137 /* 138 * Functions to define, init and get a global monitor. 139 */ 140 141 /* 142 * global monitor (a single variable) 143 */ 144 static struct da_monitor DA_MON_NAME; 145 146 /* 147 * da_get_monitor - return the global monitor address 148 */ 149 static struct da_monitor *da_get_monitor(void) 150 { 151 return &DA_MON_NAME; 152 } 153 154 /* 155 * da_monitor_reset_all - reset the single monitor 156 */ 157 static void da_monitor_reset_all(void) 158 { 159 da_monitor_reset(da_get_monitor()); 160 } 161 162 /* 163 * da_monitor_init - initialize a monitor 164 */ 165 static inline int da_monitor_init(void) 166 { 167 da_monitor_reset_all(); 168 return 0; 169 } 170 171 /* 172 * da_monitor_destroy - destroy the monitor 173 */ 174 static inline void da_monitor_destroy(void) 175 { 176 da_monitor_reset_all(); 177 } 178 179 #elif RV_MON_TYPE == RV_MON_PER_CPU 180 /* 181 * Functions to define, init and get a per-cpu monitor. 182 */ 183 184 /* 185 * per-cpu monitor variables 186 */ 187 static DEFINE_PER_CPU(struct da_monitor, DA_MON_NAME); 188 189 /* 190 * da_get_monitor - return current CPU monitor address 191 */ 192 static struct da_monitor *da_get_monitor(void) 193 { 194 return this_cpu_ptr(&DA_MON_NAME); 195 } 196 197 /* 198 * da_monitor_reset_all - reset all CPUs' monitor 199 */ 200 static void da_monitor_reset_all(void) 201 { 202 struct da_monitor *da_mon; 203 int cpu; 204 205 for_each_cpu(cpu, cpu_online_mask) { 206 da_mon = per_cpu_ptr(&DA_MON_NAME, cpu); 207 da_monitor_reset(da_mon); 208 } 209 } 210 211 /* 212 * da_monitor_init - initialize all CPUs' monitor 213 */ 214 static inline int da_monitor_init(void) 215 { 216 da_monitor_reset_all(); 217 return 0; 218 } 219 220 /* 221 * da_monitor_destroy - destroy the monitor 222 */ 223 static inline void da_monitor_destroy(void) 224 { 225 da_monitor_reset_all(); 226 } 227 228 #elif RV_MON_TYPE == RV_MON_PER_TASK 229 /* 230 * Functions to define, init and get a per-task monitor. 231 */ 232 233 /* 234 * The per-task monitor is stored a vector in the task struct. This variable 235 * stores the position on the vector reserved for this monitor. 236 */ 237 static int task_mon_slot = RV_PER_TASK_MONITOR_INIT; 238 239 /* 240 * da_get_monitor - return the monitor in the allocated slot for tsk 241 */ 242 static inline struct da_monitor *da_get_monitor(struct task_struct *tsk) 243 { 244 return &tsk->rv[task_mon_slot].da_mon; 245 } 246 247 /* 248 * da_get_task - return the task associated to the monitor 249 */ 250 static inline struct task_struct *da_get_task(struct da_monitor *da_mon) 251 { 252 return container_of(da_mon, struct task_struct, rv[task_mon_slot].da_mon); 253 } 254 255 /* 256 * da_get_id - return the id associated to the monitor 257 * 258 * For per-task monitors, the id is the task's PID. 259 */ 260 static inline da_id_type da_get_id(struct da_monitor *da_mon) 261 { 262 return da_get_task(da_mon)->pid; 263 } 264 265 static void da_monitor_reset_all(void) 266 { 267 struct task_struct *g, *p; 268 int cpu; 269 270 read_lock(&tasklist_lock); 271 for_each_process_thread(g, p) 272 da_monitor_reset(da_get_monitor(p)); 273 for_each_present_cpu(cpu) 274 da_monitor_reset(da_get_monitor(idle_task(cpu))); 275 read_unlock(&tasklist_lock); 276 } 277 278 /* 279 * da_monitor_init - initialize the per-task monitor 280 * 281 * Try to allocate a slot in the task's vector of monitors. If there 282 * is an available slot, use it and reset all task's monitor. 283 */ 284 static int da_monitor_init(void) 285 { 286 int slot; 287 288 slot = rv_get_task_monitor_slot(); 289 if (slot < 0 || slot >= RV_PER_TASK_MONITOR_INIT) 290 return slot; 291 292 task_mon_slot = slot; 293 294 da_monitor_reset_all(); 295 return 0; 296 } 297 298 /* 299 * da_monitor_destroy - return the allocated slot 300 */ 301 static inline void da_monitor_destroy(void) 302 { 303 if (task_mon_slot == RV_PER_TASK_MONITOR_INIT) { 304 WARN_ONCE(1, "Disabling a disabled monitor: " __stringify(MONITOR_NAME)); 305 return; 306 } 307 rv_put_task_monitor_slot(task_mon_slot); 308 task_mon_slot = RV_PER_TASK_MONITOR_INIT; 309 310 da_monitor_reset_all(); 311 } 312 #endif /* RV_MON_TYPE */ 313 314 #if RV_MON_TYPE == RV_MON_GLOBAL || RV_MON_TYPE == RV_MON_PER_CPU 315 /* 316 * Trace events for implicit monitors. Implicit monitor is the one which the 317 * handler does not need to specify which da_monitor to manipulate. Examples 318 * of implicit monitor are the per_cpu or the global ones. 319 */ 320 321 static inline void da_trace_event(struct da_monitor *da_mon, 322 char *curr_state, char *event, 323 char *next_state, bool is_final, 324 da_id_type id) 325 { 326 CONCATENATE(trace_event_, MONITOR_NAME)(curr_state, event, next_state, 327 is_final); 328 } 329 330 static inline void da_trace_error(struct da_monitor *da_mon, 331 char *curr_state, char *event, 332 da_id_type id) 333 { 334 CONCATENATE(trace_error_, MONITOR_NAME)(curr_state, event); 335 } 336 337 /* 338 * da_get_id - unused for implicit monitors 339 */ 340 static inline da_id_type da_get_id(struct da_monitor *da_mon) 341 { 342 return 0; 343 } 344 345 #elif RV_MON_TYPE == RV_MON_PER_TASK 346 /* 347 * Trace events for per_task monitors, report the PID of the task. 348 */ 349 350 static inline void da_trace_event(struct da_monitor *da_mon, 351 char *curr_state, char *event, 352 char *next_state, bool is_final, 353 da_id_type id) 354 { 355 CONCATENATE(trace_event_, MONITOR_NAME)(id, curr_state, event, 356 next_state, is_final); 357 } 358 359 static inline void da_trace_error(struct da_monitor *da_mon, 360 char *curr_state, char *event, 361 da_id_type id) 362 { 363 CONCATENATE(trace_error_, MONITOR_NAME)(id, curr_state, event); 364 } 365 #endif /* RV_MON_TYPE */ 366 367 /* 368 * da_event - handle an event for the da_mon 369 * 370 * This function is valid for both implicit and id monitors. 371 * Retry in case there is a race between getting and setting the next state, 372 * warn and reset the monitor if it runs out of retries. The monitor should be 373 * able to handle various orders. 374 */ 375 static inline bool da_event(struct da_monitor *da_mon, enum events event, da_id_type id) 376 { 377 enum states curr_state, next_state; 378 379 curr_state = READ_ONCE(da_mon->curr_state); 380 for (int i = 0; i < MAX_DA_RETRY_RACING_EVENTS; i++) { 381 next_state = model_get_next_state(curr_state, event); 382 if (next_state == INVALID_STATE) { 383 react(curr_state, event); 384 da_trace_error(da_mon, model_get_state_name(curr_state), 385 model_get_event_name(event), id); 386 return false; 387 } 388 if (likely(try_cmpxchg(&da_mon->curr_state, &curr_state, next_state))) { 389 if (!da_monitor_event_hook(da_mon, curr_state, event, next_state, id)) 390 return false; 391 da_trace_event(da_mon, model_get_state_name(curr_state), 392 model_get_event_name(event), 393 model_get_state_name(next_state), 394 model_is_final_state(next_state), id); 395 return true; 396 } 397 } 398 399 trace_rv_retries_error(__stringify(MONITOR_NAME), model_get_event_name(event)); 400 pr_warn("rv: " __stringify(MAX_DA_RETRY_RACING_EVENTS) 401 " retries reached for event %s, resetting monitor %s", 402 model_get_event_name(event), __stringify(MONITOR_NAME)); 403 return false; 404 } 405 406 static inline void __da_handle_event_common(struct da_monitor *da_mon, 407 enum events event, da_id_type id) 408 { 409 if (!da_event(da_mon, event, id)) 410 da_monitor_reset(da_mon); 411 } 412 413 static inline void __da_handle_event(struct da_monitor *da_mon, 414 enum events event, da_id_type id) 415 { 416 if (da_monitor_handling_event(da_mon)) 417 __da_handle_event_common(da_mon, event, id); 418 } 419 420 static inline bool __da_handle_start_event(struct da_monitor *da_mon, 421 enum events event, da_id_type id) 422 { 423 if (!da_monitor_enabled()) 424 return 0; 425 if (unlikely(!da_monitoring(da_mon))) { 426 da_monitor_start(da_mon); 427 return 0; 428 } 429 430 __da_handle_event_common(da_mon, event, id); 431 432 return 1; 433 } 434 435 static inline bool __da_handle_start_run_event(struct da_monitor *da_mon, 436 enum events event, da_id_type id) 437 { 438 if (!da_monitor_enabled()) 439 return 0; 440 if (unlikely(!da_monitoring(da_mon))) 441 da_monitor_start(da_mon); 442 443 __da_handle_event_common(da_mon, event, id); 444 445 return 1; 446 } 447 448 #if RV_MON_TYPE == RV_MON_GLOBAL || RV_MON_TYPE == RV_MON_PER_CPU 449 /* 450 * Handle event for implicit monitor: da_get_monitor() will figure out 451 * the monitor. 452 */ 453 454 /* 455 * da_handle_event - handle an event 456 */ 457 static inline void da_handle_event(enum events event) 458 { 459 __da_handle_event(da_get_monitor(), event, 0); 460 } 461 462 /* 463 * da_handle_start_event - start monitoring or handle event 464 * 465 * This function is used to notify the monitor that the system is returning 466 * to the initial state, so the monitor can start monitoring in the next event. 467 * Thus: 468 * 469 * If the monitor already started, handle the event. 470 * If the monitor did not start yet, start the monitor but skip the event. 471 */ 472 static inline bool da_handle_start_event(enum events event) 473 { 474 return __da_handle_start_event(da_get_monitor(), event, 0); 475 } 476 477 /* 478 * da_handle_start_run_event - start monitoring and handle event 479 * 480 * This function is used to notify the monitor that the system is in the 481 * initial state, so the monitor can start monitoring and handling event. 482 */ 483 static inline bool da_handle_start_run_event(enum events event) 484 { 485 return __da_handle_start_run_event(da_get_monitor(), event, 0); 486 } 487 488 #elif RV_MON_TYPE == RV_MON_PER_TASK 489 /* 490 * Handle event for per task. 491 */ 492 493 /* 494 * da_handle_event - handle an event 495 */ 496 static inline void da_handle_event(struct task_struct *tsk, enum events event) 497 { 498 __da_handle_event(da_get_monitor(tsk), event, tsk->pid); 499 } 500 501 /* 502 * da_handle_start_event - start monitoring or handle event 503 * 504 * This function is used to notify the monitor that the system is returning 505 * to the initial state, so the monitor can start monitoring in the next event. 506 * Thus: 507 * 508 * If the monitor already started, handle the event. 509 * If the monitor did not start yet, start the monitor but skip the event. 510 */ 511 static inline bool da_handle_start_event(struct task_struct *tsk, 512 enum events event) 513 { 514 return __da_handle_start_event(da_get_monitor(tsk), event, tsk->pid); 515 } 516 517 /* 518 * da_handle_start_run_event - start monitoring and handle event 519 * 520 * This function is used to notify the monitor that the system is in the 521 * initial state, so the monitor can start monitoring and handling event. 522 */ 523 static inline bool da_handle_start_run_event(struct task_struct *tsk, 524 enum events event) 525 { 526 return __da_handle_start_run_event(da_get_monitor(tsk), event, tsk->pid); 527 } 528 #endif /* RV_MON_TYPE */ 529 530 #endif 531