summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--hw/block/dataplane/virtio-blk.c8
-rw-r--r--hw/block/virtio-blk.c18
-rw-r--r--include/hw/virtio/virtio-blk.h2
3 files changed, 21 insertions, 7 deletions
diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
index 1b52e8159c..37499c5564 100644
--- a/hw/block/dataplane/virtio-blk.c
+++ b/hw/block/dataplane/virtio-blk.c
@@ -220,6 +220,9 @@ int virtio_blk_data_plane_start(VirtIODevice *vdev)
goto fail_guest_notifiers;
}
+ /* Process queued requests before the ones in vring */
+ virtio_blk_process_queued_requests(vblk, false);
+
/* Kick right away to begin processing requests already in vring */
for (i = 0; i < nvqs; i++) {
VirtQueue *vq = virtio_get_queue(s->vdev, i);
@@ -239,6 +242,11 @@ int virtio_blk_data_plane_start(VirtIODevice *vdev)
return 0;
fail_guest_notifiers:
+ /*
+ * If we failed to set up the guest notifiers queued requests will be
+ * processed on the main context.
+ */
+ virtio_blk_process_queued_requests(vblk, false);
vblk->dataplane_disabled = true;
s->starting = false;
vblk->dataplane_started = true;
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 978574e4da..8882a1d1d4 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -819,7 +819,7 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
virtio_blk_handle_output_do(s, vq);
}
-void virtio_blk_process_queued_requests(VirtIOBlock *s)
+void virtio_blk_process_queued_requests(VirtIOBlock *s, bool is_bh)
{
VirtIOBlockReq *req = s->rq;
MultiReqBuffer mrb = {};
@@ -847,7 +847,9 @@ void virtio_blk_process_queued_requests(VirtIOBlock *s)
if (mrb.num_reqs) {
virtio_blk_submit_multireq(s->blk, &mrb);
}
- blk_dec_in_flight(s->conf.conf.blk);
+ if (is_bh) {
+ blk_dec_in_flight(s->conf.conf.blk);
+ }
aio_context_release(blk_get_aio_context(s->conf.conf.blk));
}
@@ -858,21 +860,25 @@ static void virtio_blk_dma_restart_bh(void *opaque)
qemu_bh_delete(s->bh);
s->bh = NULL;
- virtio_blk_process_queued_requests(s);
+ virtio_blk_process_queued_requests(s, true);
}
static void virtio_blk_dma_restart_cb(void *opaque, int running,
RunState state)
{
VirtIOBlock *s = opaque;
+ BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(s)));
+ VirtioBusState *bus = VIRTIO_BUS(qbus);
if (!running) {
return;
}
- if (!s->bh) {
- /* FIXME The data plane is not started yet, so these requests are
- * processed in the main thread. */
+ /*
+ * If ioeventfd is enabled, don't schedule the BH here as queued
+ * requests will be processed while starting the data plane.
+ */
+ if (!s->bh && !virtio_bus_ioeventfd_enabled(bus)) {
s->bh = aio_bh_new(blk_get_aio_context(s->conf.conf.blk),
virtio_blk_dma_restart_bh, s);
blk_inc_in_flight(s->conf.conf.blk);
diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h
index f584ad9b86..b1334c3904 100644
--- a/include/hw/virtio/virtio-blk.h
+++ b/include/hw/virtio/virtio-blk.h
@@ -86,6 +86,6 @@ typedef struct MultiReqBuffer {
} MultiReqBuffer;
bool virtio_blk_handle_vq(VirtIOBlock *s, VirtQueue *vq);
-void virtio_blk_process_queued_requests(VirtIOBlock *s);
+void virtio_blk_process_queued_requests(VirtIOBlock *s, bool is_bh);
#endif