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
>


Reply via email to