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
next prev parent 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