@@ -405,6 +405,15 @@ int aio_bh_poll(AioContext *ctx);
*/
void qemu_bh_schedule_event(QEMUBH *bh, QEMUClockType clock_type);
+/**
+ * qemu_bh_schedule_event_noreplay: Schedule a bottom half avoiding replay.
+ *
+ * This function is not to be used outside record-replay code.
+ *
+ * @bh: The bottom half to be scheduled.
+ */
+void qemu_bh_schedule_event_noreplay(QEMUBH *bh);
+
/**
* qemu_bh_schedule: Schedule a bottom half.
*
@@ -7144,7 +7144,9 @@ void bdrv_schedule_unref(BlockDriverState *bs)
if (!bs) {
return;
}
- aio_bh_schedule_oneshot(qemu_get_aio_context(), bdrv_schedule_unref_bh, bs);
+ aio_bh_schedule_oneshot_event(qemu_get_aio_context(),
+ bdrv_schedule_unref_bh, bs,
+ QEMU_CLOCK_REALTIME);
}
struct BdrvOpBlocker {
@@ -67,7 +67,15 @@ static void block_request_create(uint64_t reqid, BlockDriverState *bs,
.co = co,
.bh = aio_bh_new(bdrv_get_aio_context(bs), blkreplay_bh_cb, req),
};
- replay_block_event(req->bh, reqid);
+ if (replay_events_enabled()) {
+ replay_block_event(req->bh, reqid);
+ } else {
+ /*
+ * block can be used before replay is initialized. Work around
+ * that here.
+ */
+ qemu_bh_schedule_event_noreplay(req->bh);
+ }
}
static int coroutine_fn GRAPH_RDLOCK
@@ -154,11 +154,8 @@ void replay_add_input_sync_event(void)
void replay_block_event(QEMUBH *bh, uint64_t id)
{
- if (events_enabled) {
- replay_add_event(REPLAY_ASYNC_EVENT_BLOCK, bh, NULL, id);
- } else {
- qemu_bh_schedule(bh);
- }
+ g_assert(events_enabled);
+ replay_add_event(REPLAY_ASYNC_EVENT_BLOCK, bh, NULL, id);
}
static void replay_save_event(Event *event)
@@ -261,6 +261,11 @@ void qemu_bh_schedule_event(QEMUBH *bh, QEMUClockType clock_type)
}
}
+void qemu_bh_schedule_event_noreplay(QEMUBH *bh)
+{
+ aio_bh_enqueue(bh, BH_SCHEDULED);
+}
+
void qemu_bh_schedule_idle(QEMUBH *bh)
{
aio_bh_enqueue(bh, BH_SCHEDULED | BH_IDLE);
Convert qemu_bh_schedule() to qemu_bh_schedule_event() and aio_bh_schedule_oneshot() to aio_bh_schedule_oneshot_event(), which can specify the clock type, making it compatible with record-replay. unreferencing a bdrv does not affect target machine state, so it should use QEMU_CLOCK_REALTIME so it is not recorded and replayed. blkreplay has cases at startup where the device is used before the event code is set up, so it needs special handling to avoid creating bh replay events. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> --- include/block/aio.h | 9 +++++++++ block.c | 4 +++- block/blkreplay.c | 10 +++++++++- replay/replay-events.c | 7 ++----- util/async.c | 5 +++++ 5 files changed, 28 insertions(+), 7 deletions(-)