On Thu, Dec 25, 2025 at 12:26:03PM +0800, Jason Wang wrote:
> Let's determine the last descriptor by counting the number of sg. This
> would be consistent with packed virtqueue implementation and ease the
> future in-order implementation.
> 
> Acked-by: Eugenio PĂ©rez <[email protected]>
> Reviewed-by: Xuan Zhuo <[email protected]>
> Signed-off-by: Jason Wang <[email protected]>
> ---
>  drivers/virtio/virtio_ring.c | 28 +++++++++++++---------------
>  1 file changed, 13 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
> index 4e905dc7b6cb..dbcd6f26df7d 100644
> --- a/drivers/virtio/virtio_ring.c
> +++ b/drivers/virtio/virtio_ring.c
> @@ -575,7 +575,7 @@ static inline int virtqueue_add_split(struct 
> vring_virtqueue *vq,
>       struct vring_desc_extra *extra;
>       struct scatterlist *sg;
>       struct vring_desc *desc;
> -     unsigned int i, n, avail, descs_used, prev, err_idx;
> +     unsigned int i, n, avail, descs_used, err_idx, sg_count = 0;
>       int head;
>       bool indirect;
>  
> @@ -635,42 +635,40 @@ static inline int virtqueue_add_split(struct 
> vring_virtqueue *vq,
>               for (sg = sgs[n]; sg; sg = sg_next(sg)) {
>                       dma_addr_t addr;
>                       u32 len;
> +                     u16 flags = 0;
> +
> +                     if (++sg_count != total_sg)
> +                             flags |= VRING_DESC_F_NEXT;
>  
>                       if (vring_map_one_sg(vq, sg, DMA_TO_DEVICE, &addr, 
> &len, premapped))
>                               goto unmap_release;
>  
> -                     prev = i;
>                       /* Note that we trust indirect descriptor
>                        * table since it use stream DMA mapping.
>                        */
> -                     i = virtqueue_add_desc_split(vq, desc, extra, i, addr, 
> len,
> -                                                  VRING_DESC_F_NEXT,
> -                                                  premapped);
> +                     i = virtqueue_add_desc_split(vq, desc, extra, i, addr,
> +                                                  len, flags ,premapped);

coding style violation.

>               }
>       }
>       for (; n < (out_sgs + in_sgs); n++) {
>               for (sg = sgs[n]; sg; sg = sg_next(sg)) {
>                       dma_addr_t addr;
>                       u32 len;
> +                     u16 flags = VRING_DESC_F_WRITE;
> +
> +                     if (++sg_count != total_sg)
> +                             flags |= VRING_DESC_F_NEXT;
>  
>                       if (vring_map_one_sg(vq, sg, DMA_FROM_DEVICE, &addr, 
> &len, premapped))
>                               goto unmap_release;
>  
> -                     prev = i;
>                       /* Note that we trust indirect descriptor
>                        * table since it use stream DMA mapping.
>                        */
> -                     i = virtqueue_add_desc_split(vq, desc, extra, i, addr, 
> len,
> -                                                  VRING_DESC_F_NEXT |
> -                                                  VRING_DESC_F_WRITE,
> -                                                  premapped);
> +                     i = virtqueue_add_desc_split(vq, desc, extra, i, addr,
> +                                                  len, flags, premapped);
>               }
>       }
> -     /* Last one doesn't continue. */
> -     desc[prev].flags &= cpu_to_virtio16(vq->vq.vdev, ~VRING_DESC_F_NEXT);
> -     if (!indirect && vring_need_unmap_buffer(vq, &extra[prev]))
> -             vq->split.desc_extra[prev & (vq->split.vring.num - 1)].flags &=
> -                     ~VRING_DESC_F_NEXT;
>  
>       if (indirect) {
>               /* Now that the indirect table is filled in, map it. */
> -- 
> 2.31.1


Reply via email to