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