[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v3 17/20] virtio-blk: implement BlockDevOps->drained_begin()
From: |
Stefan Hajnoczi |
Subject: |
[PATCH v3 17/20] virtio-blk: implement BlockDevOps->drained_begin() |
Date: |
Thu, 20 Apr 2023 07:37:29 -0400 |
Detach ioeventfds during drained sections to stop I/O submission from
the guest. virtio-blk is no longer reliant on aio_disable_external()
after this patch. This will allow us to remove the
aio_disable_external() API once all other code that relies on it is
converted.
Take extra care to avoid attaching/detaching ioeventfds if the data
plane is started/stopped during a drained section. This should be rare,
but maybe the mirror block job can trigger it.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
hw/block/dataplane/virtio-blk.c | 17 +++++++++------
hw/block/virtio-blk.c | 38 ++++++++++++++++++++++++++++++++-
2 files changed, 48 insertions(+), 7 deletions(-)
diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
index bd7cc6e76b..d77fc6028c 100644
--- a/hw/block/dataplane/virtio-blk.c
+++ b/hw/block/dataplane/virtio-blk.c
@@ -245,13 +245,15 @@ int virtio_blk_data_plane_start(VirtIODevice *vdev)
}
/* Get this show started by hooking up our callbacks */
- aio_context_acquire(s->ctx);
- for (i = 0; i < nvqs; i++) {
- VirtQueue *vq = virtio_get_queue(s->vdev, i);
+ if (!blk_in_drain(s->conf->conf.blk)) {
+ aio_context_acquire(s->ctx);
+ for (i = 0; i < nvqs; i++) {
+ VirtQueue *vq = virtio_get_queue(s->vdev, i);
- virtio_queue_aio_attach_host_notifier(vq, s->ctx);
+ virtio_queue_aio_attach_host_notifier(vq, s->ctx);
+ }
+ aio_context_release(s->ctx);
}
- aio_context_release(s->ctx);
return 0;
fail_aio_context:
@@ -317,7 +319,10 @@ void virtio_blk_data_plane_stop(VirtIODevice *vdev)
trace_virtio_blk_data_plane_stop(s);
aio_context_acquire(s->ctx);
- aio_wait_bh_oneshot(s->ctx, virtio_blk_data_plane_stop_bh, s);
+
+ if (!blk_in_drain(s->conf->conf.blk)) {
+ aio_wait_bh_oneshot(s->ctx, virtio_blk_data_plane_stop_bh, s);
+ }
/* Wait for virtio_blk_dma_restart_bh() and in flight I/O to complete */
blk_drain(s->conf->conf.blk);
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index cefca93b31..d8dedc575c 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -1109,8 +1109,44 @@ static void virtio_blk_resize(void *opaque)
aio_bh_schedule_oneshot(qemu_get_aio_context(), virtio_resize_cb, vdev);
}
+/* Suspend virtqueue ioeventfd processing during drain */
+static void virtio_blk_drained_begin(void *opaque)
+{
+ VirtIOBlock *s = opaque;
+ VirtIODevice *vdev = VIRTIO_DEVICE(opaque);
+ AioContext *ctx = blk_get_aio_context(s->conf.conf.blk);
+
+ if (!s->dataplane || !s->dataplane_started) {
+ return;
+ }
+
+ for (uint16_t i = 0; i < s->conf.num_queues; i++) {
+ VirtQueue *vq = virtio_get_queue(vdev, i);
+ virtio_queue_aio_detach_host_notifier(vq, ctx);
+ }
+}
+
+/* Resume virtqueue ioeventfd processing after drain */
+static void virtio_blk_drained_end(void *opaque)
+{
+ VirtIOBlock *s = opaque;
+ VirtIODevice *vdev = VIRTIO_DEVICE(opaque);
+ AioContext *ctx = blk_get_aio_context(s->conf.conf.blk);
+
+ if (!s->dataplane || !s->dataplane_started) {
+ return;
+ }
+
+ for (uint16_t i = 0; i < s->conf.num_queues; i++) {
+ VirtQueue *vq = virtio_get_queue(vdev, i);
+ virtio_queue_aio_attach_host_notifier(vq, ctx);
+ }
+}
+
static const BlockDevOps virtio_block_ops = {
- .resize_cb = virtio_blk_resize,
+ .resize_cb = virtio_blk_resize,
+ .drained_begin = virtio_blk_drained_begin,
+ .drained_end = virtio_blk_drained_end,
};
static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
--
2.39.2
- [PATCH v3 01/20] hw/qdev: introduce qdev_is_realized() helper, (continued)
- [PATCH v3 08/20] hw/xen: do not use aio_set_fd_handler(is_external=true) in xen_xenstore, Stefan Hajnoczi, 2023/04/20
- [PATCH v3 05/20] util/vhost-user-server: rename refcount to in_flight counter, Stefan Hajnoczi, 2023/04/20
- [PATCH v3 19/20] virtio: do not set is_external=true on host notifiers, Stefan Hajnoczi, 2023/04/20
- [PATCH v3 03/20] virtio-scsi: stop using aio_disable_external() during unplug, Stefan Hajnoczi, 2023/04/20
- [PATCH v3 10/20] block: drain from main loop thread in bdrv_co_yield_to_drain(), Stefan Hajnoczi, 2023/04/20
- [PATCH v3 17/20] virtio-blk: implement BlockDevOps->drained_begin(),
Stefan Hajnoczi <=
- [PATCH v3 14/20] block/export: don't require AioContext lock around blk_exp_ref/unref(), Stefan Hajnoczi, 2023/04/20
- [PATCH v3 11/20] xen-block: implement BlockDevOps->drained_begin(), Stefan Hajnoczi, 2023/04/20
- [PATCH v3 04/20] block/export: only acquire AioContext once for vhost_user_server_stop(), Stefan Hajnoczi, 2023/04/20
- [PATCH v3 20/20] aio: remove aio_disable_external() API, Stefan Hajnoczi, 2023/04/20
- [PATCH v3 12/20] hw/xen: do not set is_external=true on evtchn fds, Stefan Hajnoczi, 2023/04/20
- [PATCH v3 15/20] block/fuse: do not set is_external=true on FUSE fd, Stefan Hajnoczi, 2023/04/20
- [PATCH v3 18/20] virtio-scsi: implement BlockDevOps->drained_begin(), Stefan Hajnoczi, 2023/04/20
- [PATCH v3 07/20] block/export: stop using is_external in vhost-user-blk server, Stefan Hajnoczi, 2023/04/20