Commit 8a2fad57 authored by Michael S. Tsirkin's avatar Michael S. Tsirkin
Browse files

virtio-blk: use aio handler for data plane



In addition to handling IO in vcpu thread and in io thread, dataplane
introduces yet another mode: handling it by AioContext.

This reuses the same handler as previous modes, which triggers races as
these were not designed to be reentrant.  Use a separate handler just
for aio, and disable regular handlers when dataplane is active.

Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Reviewed-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
parent 344dc16f
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -184,6 +184,17 @@ void virtio_blk_data_plane_destroy(VirtIOBlockDataPlane *s)
    g_free(s);
}

static void virtio_blk_data_plane_handle_output(VirtIODevice *vdev,
                                                VirtQueue *vq)
{
    VirtIOBlock *s = (VirtIOBlock *)vdev;

    assert(s->dataplane);
    assert(s->dataplane_started);

    virtio_blk_handle_vq(s, vq);
}

/* Context: QEMU global mutex held */
void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
{
@@ -226,6 +237,7 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)

    /* Get this show started by hooking up our callbacks */
    aio_context_acquire(s->ctx);
    virtio_set_queue_aio(s->vq, virtio_blk_data_plane_handle_output);
    virtio_queue_aio_set_host_notifier_handler(s->vq, s->ctx, true, true);
    aio_context_release(s->ctx);
    return;
@@ -262,6 +274,7 @@ void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s)

    /* Stop notifications for new requests from guest */
    virtio_queue_aio_set_host_notifier_handler(s->vq, s->ctx, false, false);
    virtio_set_queue_aio(s->vq, NULL);

    /* Drain and switch bs back to the QEMU main loop */
    blk_set_aio_context(s->conf->conf.blk, qemu_get_aio_context());
+17 −10
Original line number Diff line number Diff line
@@ -578,20 +578,11 @@ void virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)
    }
}

static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
void virtio_blk_handle_vq(VirtIOBlock *s, VirtQueue *vq)
{
    VirtIOBlock *s = VIRTIO_BLK(vdev);
    VirtIOBlockReq *req;
    MultiReqBuffer mrb = {};

    /* Some guests kick before setting VIRTIO_CONFIG_S_DRIVER_OK so start
     * dataplane here instead of waiting for .set_status().
     */
    if (s->dataplane && !s->dataplane_started) {
        virtio_blk_data_plane_start(s->dataplane);
        return;
    }

    blk_io_plug(s->blk);

    while ((req = virtio_blk_get_request(s))) {
@@ -605,6 +596,22 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
    blk_io_unplug(s->blk);
}

static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
{
    VirtIOBlock *s = (VirtIOBlock *)vdev;

    if (s->dataplane) {
        /* Some guests kick before setting VIRTIO_CONFIG_S_DRIVER_OK so start
         * dataplane here instead of waiting for .set_status().
         */
        virtio_blk_data_plane_start(s->dataplane);
        if (!s->dataplane_disabled) {
            return;
        }
    }
    virtio_blk_handle_vq(s, vq);
}

static void virtio_blk_dma_restart_bh(void *opaque)
{
    VirtIOBlock *s = opaque;
+2 −0
Original line number Diff line number Diff line
@@ -86,4 +86,6 @@ void virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb);

void virtio_blk_submit_multireq(BlockBackend *blk, MultiReqBuffer *mrb);

void virtio_blk_handle_vq(VirtIOBlock *s, VirtQueue *vq);

#endif