Split virtqueue_push() into two logical steps - adding an element
to the used ring and notifying the other side of added elements.

This is needed because with the mergeable receive buffers scheme we
will add buffers to the used ring as we copy the packet data into them
but we only want to notify the guest of the new buffers once all the
packet buffers are available.

Signed-off-by: Mark McLoughlin <[EMAIL PROTECTED]>
---
 qemu/hw/virtio.c |   23 ++++++++++++++++++-----
 qemu/hw/virtio.h |    3 +++
 2 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/qemu/hw/virtio.c b/qemu/hw/virtio.c
index fe0a120..18ad3ed 100644
--- a/qemu/hw/virtio.c
+++ b/qemu/hw/virtio.c
@@ -107,19 +107,32 @@ static void virtqueue_init(VirtQueue *vq, void *p)
     vq->vring.used = (void *)TARGET_PAGE_ALIGN((unsigned 
long)&vq->vring.avail->ring[vq->vring.num]);
 }
 
-void virtqueue_push(VirtQueue *vq, const VirtQueueElement *elem,
-                   unsigned int len)
+void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
+                   unsigned int len, unsigned int idx)
 {
     VRingUsedElem *used;
 
+    idx += vq->vring.used->idx;
+
     /* Get a pointer to the next entry in the used ring. */
-    used = &vq->vring.used->ring[vq->vring.used->idx % vq->vring.num];
+    used = &vq->vring.used->ring[idx % vq->vring.num];
     used->id = elem->index;
     used->len = len;
+}
+
+void virtqueue_flush(VirtQueue *vq, unsigned int count)
+{
     /* Make sure buffer is written before we update index. */
     wmb();
-    vq->vring.used->idx++;
-    vq->inuse--;
+    vq->vring.used->idx += count;
+    vq->inuse -= count;
+}
+
+void virtqueue_push(VirtQueue *vq, const VirtQueueElement *elem,
+                   unsigned int len)
+{
+    virtqueue_fill(vq, elem, len, 0);
+    virtqueue_flush(vq, 1);
 }
 
 static unsigned virtqueue_next_desc(VirtQueue *vq, unsigned int i)
diff --git a/qemu/hw/virtio.h b/qemu/hw/virtio.h
index 0dcedbf..87a15cc 100644
--- a/qemu/hw/virtio.h
+++ b/qemu/hw/virtio.h
@@ -139,6 +139,9 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int 
queue_size,
 
 void virtqueue_push(VirtQueue *vq, const VirtQueueElement *elem,
                    unsigned int len);
+void virtqueue_flush(VirtQueue *vq, unsigned int count);
+void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
+                   unsigned int len, unsigned int idx);
 
 int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem);
 
-- 
1.5.4.3

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to