To handle freeing buf from the detached vring, do a split for detach_buf_packed(). The split function detach_buf_from_vring_packed() is used to release buf from vring, and the vq passed in is read-only. All modifications are for vring. In this way, detach_buf_from_vring_packed() becomes a general function, which can be used for detach_buf_packed() and also for handling detached vrings. Signed-off-by: Xuan Zhuo <xuanzhuo@xxxxxxxxxxxxxxxxx> --- drivers/virtio/virtio_ring.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 5e6bd9a4e648..1efb47b88b40 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -1703,28 +1703,28 @@ static bool virtqueue_kick_prepare_packed(struct virtqueue *_vq) return needs_kick; } -static void detach_buf_packed(struct vring_virtqueue *vq, - unsigned int id, void **ctx) +static int detach_buf_from_vring_packed(struct vring_virtqueue_packed *vring, + struct vring_virtqueue const *vq, + unsigned int id, + unsigned int free_head, + void **ctx) { struct vring_desc_state_packed *state = NULL; struct vring_packed_desc *desc; unsigned int i, curr; - state = &vq->packed.desc_state[id]; + state = &vring->desc_state[id]; /* Clear data ptr. */ state->data = NULL; - vq->packed.desc_extra[state->last].next = vq->free_head; - vq->free_head = id; - vq->vq.num_free += state->num; + vring->desc_extra[state->last].next = free_head; if (unlikely(vq->use_dma_api)) { curr = id; for (i = 0; i < state->num; i++) { - vring_unmap_extra_packed(vq, - &vq->packed.desc_extra[curr]); - curr = vq->packed.desc_extra[curr].next; + vring_unmap_extra_packed(vq, &vring->desc_extra[curr]); + curr = vring->desc_extra[curr].next; } } @@ -1734,10 +1734,10 @@ static void detach_buf_packed(struct vring_virtqueue *vq, /* Free the indirect table, if any, now that it's unmapped. */ desc = state->indir_desc; if (!desc) - return; + return state->num; if (vq->use_dma_api) { - len = vq->packed.desc_extra[id].len; + len = vring->desc_extra[id].len; for (i = 0; i < len / sizeof(struct vring_packed_desc); i++) vring_unmap_desc_packed(vq, &desc[i]); @@ -1747,6 +1747,20 @@ static void detach_buf_packed(struct vring_virtqueue *vq, } else if (ctx) { *ctx = state->indir_desc; } + + return state->num; +} + +static void detach_buf_packed(struct vring_virtqueue *vq, + unsigned int id, void **ctx) +{ + int num; + + num = detach_buf_from_vring_packed(&vq->packed, vq, id, vq->free_head, + ctx); + + vq->free_head = id; + vq->vq.num_free += num; } static inline bool is_used_desc_packed(const struct vring_virtqueue *vq, -- 2.31.0 _______________________________________________ Virtualization mailing list Virtualization@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linuxfoundation.org/mailman/listinfo/virtualization