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