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.pal...@oracle.com> --- hw/virtio/vhost-shadow-virtqueue.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c index fc5f408f77..3c42adee87 100644 --- a/hw/virtio/vhost-shadow-virtqueue.c +++ b/hw/virtio/vhost-shadow-virtqueue.c @@ -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); -- 2.39.3