aboutsummaryrefslogtreecommitdiff
path: root/hw/virtio/vhost-shadow-virtqueue.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/virtio/vhost-shadow-virtqueue.c')
-rw-r--r--hw/virtio/vhost-shadow-virtqueue.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
index c3a75ca89e..cc2ee4780d 100644
--- a/hw/virtio/vhost-shadow-virtqueue.c
+++ b/hw/virtio/vhost-shadow-virtqueue.c
@@ -486,6 +486,33 @@ static void vhost_svq_flush(VhostShadowVirtqueue *svq,
}
/**
+ * Poll the SVQ for one device used buffer.
+ *
+ * This function race with main event loop SVQ polling, so extra
+ * synchronization is needed.
+ *
+ * Return the length written by the device.
+ */
+size_t vhost_svq_poll(VhostShadowVirtqueue *svq)
+{
+ int64_t start_us = g_get_monotonic_time();
+ do {
+ uint32_t len;
+ VirtQueueElement *elem = vhost_svq_get_buf(svq, &len);
+ if (elem) {
+ return len;
+ }
+
+ if (unlikely(g_get_monotonic_time() - start_us > 10e6)) {
+ return 0;
+ }
+
+ /* Make sure we read new used_idx */
+ smp_rmb();
+ } while (true);
+}
+
+/**
* Forward used buffers.
*
* @n: hdev call event notifier, the one that device set to notify svq.