Commit 5b2ffbe4 authored by Ming Lei's avatar Ming Lei Committed by Stefan Hajnoczi
Browse files

virtio-blk: dataplane: notify guest as a batch



Now requests are submitted as a batch, so it is natural
to notify guest as a batch too.

This may suppress interrupt notification to VM a lot:

        - in my test, decreased by ~13K/sec

Signed-off-by: default avatarMing Lei <ming.lei@canonical.com>
Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
parent e926d9b8
Loading
Loading
Loading
Loading
+19 −1
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ struct VirtIOBlockDataPlane {
    VirtIODevice *vdev;
    Vring vring;                    /* virtqueue vring */
    EventNotifier *guest_notifier;  /* irq */
    QEMUBH *bh;                     /* bh for guest notification */

    /* Note that these EventNotifiers are assigned by value.  This is
     * fine as long as you do not call event_notifier_cleanup on them
@@ -61,13 +62,28 @@ static void notify_guest(VirtIOBlockDataPlane *s)
    event_notifier_set(s->guest_notifier);
}

static void notify_guest_bh(void *opaque)
{
    VirtIOBlockDataPlane *s = opaque;

    notify_guest(s);
}

static void complete_request_vring(VirtIOBlockReq *req, unsigned char status)
{
    VirtIOBlockDataPlane *s = req->dev->dataplane;
    stb_p(&req->in->status, status);

    vring_push(&req->dev->dataplane->vring, &req->elem,
               req->qiov.size + sizeof(*req->in));
    notify_guest(req->dev->dataplane);

    /* Suppress notification to guest by BH and its scheduled
     * flag because requests are completed as a batch after io
     * plug & unplug is introduced, and the BH can still be
     * executed in dataplane aio context even after it is
     * stopped, so needn't worry about notification loss with BH.
     */
    qemu_bh_schedule(s->bh);
}

static void handle_notify(EventNotifier *e)
@@ -172,6 +188,7 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *blk,
        s->iothread = &s->internal_iothread_obj;
    }
    s->ctx = iothread_get_aio_context(s->iothread);
    s->bh = aio_bh_new(s->ctx, notify_guest_bh, s);

    error_setg(&s->blocker, "block device is in use by data plane");
    bdrv_op_block_all(blk->conf.bs, s->blocker);
@@ -190,6 +207,7 @@ void virtio_blk_data_plane_destroy(VirtIOBlockDataPlane *s)
    bdrv_op_unblock_all(s->blk->conf.bs, s->blocker);
    error_free(s->blocker);
    object_unref(OBJECT(s->iothread));
    qemu_bh_delete(s->bh);
    g_free(s);
}