On Fri, Jul 25, 2025 at 5:10 PM Xuan Zhuo <xuanz...@linux.alibaba.com> wrote: > > On Fri, 18 Jul 2025 17:16:09 +0800, Jason Wang <jasow...@redhat.com> wrote: > > This patch switches to use dma_{map|unmap}_page() to reduce the > > coverage of DMA operations. This would help for the following rework > > on the virtio map operations. > > > > Reviewed-by: Christoph Hellwig <h...@lst.de> > > Signed-off-by: Jason Wang <jasow...@redhat.com> > > --- > > drivers/virtio/virtio_ring.c | 55 +++++++++++++++--------------------- > > 1 file changed, 23 insertions(+), 32 deletions(-) > > > > diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c > > index 103bad8cffff..75e5f6336c8d 100644 > > --- a/drivers/virtio/virtio_ring.c > > +++ b/drivers/virtio/virtio_ring.c > > @@ -405,8 +405,8 @@ static dma_addr_t vring_map_single(const struct > > vring_virtqueue *vq, > > if (!vq->use_dma_api) > > return (dma_addr_t)virt_to_phys(cpu_addr); > > > > - return dma_map_single(vring_dma_dev(vq), > > - cpu_addr, size, direction); > > + return virtqueue_dma_map_single_attrs(&vq->vq, cpu_addr, > > + size, direction, 0); > > } > > > > static int vring_mapping_error(const struct vring_virtqueue *vq, > > @@ -451,22 +451,14 @@ static unsigned int vring_unmap_one_split(const > > struct vring_virtqueue *vq, > > if (flags & VRING_DESC_F_INDIRECT) { > > if (!vq->use_dma_api) > > goto out; > > + } else if (!vring_need_unmap_buffer(vq, extra)) > > + goto out; > > > > - dma_unmap_single(vring_dma_dev(vq), > > - extra->addr, > > - extra->len, > > - (flags & VRING_DESC_F_WRITE) ? > > - DMA_FROM_DEVICE : DMA_TO_DEVICE); > > - } else { > > - if (!vring_need_unmap_buffer(vq, extra)) > > - goto out; > > - > > - dma_unmap_page(vring_dma_dev(vq), > > - extra->addr, > > - extra->len, > > - (flags & VRING_DESC_F_WRITE) ? > > - DMA_FROM_DEVICE : DMA_TO_DEVICE); > > - } > > + dma_unmap_page(vring_dma_dev(vq), > > + extra->addr, > > + extra->len, > > + (flags & VRING_DESC_F_WRITE) ? > > + DMA_FROM_DEVICE : DMA_TO_DEVICE); > > > > out: > > return extra->next; > > @@ -1276,20 +1268,13 @@ static void vring_unmap_extra_packed(const struct > > vring_virtqueue *vq, > > if (flags & VRING_DESC_F_INDIRECT) { > > if (!vq->use_dma_api) > > return; > > + } else if (!vring_need_unmap_buffer(vq, extra)) > > + return; > > > > - dma_unmap_single(vring_dma_dev(vq), > > - extra->addr, extra->len, > > - (flags & VRING_DESC_F_WRITE) ? > > - DMA_FROM_DEVICE : DMA_TO_DEVICE); > > - } else { > > - if (!vring_need_unmap_buffer(vq, extra)) > > - return; > > - > > - dma_unmap_page(vring_dma_dev(vq), > > - extra->addr, extra->len, > > - (flags & VRING_DESC_F_WRITE) ? > > - DMA_FROM_DEVICE : DMA_TO_DEVICE); > > - } > > + dma_unmap_page(vring_dma_dev(vq), > > + extra->addr, extra->len, > > + (flags & VRING_DESC_F_WRITE) ? > > + DMA_FROM_DEVICE : DMA_TO_DEVICE); > > } > > > > static struct vring_packed_desc *alloc_indirect_packed(unsigned int > > total_sg, > > @@ -3161,7 +3146,13 @@ dma_addr_t virtqueue_dma_map_single_attrs(const > > struct virtqueue *_vq, void *ptr > > return (dma_addr_t)virt_to_phys(ptr); > > } > > > > - return dma_map_single_attrs(vring_dma_dev(vq), ptr, size, dir, attrs); > > + /* DMA must never operate on areas that might be remapped. */ > > + if (dev_WARN_ONCE(&_vq->vdev->dev, is_vmalloc_addr(ptr), > > + "rejecting DMA map of vmalloc memory\n")) > > + return DMA_MAPPING_ERROR; > > > Why add this check, we never use the vmalloc address?
Yes for current drivers. Actually, I copy this from dma_map_single_attrs() for extra safety: static inline dma_addr_t dma_map_single_attrs(struct device *dev, void *ptr, size_t size, enum dma_data_direction dir, unsigned long attrs) { /* DMA must never operate on areas that might be remapped. */ if (dev_WARN_ONCE(dev, is_vmalloc_addr(ptr), "rejecting DMA map of vmalloc memory\n")) return DMA_MAPPING_ERROR; debug_dma_map_single(dev, ptr, size); return dma_map_page_attrs(dev, virt_to_page(ptr), offset_in_page(ptr), size, dir, attrs); } Thanks > > Thanks. > > > > + > > + return dma_map_page_attrs(vring_dma_dev(vq), virt_to_page(ptr), > > + offset_in_page(ptr), size, dir, attrs); > > } > > EXPORT_SYMBOL_GPL(virtqueue_dma_map_single_attrs); > > > > @@ -3186,7 +3177,7 @@ void virtqueue_dma_unmap_single_attrs(const struct > > virtqueue *_vq, > > if (!vq->use_dma_api) > > return; > > > > - dma_unmap_single_attrs(vring_dma_dev(vq), addr, size, dir, attrs); > > + dma_unmap_page_attrs(vring_dma_dev(vq), addr, size, dir, attrs); > > } > > EXPORT_SYMBOL_GPL(virtqueue_dma_unmap_single_attrs); > > > > -- > > 2.47.3 > > >