diff options
author | Ming Lei <tom.leiming@gmail.com> | 2014-07-12 12:08:53 +0800 |
---|---|---|
committer | Stefan Hajnoczi <stefanha@redhat.com> | 2014-07-15 15:34:13 +0200 |
commit | 5b2ffbe4d99843fd8305c573a100047a8c962327 (patch) | |
tree | beb91143f9df9c61e1746e1aceb3d349072d7367 /hw | |
parent | e926d9b8c52d5ddf413617df4b341a3114642b14 (diff) |
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: Ming Lei <ming.lei@canonical.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/block/dataplane/virtio-blk.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c index e88862dc50..d6ba65ca23 100644 --- a/hw/block/dataplane/virtio-blk.c +++ b/hw/block/dataplane/virtio-blk.c @@ -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); } |