Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
virtio-blk: implement BlockDevOps->drained_begin()
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>
Message-Id: <20230516190238.8401-18-stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
  • Loading branch information
Stefan Hajnoczi authored and Kevin Wolf committed May 30, 2023
1 parent bd58ab4 commit 1665d93
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 7 deletions.
16 changes: 10 additions & 6 deletions hw/block/dataplane/virtio-blk.c
Expand Up @@ -246,13 +246,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:
Expand Down Expand Up @@ -322,7 +324,9 @@ void virtio_blk_data_plane_stop(VirtIODevice *vdev)
s->stopping = true;
trace_virtio_blk_data_plane_stop(s);

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);
}

aio_context_acquire(s->ctx);

Expand Down
38 changes: 37 additions & 1 deletion hw/block/virtio-blk.c
Expand Up @@ -1506,8 +1506,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)
Expand Down

0 comments on commit 1665d93

Please sign in to comment.