[PATCH 11/17] block: Convert to new bh API

Nicholas Piggin posted 17 patches 3 days, 12 hours ago
[PATCH 11/17] block: Convert to new bh API
Posted by Nicholas Piggin 3 days, 12 hours ago
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(-)

diff --git a/include/block/aio.h b/include/block/aio.h
index bc323b0d936..26859bd0b93 100644
--- a/include/block/aio.h
+++ b/include/block/aio.h
@@ -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.
  *
diff --git a/block.c b/block.c
index 7d90007cae8..77e6c6b3c7e 100644
--- a/block.c
+++ b/block.c
@@ -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 {
diff --git a/block/blkreplay.c b/block/blkreplay.c
index 792d980aa9d..c6b9d91062e 100644
--- a/block/blkreplay.c
+++ b/block/blkreplay.c
@@ -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
diff --git a/replay/replay-events.c b/replay/replay-events.c
index d4b095b2097..6a7c27cac1e 100644
--- a/replay/replay-events.c
+++ b/replay/replay-events.c
@@ -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)
diff --git a/util/async.c b/util/async.c
index 6ac994effec..5d2c76dec08 100644
--- a/util/async.c
+++ b/util/async.c
@@ -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);
-- 
2.45.2