@@ -493,11 +493,20 @@ static void vhost_svq_flush(VhostShadowVirtqueue *svq,
qemu_log_mask(LOG_GUEST_ERROR,
"More than %u used buffers obtained in a %u size SVQ",
i, svq->vring.num);
- virtqueue_fill(vq, elem, len, i);
- virtqueue_flush(vq, i);
+ if (virtio_vdev_has_feature(svq->vdev, VIRTIO_F_IN_ORDER)) {
+ virtqueue_order_element(vq, elem, len, i, i);
+ } else {
+ virtqueue_fill(vq, elem, len, i);
+ virtqueue_flush(vq, i);
+ }
return;
}
- virtqueue_fill(vq, elem, len, i++);
+
+ if (virtio_vdev_has_feature(svq->vdev, VIRTIO_F_IN_ORDER)) {
+ virtqueue_order_element(vq, elem, len, i++, 0);
+ } else {
+ virtqueue_fill(vq, elem, len, i++);
+ }
}
virtqueue_flush(vq, i);
Implements in-order handling for vhost devices using shadow virtqueues. Since vhost's shadow virtqueues utilize batching in their vhost_svq_flush calls, the vhost device is responsible for calling virtqueue_flush once it has completed its batching operation. Note: ----- It's unclear if this implementation is really necessary to "guarantee" in-order handling since, by design, the vhost_svq_flush function puts used VirtQueueElements in-order already. Signed-off-by: Jonah Palmer <jonah.palmer@oracle.com> --- hw/virtio/vhost-shadow-virtqueue.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)