On Mon, Mar 24, 2025 at 7:02 AM Jason Wang <jasow...@redhat.com> wrote: > > Factor out the split indirect descriptor detaching logic in order to > make it be reused by the in order support. >
Acked-by: Eugenio Pérez <epere...@redhat.com> > Signed-off-by: Jason Wang <jasow...@redhat.com> > --- > drivers/virtio/virtio_ring.c | 63 ++++++++++++++++++++---------------- > 1 file changed, 35 insertions(+), 28 deletions(-) > > diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c > index a1a8cd931052..0fad8e8419c8 100644 > --- a/drivers/virtio/virtio_ring.c > +++ b/drivers/virtio/virtio_ring.c > @@ -765,11 +765,42 @@ static bool virtqueue_kick_prepare_split(struct > vring_virtqueue *vq) > return needs_kick; > } > > +static void detach_indirect_split(struct vring_virtqueue *vq, > + unsigned int head) > +{ > + struct vring_desc_extra *extra = vq->split.desc_extra; > + struct vring_desc *indir_desc = > + vq->split.desc_state[head].indir_desc; > + unsigned int j; > + u32 len, num; > + > + /* Free the indirect table, if any, now that it's unmapped. */ > + if (!indir_desc) > + return; > + len = vq->split.desc_extra[head].len; > + > + BUG_ON(!(vq->split.desc_extra[head].flags & > + VRING_DESC_F_INDIRECT)); > + BUG_ON(len == 0 || len % sizeof(struct vring_desc)); > + > + num = len / sizeof(struct vring_desc); > + > + extra = (struct vring_desc_extra *)&indir_desc[num]; > + > + if (vq->use_dma_api) { > + for (j = 0; j < num; j++) > + vring_unmap_one_split(vq, &extra[j]); > + } > + > + kfree(indir_desc); > + vq->split.desc_state[head].indir_desc = NULL; > +} > + > static void detach_buf_split(struct vring_virtqueue *vq, unsigned int head, > void **ctx) > { > struct vring_desc_extra *extra; > - unsigned int i, j; > + unsigned int i; > __virtio16 nextflag = cpu_to_virtio16(vq->vq.vdev, VRING_DESC_F_NEXT); > > /* Clear data ptr. */ > @@ -793,34 +824,10 @@ static void detach_buf_split(struct vring_virtqueue > *vq, unsigned int head, > /* Plus final descriptor */ > vq->vq.num_free++; > > - if (vq->indirect) { > - struct vring_desc *indir_desc = > - vq->split.desc_state[head].indir_desc; > - u32 len, num; > - > - /* Free the indirect table, if any, now that it's unmapped. */ > - if (!indir_desc) > - return; > - len = vq->split.desc_extra[head].len; > - > - BUG_ON(!(vq->split.desc_extra[head].flags & > - VRING_DESC_F_INDIRECT)); > - BUG_ON(len == 0 || len % sizeof(struct vring_desc)); > - > - num = len / sizeof(struct vring_desc); > - > - extra = (struct vring_desc_extra *)&indir_desc[num]; > - > - if (vq->use_dma_api) { > - for (j = 0; j < num; j++) > - vring_unmap_one_split(vq, &extra[j]); > - } > - > - kfree(indir_desc); > - vq->split.desc_state[head].indir_desc = NULL; > - } else if (ctx) { > + if (vq->indirect) > + detach_indirect_split(vq, head); > + else if (ctx) > *ctx = vq->split.desc_state[head].indir_desc; > - } > } > > static bool virtqueue_poll_split(const struct vring_virtqueue *vq, > -- > 2.42.0 >