On Thu, Dec 4, 2025 at 8:45 AM Wafer Xie <[email protected]> wrote: > > Retrieve the used ring buffers in the indirect descriptor area > of split shadow virtqueues. >
This needs to be squashed with the previous patch. Otherwise, we are allocating & mapping on each indirect descriptor but not freeing & unmapping. > Signed-off-by: Wafer Xie <[email protected]> > --- > hw/virtio/vhost-shadow-virtqueue.c | 36 ++++++++++++++++++++++++++---- > 1 file changed, 32 insertions(+), 4 deletions(-) > > diff --git a/hw/virtio/vhost-shadow-virtqueue.c > b/hw/virtio/vhost-shadow-virtqueue.c > index 94ad5c3a57..0ffb884196 100644 > --- a/hw/virtio/vhost-shadow-virtqueue.c > +++ b/hw/virtio/vhost-shadow-virtqueue.c > @@ -636,12 +636,40 @@ static VirtQueueElement > *vhost_svq_get_buf(VhostShadowVirtqueue *svq, > return NULL; > } > > + bool used_indirect = (svq->desc_state[used_elem.id].indirect_desc != > NULL); > + > + /* Free indirect descriptor table if it was used */ > + if (used_indirect) { > + if (svq->indirect_ops && svq->indirect_ops->free) { > + svq->indirect_ops->free(svq, > + > svq->desc_state[used_elem.id].indirect_desc, > + > svq->desc_state[used_elem.id].indirect_iova, > + > svq->desc_state[used_elem.id].indirect_size, > + svq->indirect_ops->opaque); > + } > + svq->desc_state[used_elem.id].indirect_desc = NULL; > + svq->desc_state[used_elem.id].indirect_iova = 0; > + svq->desc_state[used_elem.id].indirect_size = 0; > + } > + > num = svq->desc_state[used_elem.id].ndescs; > svq->desc_state[used_elem.id].ndescs = 0; > - last_used_chain = vhost_svq_last_desc_of_chain(svq, num, used_elem.id); > - svq->desc_next[last_used_chain] = svq->free_head; > - svq->free_head = used_elem.id; > - svq->num_free += num; > + > + /* > + * If using indirect descriptors, only 1 main descriptor is used. > + * To maintain consistency with `add split`, > + * we used 'num' as free descriptors. > + */ > + if (used_indirect) { > + svq->desc_next[used_elem.id] = svq->free_head; > + svq->free_head = used_elem.id; > + svq->num_free += num; > + } else { > + last_used_chain = vhost_svq_last_desc_of_chain(svq, num, > used_elem.id); > + svq->desc_next[last_used_chain] = svq->free_head; > + svq->free_head = used_elem.id; > + svq->num_free += num; > + } > > *len = used_elem.len; > return g_steal_pointer(&svq->desc_state[used_elem.id].elem); > -- > 2.34.1 >
