public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Mark McLoughlin <markmc@redhat.com>
To: Anthony Liguori <aliguori@us.ibm.com>,
	Avi Kivity <avi@qumranet.com>,
	Rusty Russell <rusty@rustcorp.com.au>
Cc: kvm@vger.kernel.org, Mark McLoughlin <markmc@redhat.com>
Subject: [PATCH 3/5] kvm: qemu: Publish last_avail index in the ring
Date: Fri, 13 Jun 2008 14:57:59 +0100	[thread overview]
Message-ID: <1213365481-23460-4-git-send-email-markmc@redhat.com> (raw)
In-Reply-To: <1213365481-23460-3-git-send-email-markmc@redhat.com>

Set the VIRTIO_RING_F_PUBLISH_INDICES feature and publish
the last_avail index within the ring itself.

This is important for save/restore when using vringfd
because the kernel is the one tracking last_avail, but
we need to be able to peek at that state.

Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
 qemu/hw/virtio-net.c |    4 ++--
 qemu/hw/virtio.c     |   16 ++++++++--------
 qemu/hw/virtio.h     |    7 ++++++-
 3 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/qemu/hw/virtio-net.c b/qemu/hw/virtio-net.c
index a61fdb1..6c42bf0 100644
--- a/qemu/hw/virtio-net.c
+++ b/qemu/hw/virtio-net.c
@@ -106,7 +106,7 @@ static int virtio_net_can_receive(void *opaque)
 	!(n->vdev.status & VIRTIO_CONFIG_S_DRIVER_OK))
 	return 0;
 
-    if (n->rx_vq->vring.avail->idx == n->rx_vq->last_avail_idx)
+    if (n->rx_vq->vring.avail->idx == vq_last_avail(n->rx_vq))
 	return 0;
 
     return 1;
@@ -178,7 +178,7 @@ static void virtio_net_handle_tx(VirtIODevice *vdev, VirtQueue *vq)
     VirtIONet *n = to_virtio_net(vdev);
 
     if (n->tx_timer_active &&
-	(vq->vring.avail->idx - vq->last_avail_idx) == 64) {
+	(vq->vring.avail->idx - vq_last_avail(vq)) == 64) {
 	vq->vring.used->flags &= ~VRING_USED_F_NO_NOTIFY;
 	qemu_del_timer(n->tx_timer);
 	n->tx_timer_active = 0;
diff --git a/qemu/hw/virtio.c b/qemu/hw/virtio.c
index 3119ea9..a1ee93f 100644
--- a/qemu/hw/virtio.c
+++ b/qemu/hw/virtio.c
@@ -147,17 +147,17 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
     unsigned int position;
 
     /* Check it isn't doing very strange things with descriptor numbers. */
-    if ((uint16_t)(vq->vring.avail->idx - vq->last_avail_idx) > vq->vring.num)
+    if ((uint16_t)(vq->vring.avail->idx - vq_last_avail(vq)) > vq->vring.num)
 	errx(1, "Guest moved used index from %u to %u",
-	     vq->last_avail_idx, vq->vring.avail->idx);
+	     vq_last_avail(vq), vq->vring.avail->idx);
 
     /* If there's nothing new since last we looked, return invalid. */
-    if (vq->vring.avail->idx == vq->last_avail_idx)
+    if (vq->vring.avail->idx == vq_last_avail(vq))
 	return 0;
 
     /* Grab the next descriptor number they're advertising, and increment
      * the index we've seen. */
-    head = vq->vring.avail->ring[vq->last_avail_idx++ % vq->vring.num];
+    head = vq->vring.avail->ring[vq_last_avail(vq)++ % vq->vring.num];
 
     /* If their number is silly, that's a fatal mistake. */
     if (head >= vq->vring.num)
@@ -222,7 +222,6 @@ void virtio_reset(void *opaque)
         vdev->vq[i].vring.desc = NULL;
         vdev->vq[i].vring.avail = NULL;
         vdev->vq[i].vring.used = NULL;
-        vdev->vq[i].last_avail_idx = 0;
         vdev->vq[i].pfn = 0;
     }
 }
@@ -278,6 +277,7 @@ static uint32_t virtio_ioport_read(void *opaque, uint32_t addr)
     case VIRTIO_PCI_HOST_FEATURES:
 	ret = vdev->get_features(vdev);
 	ret |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY);
+	ret |= (1 << VIRTIO_RING_F_PUBLISH_INDICES);
 	break;
     case VIRTIO_PCI_GUEST_FEATURES:
 	ret = vdev->features;
