Skip to content

Commit 9dc6b94

Browse files
jasowangmstsirkin
authored andcommitted
virtio_ring: factor out split indirect detaching logic
Factor out the split indirect descriptor detaching logic in order to allow it to be reused by the in order support. Acked-by: Eugenio Pérez <eperezma@redhat.com> Reviewed-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Signed-off-by: Jason Wang <jasowang@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Message-Id: <20251230064649.55597-18-jasowang@redhat.com>
1 parent fa56d17 commit 9dc6b94

1 file changed

Lines changed: 34 additions & 28 deletions

File tree

drivers/virtio/virtio_ring.c

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -775,11 +775,41 @@ static bool virtqueue_kick_prepare_split(struct vring_virtqueue *vq)
775775
return needs_kick;
776776
}
777777

778+
static void detach_indirect_split(struct vring_virtqueue *vq,
779+
unsigned int head)
780+
{
781+
struct vring_desc_extra *extra = vq->split.desc_extra;
782+
struct vring_desc *indir_desc = vq->split.desc_state[head].indir_desc;
783+
unsigned int j;
784+
u32 len, num;
785+
786+
/* Free the indirect table, if any, now that it's unmapped. */
787+
if (!indir_desc)
788+
return;
789+
len = vq->split.desc_extra[head].len;
790+
791+
BUG_ON(!(vq->split.desc_extra[head].flags &
792+
VRING_DESC_F_INDIRECT));
793+
BUG_ON(len == 0 || len % sizeof(struct vring_desc));
794+
795+
num = len / sizeof(struct vring_desc);
796+
797+
extra = (struct vring_desc_extra *)&indir_desc[num];
798+
799+
if (vq->use_map_api) {
800+
for (j = 0; j < num; j++)
801+
vring_unmap_one_split(vq, &extra[j]);
802+
}
803+
804+
kfree(indir_desc);
805+
vq->split.desc_state[head].indir_desc = NULL;
806+
}
807+
778808
static void detach_buf_split(struct vring_virtqueue *vq, unsigned int head,
779809
void **ctx)
780810
{
781811
struct vring_desc_extra *extra;
782-
unsigned int i, j;
812+
unsigned int i;
783813
__virtio16 nextflag = cpu_to_virtio16(vq->vq.vdev, VRING_DESC_F_NEXT);
784814

785815
/* Clear data ptr. */
@@ -802,34 +832,10 @@ static void detach_buf_split(struct vring_virtqueue *vq, unsigned int head,
802832
/* Plus final descriptor */
803833
vq->vq.num_free++;
804834

805-
if (vq->indirect) {
806-
struct vring_desc *indir_desc =
807-
vq->split.desc_state[head].indir_desc;
808-
u32 len, num;
809-
810-
/* Free the indirect table, if any, now that it's unmapped. */
811-
if (!indir_desc)
812-
return;
813-
len = vq->split.desc_extra[head].len;
814-
815-
BUG_ON(!(vq->split.desc_extra[head].flags &
816-
VRING_DESC_F_INDIRECT));
817-
BUG_ON(len == 0 || len % sizeof(struct vring_desc));
818-
819-
num = len / sizeof(struct vring_desc);
820-
821-
extra = (struct vring_desc_extra *)&indir_desc[num];
822-
823-
if (vq->use_map_api) {
824-
for (j = 0; j < num; j++)
825-
vring_unmap_one_split(vq, &extra[j]);
826-
}
827-
828-
kfree(indir_desc);
829-
vq->split.desc_state[head].indir_desc = NULL;
830-
} else if (ctx) {
835+
if (vq->indirect)
836+
detach_indirect_split(vq, head);
837+
else if (ctx)
831838
*ctx = vq->split.desc_state[head].indir_desc;
832-
}
833839
}
834840

835841
static bool virtqueue_poll_split(const struct vring_virtqueue *vq,

0 commit comments

Comments
 (0)