Factor out the split indirect descriptor detaching logic in order to
make it be reused by the in order support.

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


Reply via email to