qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

ptimer: Remove old ptimer_init_with_bh() API

Now all the users of ptimers have converted to the transaction-based
API, we can remove ptimer_init_with_bh() and all the code paths
that are used only by bottom-half based ptimers, and tidy up the
documentation comments to consider the transaction-based API the
only possibility.

The code changes result from:
* s->bh no longer exists
* s->callback is now always non-NULL

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20191025142411.17085-1-peter.maydell@linaro.org

+36 -100
+15 -76
hw/core/ptimer.c
··· 29 29 int64_t last_event; 30 30 int64_t next_event; 31 31 uint8_t policy_mask; 32 - QEMUBH *bh; 33 32 QEMUTimer *timer; 34 33 ptimer_cb callback; 35 34 void *callback_opaque; ··· 46 45 /* Use a bottom-half routine to avoid reentrancy issues. */ 47 46 static void ptimer_trigger(ptimer_state *s) 48 47 { 49 - if (s->bh) { 50 - replay_bh_schedule_event(s->bh); 51 - } 52 - if (s->callback) { 53 - s->callback(s->callback_opaque); 54 - } 48 + s->callback(s->callback_opaque); 55 49 } 56 50 57 51 static void ptimer_reload(ptimer_state *s, int delta_adjust) ··· 296 290 297 291 void ptimer_set_count(ptimer_state *s, uint64_t count) 298 292 { 299 - assert(s->in_transaction || !s->callback); 293 + assert(s->in_transaction); 300 294 s->delta = count; 301 295 if (s->enabled) { 302 - if (!s->callback) { 303 - s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 304 - ptimer_reload(s, 0); 305 - } else { 306 - s->need_reload = true; 307 - } 296 + s->need_reload = true; 308 297 } 309 298 } 310 299 ··· 312 301 { 313 302 bool was_disabled = !s->enabled; 314 303 315 - assert(s->in_transaction || !s->callback); 304 + assert(s->in_transaction); 316 305 317 306 if (was_disabled && s->period == 0) { 318 307 if (!qtest_enabled()) { ··· 322 311 } 323 312 s->enabled = oneshot ? 2 : 1; 324 313 if (was_disabled) { 325 - if (!s->callback) { 326 - s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 327 - ptimer_reload(s, 0); 328 - } else { 329 - s->need_reload = true; 330 - } 314 + s->need_reload = true; 331 315 } 332 316 } 333 317 ··· 335 319 is immediately restarted. */ 336 320 void ptimer_stop(ptimer_state *s) 337 321 { 338 - assert(s->in_transaction || !s->callback); 322 + assert(s->in_transaction); 339 323 340 324 if (!s->enabled) 341 325 return; ··· 343 327 s->delta = ptimer_get_count(s); 344 328 timer_del(s->timer); 345 329 s->enabled = 0; 346 - if (s->callback) { 347 - s->need_reload = false; 348 - } 330 + s->need_reload = false; 349 331 } 350 332 351 333 /* Set counter increment interval in nanoseconds. */ 352 334 void ptimer_set_period(ptimer_state *s, int64_t period) 353 335 { 354 - assert(s->in_transaction || !s->callback); 336 + assert(s->in_transaction); 355 337 s->delta = ptimer_get_count(s); 356 338 s->period = period; 357 339 s->period_frac = 0; 358 340 if (s->enabled) { 359 - if (!s->callback) { 360 - s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 361 - ptimer_reload(s, 0); 362 - } else { 363 - s->need_reload = true; 364 - } 341 + s->need_reload = true; 365 342 } 366 343 } 367 344 368 345 /* Set counter frequency in Hz. */ 369 346 void ptimer_set_freq(ptimer_state *s, uint32_t freq) 370 347 { 371 - assert(s->in_transaction || !s->callback); 348 + assert(s->in_transaction); 372 349 s->delta = ptimer_get_count(s); 373 350 s->period = 1000000000ll / freq; 374 351 s->period_frac = (1000000000ll << 32) / freq; 375 352 if (s->enabled) { 376 - if (!s->callback) { 377 - s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 378 - ptimer_reload(s, 0); 379 - } else { 380 - s->need_reload = true; 381 - } 353 + s->need_reload = true; 382 354 } 383 355 } 384 356 ··· 386 358 count = limit. */ 387 359 void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload) 388 360 { 389 - assert(s->in_transaction || !s->callback); 361 + assert(s->in_transaction); 390 362 s->limit = limit; 391 363 if (reload) 392 364 s->delta = limit; 393 365 if (s->enabled && reload) { 394 - if (!s->callback) { 395 - s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 396 - ptimer_reload(s, 0); 397 - } else { 398 - s->need_reload = true; 399 - } 366 + s->need_reload = true; 400 367 } 401 368 } 402 369 ··· 407 374 408 375 void ptimer_transaction_begin(ptimer_state *s) 409 376 { 410 - assert(!s->in_transaction || !s->callback); 377 + assert(!s->in_transaction); 411 378 s->in_transaction = true; 412 379 s->need_reload = false; 413 380 } ··· 448 415 } 449 416 }; 450 417 451 - ptimer_state *ptimer_init_with_bh(QEMUBH *bh, uint8_t policy_mask) 452 - { 453 - ptimer_state *s; 454 - 455 - s = (ptimer_state *)g_malloc0(sizeof(ptimer_state)); 456 - s->bh = bh; 457 - s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ptimer_tick, s); 458 - s->policy_mask = policy_mask; 459 - 460 - /* 461 - * These two policies are incompatible -- trigger-on-decrement implies 462 - * a timer trigger when the count becomes 0, but no-immediate-trigger 463 - * implies a trigger when the count stops being 0. 464 - */ 465 - assert(!((policy_mask & PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT) && 466 - (policy_mask & PTIMER_POLICY_NO_IMMEDIATE_TRIGGER))); 467 - return s; 468 - } 469 - 470 418 ptimer_state *ptimer_init(ptimer_cb callback, void *callback_opaque, 471 419 uint8_t policy_mask) 472 420 { 473 421 ptimer_state *s; 474 422 475 - /* 476 - * The callback function is mandatory; so we use it to distinguish 477 - * old-style QEMUBH ptimers from new transaction API ptimers. 478 - * (ptimer_init_with_bh() allows a NULL bh pointer and at least 479 - * one device (digic-timer) passes NULL, so it's not the case 480 - * that either s->bh != NULL or s->callback != NULL.) 481 - */ 423 + /* The callback function is mandatory. */ 482 424 assert(callback); 483 425 484 426 s = g_new0(ptimer_state, 1); ··· 499 441 500 442 void ptimer_free(ptimer_state *s) 501 443 { 502 - if (s->bh) { 503 - qemu_bh_delete(s->bh); 504 - } 505 444 timer_free(s->timer); 506 445 g_free(s); 507 446 }
+21 -24
include/hw/ptimer.h
··· 10 10 11 11 #include "qemu/timer.h" 12 12 13 - /* The ptimer API implements a simple periodic countdown timer. 13 + /* 14 + * The ptimer API implements a simple periodic countdown timer. 14 15 * The countdown timer has a value (which can be read and written via 15 16 * ptimer_get_count() and ptimer_set_count()). When it is enabled 16 17 * using ptimer_run(), the value will count downwards at the frequency 17 18 * which has been configured using ptimer_set_period() or ptimer_set_freq(). 18 - * When it reaches zero it will trigger a QEMU bottom half handler, and 19 + * When it reaches zero it will trigger a callback function, and 19 20 * can be set to either reload itself from a specified limit value 20 21 * and keep counting down, or to stop (as a one-shot timer). 22 + * 23 + * A transaction-based API is used for modifying ptimer state: all calls 24 + * to functions which modify ptimer state must be between matched calls to 25 + * ptimer_transaction_begin() and ptimer_transaction_commit(). 26 + * When ptimer_transaction_commit() is called it will evaluate the state 27 + * of the timer after all the changes in the transaction, and call the 28 + * callback if necessary. (See the ptimer_init() documentation for the full 29 + * list of state-modifying functions and detailed semantics of the callback.) 21 30 * 22 31 * Forgetting to set the period/frequency (or setting it to zero) is a 23 32 * bug in the QEMU device and will cause warning messages to be printed ··· 72 81 * ptimer_set_count() or ptimer_set_limit() will not trigger the timer 73 82 * (though it will cause a reload). Only a counter decrement to "0" 74 83 * will cause a trigger. Not compatible with NO_IMMEDIATE_TRIGGER; 75 - * ptimer_init_with_bh() will assert() that you don't set both. 84 + * ptimer_init() will assert() that you don't set both. 76 85 */ 77 86 #define PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT (1 << 5) 78 87 ··· 81 90 typedef void (*ptimer_cb)(void *opaque); 82 91 83 92 /** 84 - * ptimer_init_with_bh - Allocate and return a new ptimer 85 - * @bh: QEMU bottom half which is run on timer expiry 86 - * @policy: PTIMER_POLICY_* bits specifying behaviour 87 - * 88 - * The ptimer returned must be freed using ptimer_free(). 89 - * The ptimer takes ownership of @bh and will delete it 90 - * when the ptimer is eventually freed. 91 - */ 92 - ptimer_state *ptimer_init_with_bh(QEMUBH *bh, uint8_t policy_mask); 93 - 94 - /** 95 93 * ptimer_init - Allocate and return a new ptimer 96 94 * @callback: function to call on ptimer expiry 97 95 * @callback_opaque: opaque pointer passed to @callback ··· 127 125 * ptimer_free - Free a ptimer 128 126 * @s: timer to free 129 127 * 130 - * Free a ptimer created using ptimer_init_with_bh() (including 131 - * deleting the bottom half which it is using). 128 + * Free a ptimer created using ptimer_init(). 132 129 */ 133 130 void ptimer_free(ptimer_state *s); 134 131 ··· 164 161 * may be more appropriate. 165 162 * 166 163 * This function will assert if it is called outside a 167 - * ptimer_transaction_begin/commit block, unless this is a bottom-half ptimer. 164 + * ptimer_transaction_begin/commit block. 168 165 */ 169 166 void ptimer_set_period(ptimer_state *s, int64_t period); 170 167 ··· 180 177 * precise to fractions of a nanosecond, avoiding rounding errors. 181 178 * 182 179 * This function will assert if it is called outside a 183 - * ptimer_transaction_begin/commit block, unless this is a bottom-half ptimer. 180 + * ptimer_transaction_begin/commit block. 184 181 */ 185 182 void ptimer_set_freq(ptimer_state *s, uint32_t freq); 186 183 ··· 210 207 * reload the counter when their reload register is written to. 211 208 * 212 209 * This function will assert if it is called outside a 213 - * ptimer_transaction_begin/commit block, unless this is a bottom-half ptimer. 210 + * ptimer_transaction_begin/commit block. 214 211 */ 215 212 void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload); 216 213 ··· 234 231 * point in the future. 235 232 * 236 233 * This function will assert if it is called outside a 237 - * ptimer_transaction_begin/commit block, unless this is a bottom-half ptimer. 234 + * ptimer_transaction_begin/commit block. 238 235 */ 239 236 void ptimer_set_count(ptimer_state *s, uint64_t count); 240 237 ··· 243 240 * @s: ptimer 244 241 * @oneshot: non-zero if this timer should only count down once 245 242 * 246 - * Start a ptimer counting down; when it reaches zero the bottom half 247 - * passed to ptimer_init_with_bh() will be invoked. 243 + * Start a ptimer counting down; when it reaches zero the callback function 244 + * passed to ptimer_init() will be invoked. 248 245 * If the @oneshot argument is zero, 249 246 * the counter value will then be reloaded from the limit and it will 250 247 * start counting down again. If @oneshot is non-zero, then the counter 251 248 * will disable itself when it reaches zero. 252 249 * 253 250 * This function will assert if it is called outside a 254 - * ptimer_transaction_begin/commit block, unless this is a bottom-half ptimer. 251 + * ptimer_transaction_begin/commit block. 255 252 */ 256 253 void ptimer_run(ptimer_state *s, int oneshot); 257 254 ··· 266 263 * restarted. 267 264 * 268 265 * This function will assert if it is called outside a 269 - * ptimer_transaction_begin/commit block, unless this is a bottom-half ptimer. 266 + * ptimer_transaction_begin/commit block. 270 267 */ 271 268 void ptimer_stop(ptimer_state *s); 272 269