From bad54220ef2133fac3f1978f40d0e82f5b5dfc6c Mon Sep 17 00:00:00 2001 From: Vadim Rozenfeld <vrozenfe@redhat.com> Date: Sun, 3 Jan 2010 21:55:56 -0200 Subject: [PATCH 4/6] Queue notify support for virtio block device. RH-Author: Vadim Rozenfeld <vrozenfe@redhat.com> Message-id: <4B41126C.9080906@redhat.com> Patchwork-id: 6043 O-Subject: [RFC][PATCH] Queue notify support for virtio block device. Bugzilla: 552250 RH-Acked-by: Dor Laor <dlaor@redhat.com> RH-Acked-by: Michael S. Tsirkin <mst@redhat.com> RH-Acked-by: Juan Quintela <quintela@redhat.com> The following patch allows to reduce CPU utilization for Windows guests running with virtio block devices. repository: /home/vadimr/work/rhel5/kvm-userspace-rhel5 branch: rhel5/master commit d1da74713a8d6a25ed8cdf212379f0aebe231135 Author: Vadim Rozenfeld <vadimr@localhost.localdomain> Date: Sun Jan 3 17:57:54 2010 +0200 [RFC][PATCH] Queue notify support for virtio block device. Signed-off-by: Vadim Rozenfeld <vrozenfe@redhat.com> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- qemu/hw/virtio-blk.c | 9 +++++++++ 1 files changed, 9 insertions(+), 0 deletions(-) diff --git a/qemu/hw/virtio-blk.c b/qemu/hw/virtio-blk.c index 6f74c25..720243d 100644 --- a/qemu/hw/virtio-blk.c +++ b/qemu/hw/virtio-blk.c @@ -24,6 +24,7 @@ typedef struct VirtIOBlock VirtQueue *vq; void *rq; QEMUBH *bh; + unsigned int pending; } VirtIOBlock; static VirtIOBlock *to_virtio_blk(VirtIODevice *vdev) @@ -42,6 +43,7 @@ typedef struct VirtIOBlockReq struct VirtIOBlockReq *next; } VirtIOBlockReq; +static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq); static void virtio_blk_req_complete(VirtIOBlockReq *req, int status) { VirtIOBlock *s = req->dev; @@ -50,6 +52,10 @@ static void virtio_blk_req_complete(VirtIOBlockReq *req, int status) virtqueue_push(s->vq, &req->elem, req->size + sizeof(*req->in)); virtio_notify(&s->vdev, s->vq); + virtio_blk_handle_output(&s->vdev, s->vq); + if(--s->pending == 0) + virtio_queue_set_notification(s->vq, 1); + qemu_free(req->buffer); qemu_free(req); } @@ -200,6 +206,9 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq) exit(1); } + if(++s->pending == 1) + virtio_queue_set_notification(s->vq, 0); + req->out = (void *)req->elem.out_sg[0].iov_base; req->in = (void *)req->elem.in_sg[req->elem.in_num - 1].iov_base; -- 1.6.3.rc4.29.g8146