|
@@ -485,6 +485,33 @@ static void vhost_svq_flush(VhostShadowVirtqueue *svq,
|
|
|
} while (!vhost_svq_enable_notification(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.
|
|
|
*
|