Patchwork [1/9] vring: split the modification and publish of used ring

login
register
mail settings
Submitter pingfan liu
Date Feb. 21, 2013, 12:54 p.m.
Message ID <1361451293-5181-2-git-send-email-qemulist@gmail.com>
Download mbox | patch
Permalink /patch/222281/
State New
Headers show

Comments

pingfan liu - Feb. 21, 2013, 12:54 p.m.
From: Liu Ping Fan <pingfank@linux.vnet.ibm.com>

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 <pingfank@linux.vnet.ibm.com>
---
 hw/dataplane/vring.c |   31 +++++++++++++++++++++++++++++++
 hw/dataplane/vring.h |    2 ++
 2 files changed, 33 insertions(+), 0 deletions(-)

Patch

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 */