Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Jason Wang and committed by
Michael S. Tsirkin
9dc6b944 fa56d17b

+34 -28
+34 -28
drivers/virtio/virtio_ring.c
··· 775 775 return needs_kick; 776 776 } 777 777 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 + 778 808 static void detach_buf_split(struct vring_virtqueue *vq, unsigned int head, 779 809 void **ctx) 780 810 { 781 811 struct vring_desc_extra *extra; 782 - unsigned int i, j; 812 + unsigned int i; 783 813 __virtio16 nextflag = cpu_to_virtio16(vq->vq.vdev, VRING_DESC_F_NEXT); 784 814 785 815 /* Clear data ptr. */ ··· 832 802 /* Plus final descriptor */ 833 803 vq->vq.num_free++; 834 804 835 - if (vq->indirect) { 836 - struct vring_desc *indir_desc = 837 - vq->split.desc_state[head].indir_desc; 838 - u32 len, num; 839 - 840 - /* Free the indirect table, if any, now that it's unmapped. */ 841 - if (!indir_desc) 842 - return; 843 - len = vq->split.desc_extra[head].len; 844 - 845 - BUG_ON(!(vq->split.desc_extra[head].flags & 846 - VRING_DESC_F_INDIRECT)); 847 - BUG_ON(len == 0 || len % sizeof(struct vring_desc)); 848 - 849 - num = len / sizeof(struct vring_desc); 850 - 851 - extra = (struct vring_desc_extra *)&indir_desc[num]; 852 - 853 - if (vq->use_map_api) { 854 - for (j = 0; j < num; j++) 855 - vring_unmap_one_split(vq, &extra[j]); 856 - } 857 - 858 - kfree(indir_desc); 859 - vq->split.desc_state[head].indir_desc = NULL; 860 - } else if (ctx) { 805 + if (vq->indirect) 806 + detach_indirect_split(vq, head); 807 + else if (ctx) 861 808 *ctx = vq->split.desc_state[head].indir_desc; 862 - } 863 809 } 864 810 865 811 static bool virtqueue_poll_split(const struct vring_virtqueue *vq,