This helps to track the inflight buffers, make easier to transverse all of them, and return them in order.
Signed-off-by: Eugenio Pérez <epere...@redhat.com> --- hw/virtio/vhost-shadow-virtqueue.h | 6 ++++++ hw/virtio/vhost-shadow-virtqueue.c | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h index d04c34a589..a01a7d4a18 100644 --- a/hw/virtio/vhost-shadow-virtqueue.h +++ b/hw/virtio/vhost-shadow-virtqueue.h @@ -23,6 +23,9 @@ typedef struct SVQDescState { * guest's */ unsigned int ndescs; + + /* List to save or free inflight descriptors */ + QTAILQ_ENTRY(SVQDescState) entry; } SVQDescState; typedef struct VhostShadowVirtqueue VhostShadowVirtqueue; @@ -81,6 +84,9 @@ typedef struct VhostShadowVirtqueue { /* SVQ vring descriptors state */ SVQDescState *desc_state; + /* Linked list to follow avail descriptors */ + QTAILQ_HEAD(, SVQDescState) desc_state_avail; + /* Next VirtQueue element that guest made available */ VirtQueueElement *next_guest_avail_elem; diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c index 5bd14cad96..0da72cb0ec 100644 --- a/hw/virtio/vhost-shadow-virtqueue.c +++ b/hw/virtio/vhost-shadow-virtqueue.c @@ -265,6 +265,8 @@ int vhost_svq_add(VhostShadowVirtqueue *svq, const struct iovec *out_sg, svq->desc_state[qemu_head].elem = elem; svq->desc_state[qemu_head].ndescs = ndescs; + QTAILQ_INSERT_TAIL(&svq->desc_state_avail, &svq->desc_state[qemu_head], + entry); vhost_svq_kick(svq); return 0; } @@ -451,6 +453,8 @@ static VirtQueueElement *vhost_svq_get_buf(VhostShadowVirtqueue *svq, svq->free_head = used_elem.id; *len = used_elem.len; + QTAILQ_REMOVE(&svq->desc_state_avail, &svq->desc_state[used_elem.id], + entry); return g_steal_pointer(&svq->desc_state[used_elem.id].elem); } @@ -665,6 +669,7 @@ void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev, svq->vring.used = qemu_memalign(qemu_real_host_page_size(), device_size); memset(svq->vring.used, 0, device_size); svq->desc_state = g_new0(SVQDescState, svq->vring.num); + QTAILQ_INIT(&svq->desc_state_avail); svq->desc_next = g_new0(uint16_t, svq->vring.num); for (unsigned i = 0; i < svq->vring.num - 1; i++) { svq->desc_next[i] = cpu_to_le16(i + 1); -- 2.31.1