@@ -434,7 +434,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->inuse || vq->vring.avail->idx != vq->last_avail_idx)) &&
+    if ((vq->inuse || vq->vring.avail->idx != vq_last_avail(vq)) &&
 	(vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT))
 	return;
 
@@ -469,7 +469,7 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
 
 	qemu_put_be32(f, vdev->vq[i].vring.num);
 	qemu_put_be32s(f, &vdev->vq[i].pfn);
-	qemu_put_be16s(f, &vdev->vq[i].last_avail_idx);
+	qemu_put_be16(f, vq_last_avail(&vdev->vq[i]));
     }
 }
 
@@ -492,7 +492,7 @@ void virtio_load(VirtIODevice *vdev, QEMUFile *f)
     for (i = 0; i < num; i++) {
 	vdev->vq[i].vring.num = qemu_get_be32(f);
 	qemu_get_be32s(f, &vdev->vq[i].pfn);
-	qemu_get_be16s(f, &vdev->vq[i].last_avail_idx);
+	vq_last_avail(&vdev->vq[i]) = qemu_get_be16(f);
 
 	if (vdev->vq[i].pfn) {
 	    size_t size;
diff --git a/qemu/hw/virtio.h b/qemu/hw/virtio.h
index 1adaed3..142ecbd 100644
--- a/qemu/hw/virtio.h
+++ b/qemu/hw/virtio.h
@@ -46,6 +46,9 @@
 /* This means don't interrupt guest when buffer consumed. */
 #define VRING_AVAIL_F_NO_INTERRUPT	1
 
+/* We publish the last-seen available index at the end of the used ring */
+#define VIRTIO_RING_F_PUBLISH_INDICES	28
+
 typedef struct VirtQueue VirtQueue;
 typedef struct VirtIODevice VirtIODevice;
 
@@ -89,11 +92,13 @@ struct VirtQueue
 {
     VRing vring;
     uint32_t pfn;
-    uint16_t last_avail_idx;
     int inuse;
     void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq);
 };
 
+/* We publish the last-seen available index at the end of the used ring */
+#define vq_last_avail(q) (*(uint16_t *)&(q)->vring.used->ring[(q)->vring.num])
+
 #define VIRTQUEUE_MAX_SIZE 1024
 
 typedef struct VirtQueueElement
-- 
1.5.4.1


  reply	other threads:[~2008-06-13 13:58 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-06-13 13:57 [PATCH 0/0][RFC] KVM use of vringfd Mark McLoughlin
2008-06-13 13:57 ` [PATCH 1/5] vring: Replace mmap() interface with ioctl() Mark McLoughlin
2008-06-13 13:57   ` [PATCH 2/5] lguest: Use VRINGSETINFO ioctl() instead of mmap() Mark McLoughlin
2008-06-13 13:57     ` Mark McLoughlin [this message]
2008-06-13 13:58       ` [PATCH 4/5] kvm: qemu: Use vringfd to eliminate copies Mark McLoughlin
2008-06-13 13:58         ` [PATCH 5/5] kvm: qemu: Add support for partial csums and GSO Mark McLoughlin
2008-06-14 23:28         ` [PATCH 4/5] kvm: qemu: Use vringfd to eliminate copies Anthony Liguori
2008-06-16  2:10           ` Rusty Russell
2008-06-16 14:02             ` Anthony Liguori
2008-06-16 14:58               ` Avi Kivity
2008-06-18  5:43               ` Rusty Russell
2008-06-18 14:01             ` Avi Kivity
2008-06-17 14:08           ` Mark McLoughlin
2008-06-17 14:54             ` Anthony Liguori
2008-06-17 15:45               ` Mark McLoughlin
2008-06-13 14:09   ` [PATCH 1/5] vring: Replace mmap() interface with ioctl() Avi Kivity
2008-06-17 12:19     ` Mark McLoughlin
2008-06-18 14:05       ` Avi Kivity
2008-06-14  9:02   ` Rusty Russell
2008-06-14 14:20     ` Avi Kivity
2008-06-14 23:23       ` Anthony Liguori
2008-06-15 15:24         ` Avi Kivity
2008-06-15 19:13           ` Anthony Liguori

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1213365481-23460-4-git-send-email-markmc@redhat.com \
    --to=markmc@redhat.com \
    --cc=aliguori@us.ibm.com \
    --cc=avi@qumranet.com \
    --cc=kvm@vger.kernel.org \
    --cc=rusty@rustcorp.com.au \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox