virtqueue_add_packed() only supports virtual addresses, dma is completed in virtqueue_add_packed(). In some scenarios (such as the AF_XDP scenario), the memory is allocated and DMA is completed in advance, so it is necessary for us to support passing the DMA address to virtio core. Signed-off-by: Xuan Zhuo <xuanzhuo@xxxxxxxxxxxxxxxxx> --- drivers/virtio/virtio_ring.c | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 81a9c0692fec..5e98f828236d 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -78,6 +78,7 @@ struct vring_desc_state_packed { struct vring_packed_desc *indir_desc; /* Indirect descriptor, if any. */ u16 num; /* Descriptor list length. */ u16 last; /* The last desc state in a list. */ + bool dma_map; /* Addr is mapped by virtio core or not. */ }; struct vring_desc_extra { @@ -1286,7 +1287,8 @@ static inline u16 packed_last_used(u16 last_used_idx) } static void vring_unmap_extra_packed(const struct vring_virtqueue *vq, - struct vring_desc_extra *extra) + struct vring_desc_extra *extra, + bool dma_map) { u16 flags; @@ -1301,6 +1303,9 @@ static void vring_unmap_extra_packed(const struct vring_virtqueue *vq, (flags & VRING_DESC_F_WRITE) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); } else { + if (!dma_map) + return; + dma_unmap_page(vring_dma_dev(vq), extra->addr, extra->len, (flags & VRING_DESC_F_WRITE) ? @@ -1564,6 +1569,7 @@ static inline int virtqueue_add_packed(struct virtqueue *_vq, unsigned int in_sgs, void *data, void *ctx, + bool dma_map, gfp_t gfp) { @@ -1581,9 +1587,11 @@ static inline int virtqueue_add_packed(struct virtqueue *_vq, goto end; } - err = virtqueue_map_sgs(vq, sgs, total_sg, out_sgs, in_sgs); - if (err) - goto err; + if (dma_map) { + err = virtqueue_map_sgs(vq, sgs, total_sg, out_sgs, in_sgs); + if (err) + goto err; + } id = vq->free_head; @@ -1597,11 +1605,14 @@ static inline int virtqueue_add_packed(struct virtqueue *_vq, } vq->packed.desc_state[id].data = data; + vq->packed.desc_state[id].dma_map = dma_map; goto end; err: - virtqueue_unmap_sgs(vq, sgs, total_sg, out_sgs, in_sgs); + if (dma_map) + virtqueue_unmap_sgs(vq, sgs, total_sg, out_sgs, in_sgs); + kfree(desc); end: @@ -1664,8 +1675,10 @@ static void detach_buf_packed(struct vring_virtqueue *vq, struct vring_desc_state_packed *state = NULL; struct vring_packed_desc *desc; unsigned int i, curr; + bool dma_map; state = &vq->packed.desc_state[id]; + dma_map = state->dma_map; /* Clear data ptr. */ state->data = NULL; @@ -1678,7 +1691,8 @@ static void detach_buf_packed(struct vring_virtqueue *vq, curr = id; for (i = 0; i < state->num; i++) { vring_unmap_extra_packed(vq, - &vq->packed.desc_extra[curr]); + &vq->packed.desc_extra[curr], + dma_map); curr = vq->packed.desc_extra[curr].next; } } @@ -1691,7 +1705,7 @@ static void detach_buf_packed(struct vring_virtqueue *vq, if (!desc) return; - if (vq->use_dma_api) { + if (vq->use_dma_api && dma_map) { len = vq->packed.desc_extra[id].len; for (i = 0; i < len / sizeof(struct vring_packed_desc); i++) @@ -2218,7 +2232,7 @@ static inline int virtqueue_add(struct virtqueue *_vq, struct vring_virtqueue *vq = to_vvq(_vq); return vq->packed_ring ? virtqueue_add_packed(_vq, sgs, total_sg, - out_sgs, in_sgs, data, ctx, gfp) : + out_sgs, in_sgs, data, ctx, true, gfp) : virtqueue_add_split(_vq, sgs, total_sg, out_sgs, in_sgs, data, ctx, true, gfp); } @@ -2234,8 +2248,10 @@ static inline int virtqueue_add_premapped(struct virtqueue *_vq, { struct vring_virtqueue *vq = to_vvq(_vq); - return virtqueue_add_split(_vq, sgs, total_sg, out_sgs, in_sgs, data, - ctx, false, gfp); + return vq->packed_ring ? virtqueue_add_packed(_vq, sgs, total_sg, + out_sgs, in_sgs, data, ctx, false, gfp) : + virtqueue_add_split(_vq, sgs, total_sg, out_sgs, + in_sgs, data, ctx, false, gfp); } /** -- 2.32.0.3.g01195cf9f _______________________________________________ Virtualization mailing list Virtualization@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linuxfoundation.org/mailman/listinfo/virtualization