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.c36
1 files changed, 22 insertions, 14 deletions
diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
index 49e5aed931..e731b1d2ea 100644
--- a/hw/virtio/vhost-shadow-virtqueue.c
+++ b/hw/virtio/vhost-shadow-virtqueue.c
@@ -514,29 +514,37 @@ static void vhost_svq_flush(VhostShadowVirtqueue *svq,
}
/**
- * Poll the SVQ for one device used buffer.
+ * Poll the SVQ to wait for the device to use the specified number
+ * of elements and return the total length written by the device.
*
* This function race with main event loop SVQ polling, so extra
* synchronization is needed.
*
- * Return the length written by the device.
+ * @svq: The svq
+ * @num: The number of elements that need to be used
*/
-size_t vhost_svq_poll(VhostShadowVirtqueue *svq)
+size_t vhost_svq_poll(VhostShadowVirtqueue *svq, size_t num)
{
- int64_t start_us = g_get_monotonic_time();
- uint32_t len = 0;
+ size_t len = 0;
+ uint32_t r;
- do {
- if (vhost_svq_more_used(svq)) {
- break;
- }
+ while (num--) {
+ int64_t start_us = g_get_monotonic_time();
- if (unlikely(g_get_monotonic_time() - start_us > 10e6)) {
- return 0;
- }
- } while (true);
+ do {
+ if (vhost_svq_more_used(svq)) {
+ break;
+ }
+
+ if (unlikely(g_get_monotonic_time() - start_us > 10e6)) {
+ return len;
+ }
+ } while (true);
+
+ vhost_svq_get_buf(svq, &r);
+ len += r;
+ }
- vhost_svq_get_buf(svq, &len);
return len;
}