qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 1/9] vring: split the modification and publish of us


From: Liu Ping Fan
Subject: [Qemu-devel] [PATCH 1/9] vring: split the modification and publish of used ring
Date: Thu, 21 Feb 2013 20:54:45 +0800

From: Liu Ping Fan <address@hidden>

Currently, vring_push() modify used ring and publish it, but
sometime, we need to gather the changes and publish them all
at once. So introduce vring_fill(), vring_flush().

Signed-off-by: Liu Ping Fan <address@hidden>
---
 hw/dataplane/vring.c |   31 +++++++++++++++++++++++++++++++
 hw/dataplane/vring.h |    2 ++
 2 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/hw/dataplane/vring.c b/hw/dataplane/vring.c
index d5d4ef4..865bd4d 100644
--- a/hw/dataplane/vring.c
+++ b/hw/dataplane/vring.c
@@ -332,6 +332,37 @@ int vring_pop(VirtIODevice *vdev, Vring *vring,
     return head;
 }
 
+/* Same as vring_push, but delay update used->idx, until ready */
+void vring_fill(Vring *vring, unsigned int head, int len)
+{
+    struct vring_used_elem *used;
+
+    /* Don't touch vring if a fatal error occurred */
+    if (vring->broken) {
+        return;
+    }
+
+    /* The virtqueue contains a ring of used buffers.  Get a pointer to the
+     * next entry in that used ring. */
+    used = &vring->vr.used->ring[vring->last_used_idx % vring->vr.num];
+    used->id = head;
+    used->len = len;
+    vring->last_used_idx++;
+}
+
+void vring_flush(Vring *vring)
+{
+    uint16_t new;
+
+    /* Make sure buffer is written before we update index. */
+    smp_wmb();
+
+    new = vring->vr.used->idx = vring->last_used_idx;
+    if (unlikely((int16_t)(new - vring->signalled_used) < (uint16_t)1)) {
+        vring->signalled_used_valid = false;
+    }
+}
+
 /* After we've used one of their buffers, we tell them about it.
  *
  * Stolen from linux/drivers/vhost/vhost.c.
diff --git a/hw/dataplane/vring.h b/hw/dataplane/vring.h
index 3274f62..0d00500 100644
--- a/hw/dataplane/vring.h
+++ b/hw/dataplane/vring.h
@@ -57,6 +57,8 @@ bool vring_should_notify(VirtIODevice *vdev, Vring *vring);
 int vring_pop(VirtIODevice *vdev, Vring *vring,
               struct iovec iov[], struct iovec *iov_end,
               unsigned int *out_num, unsigned int *in_num);
+void vring_fill(Vring *vring, unsigned int head, int len);
+void vring_flush(Vring *vring);
 void vring_push(Vring *vring, unsigned int head, int len);
 
 #endif /* VRING_H */
-- 
1.7.4.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]