This allows SVQ to return all the inflight descriptors in order. TODO: Rewind descriptors that can be fetched from avail ring again.
Signed-off-by: Eugenio Pérez <epere...@redhat.com> --- hw/virtio/vhost-shadow-virtqueue.h | 2 ++ hw/virtio/vhost-shadow-virtqueue.c | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h index a01a7d4a18..e82da4b55c 100644 --- a/hw/virtio/vhost-shadow-virtqueue.h +++ b/hw/virtio/vhost-shadow-virtqueue.h @@ -133,6 +133,8 @@ size_t vhost_svq_device_area_size(const VhostShadowVirtqueue *svq); void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev, VirtQueue *vq); +VirtQueueElement **vhost_svq_save_inflight(VhostShadowVirtqueue *svq, + uint32_t *num); void vhost_svq_stop(VhostShadowVirtqueue *svq); VhostShadowVirtqueue *vhost_svq_new(VhostIOVATree *iova_tree, diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c index e50bfba6dc..029ccee957 100644 --- a/hw/virtio/vhost-shadow-virtqueue.c +++ b/hw/virtio/vhost-shadow-virtqueue.c @@ -676,6 +676,26 @@ void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev, } } +VirtQueueElement **vhost_svq_save_inflight(VhostShadowVirtqueue *svq, + uint32_t *num) +{ + GPtrArray *aret = g_ptr_array_new(); + SVQDescState *s, *tmp; + + QTAILQ_FOREACH_SAFE(s, &svq->desc_state_avail, entry, tmp) { + VirtQueueElement *elem = s->elem; + + virtqueue_detach_element(svq->vq, elem, 0); + g_ptr_array_add(aret, elem); + QTAILQ_REMOVE(&svq->desc_state_avail, s, entry); + } + + *num = aret->len; + + /* TODO: return g_ptr_array_steal(aret) when min glib >= 2.64 */ + return (void *)g_ptr_array_free(aret, false); +} + /** * Stop the shadow virtqueue operation. * @svq: Shadow Virtqueue -- 2.31.1