From mboxrd@z Thu Jan 1 00:00:00 1970 From: Mark McLoughlin Subject: [PATCH 03/12] kvm: qemu: Add VIRTIO_F_NOTIFY_ON_EMPTY Date: Mon, 11 Aug 2008 21:12:06 +0100 Message-ID: <1218485535-877-4-git-send-email-markmc@redhat.com> References: <1218485535-877-1-git-send-email-markmc@redhat.com> <1218485535-877-2-git-send-email-markmc@redhat.com> <1218485535-877-3-git-send-email-markmc@redhat.com> Cc: kvm@vger.kernel.org, Mark McLoughlin To: Avi Kivity Return-path: Received: from mail09.svc.cra.dublin.eircom.net ([159.134.118.25]:44028 "HELO mail09.svc.cra.dublin.eircom.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1757556AbYHKUMh (ORCPT ); Mon, 11 Aug 2008 16:12:37 -0400 In-Reply-To: <1218485535-877-3-git-send-email-markmc@redhat.com> Sender: kvm-owner@vger.kernel.org List-ID: Set the VIRTIO_F_NOTIFY_ON_EMPTY feature bit so the guest can rely on us notifying them when the queue is empty. Also, only notify when the available queue is empty *and* when we've finished with all the buffers we had detached. Right now, when the queue is empty, we notify the guest for every used buffer. Signed-off-by: Mark McLoughlin --- qemu/hw/virtio.c | 6 +++++- qemu/hw/virtio.h | 5 +++++ 2 files changed, 10 insertions(+), 1 deletions(-) diff --git a/qemu/hw/virtio.c b/qemu/hw/virtio.c index 3429ac8..e035e4e 100644 --- a/qemu/hw/virtio.c +++ b/qemu/hw/virtio.c @@ -138,6 +138,7 @@ void virtqueue_push(VirtQueue *vq, const VirtQueueElement *elem, /* Make sure buffer is written before we update index. */ wmb(); vq->vring.used->idx++; + vq->inuse--; } int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem) @@ -187,6 +188,8 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem) elem->index = head; + vq->inuse++; + return elem->in_num + elem->out_num; } @@ -275,6 +278,7 @@ static uint32_t virtio_ioport_read(void *opaque, uint32_t addr) switch (addr) { case VIRTIO_PCI_HOST_FEATURES: ret = vdev->get_features(vdev); + ret |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY); break; case VIRTIO_PCI_GUEST_FEATURES: ret = vdev->features; @@ -431,7 +435,7 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size, void virtio_notify(VirtIODevice *vdev, VirtQueue *vq) { /* Always notify when queue is empty */ - if (vq->vring.avail->idx != vq->last_avail_idx && + if ((vq->inuse || vq->vring.avail->idx != vq->last_avail_idx) && (vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT)) return; diff --git a/qemu/hw/virtio.h b/qemu/hw/virtio.h index 61f5038..1adaed3 100644 --- a/qemu/hw/virtio.h +++ b/qemu/hw/virtio.h @@ -30,6 +30,10 @@ /* We've given up on this device. */ #define VIRTIO_CONFIG_S_FAILED 0x80 +/* We notify when the ring is completely used, even if the guest is supressing + * callbacks */ +#define VIRTIO_F_NOTIFY_ON_EMPTY 24 + /* from Linux's linux/virtio_ring.h */ /* This marks a buffer as continuing via the next field. */ @@ -86,6 +90,7 @@ struct VirtQueue VRing vring; uint32_t pfn; uint16_t last_avail_idx; + int inuse; void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq); }; -- 1.5.4.1