On Tue, Mar 02, 2021 at 09:46:24AM +0900, Sergey Senozhatsky wrote: > This adds support for new noncontiguous DMA API, which > requires allocators to have two execution branches: one > for the current API, and one for the new one. > > Signed-off-by: Sergey Senozhatsky <senozhatsky@xxxxxxxxxxxx> > [hch: untested conversion to the ne API] > Signed-off-by: Christoph Hellwig <hch@xxxxxx> > --- > .../common/videobuf2/videobuf2-dma-contig.c | 141 +++++++++++++++--- > 1 file changed, 117 insertions(+), 24 deletions(-) > > diff --git a/drivers/media/common/videobuf2/videobuf2-dma-contig.c b/drivers/media/common/videobuf2/videobuf2-dma-contig.c > index 1e218bc440c6..d6a9f7b682f3 100644 > --- a/drivers/media/common/videobuf2/videobuf2-dma-contig.c > +++ b/drivers/media/common/videobuf2/videobuf2-dma-contig.c > @@ -17,6 +17,7 @@ > #include <linux/sched.h> > #include <linux/slab.h> > #include <linux/dma-mapping.h> > +#include <linux/highmem.h> > > #include <media/videobuf2-v4l2.h> > #include <media/videobuf2-dma-contig.h> > @@ -42,8 +43,14 @@ struct vb2_dc_buf { > struct dma_buf_attachment *db_attach; > > struct vb2_buffer *vb; > + unsigned int non_coherent_mem:1; > }; > > +static bool vb2_dc_is_coherent(struct vb2_dc_buf *buf) > +{ > + return !buf->non_coherent_mem; > +} nit: Given that this is just a simple negated return, do we need a dedicated helper for it? > + > /*********************************************/ > /* scatterlist table functions */ > /*********************************************/ > @@ -78,12 +85,21 @@ static void *vb2_dc_cookie(struct vb2_buffer *vb, void *buf_priv) > static void *vb2_dc_vaddr(struct vb2_buffer *vb, void *buf_priv) > { > struct vb2_dc_buf *buf = buf_priv; > - struct dma_buf_map map; > - int ret; > > - if (!buf->vaddr && buf->db_attach) { > - ret = dma_buf_vmap(buf->db_attach->dmabuf, &map); > - buf->vaddr = ret ? NULL : map.vaddr; > + if (buf->vaddr) > + return buf->vaddr; > + > + if (buf->db_attach) { > + struct dma_buf_map map; > + > + if (!dma_buf_vmap(buf->db_attach->dmabuf, &map)) > + buf->vaddr = map.vaddr; > + } > + > + if (!vb2_dc_is_coherent(buf)) { I believe it's not possible for both buf->db_attach and !vb2_dc_is_coherent() to be true, but nevertheless the code can be misleading for the reader. Would it make sense to just return early in the if that handles db_attach? > + buf->vaddr = dma_vmap_noncontiguous(buf->dev, > + buf->size, > + buf->dma_sgt); > } > > return buf->vaddr; > @@ -101,13 +117,26 @@ static void vb2_dc_prepare(void *buf_priv) > struct vb2_dc_buf *buf = buf_priv; > struct sg_table *sgt = buf->dma_sgt; > > + /* This takes care of DMABUF and user-enforced cache sync hint */ > if (buf->vb->skip_cache_sync_on_prepare) > return; > > + /* > + * Coherent MMAP buffers do not need to be synced, unlike coherent > + * USERPTR and non-coherent MMAP buffers. USERPTR buffers are always considered non-coherent. > + */ > + if (buf->vb->memory == V4L2_MEMORY_MMAP && vb2_dc_is_coherent(buf)) > + return; > + > if (!sgt) > return; > > + /* For both USERPTR and non-coherent MMAP */ > dma_sync_sgtable_for_device(buf->dev, sgt, buf->dma_dir); > + > + /* Non-coherrent MMAP only */ > + if (!vb2_dc_is_coherent(buf) && buf->vaddr) > + flush_kernel_vmap_range(buf->vaddr, buf->size); > } > > static void vb2_dc_finish(void *buf_priv) > @@ -115,19 +144,46 @@ static void vb2_dc_finish(void *buf_priv) > struct vb2_dc_buf *buf = buf_priv; > struct sg_table *sgt = buf->dma_sgt; > > + /* This takes care of DMABUF and user-enforced cache sync hint */ > if (buf->vb->skip_cache_sync_on_finish) > return; > > + /* > + * Coherent MMAP buffers do not need to be synced, unlike coherent > + * USERPTR and non-coherent MMAP buffers. Ditto. > + */ > + if (buf->vb->memory == V4L2_MEMORY_MMAP && vb2_dc_is_coherent(buf)) > + return; > + > if (!sgt) > return; > > + /* For both USERPTR and non-coherent MMAP */ > dma_sync_sgtable_for_cpu(buf->dev, sgt, buf->dma_dir); > + > + /* Non-coherrent MMAP only */ > + if (!vb2_dc_is_coherent(buf) && buf->vaddr) > + invalidate_kernel_vmap_range(buf->vaddr, buf->size); > } > > /*********************************************/ > /* callbacks for MMAP buffers */ > /*********************************************/ > > +static void __vb2_dc_put(struct vb2_dc_buf *buf) > +{ > + if (vb2_dc_is_coherent(buf)) { > + dma_free_attrs(buf->dev, buf->size, buf->cookie, > + buf->dma_addr, buf->attrs); > + return; > + } > + > + if (buf->vaddr) > + dma_vunmap_noncontiguous(buf->dev, buf->vaddr); > + dma_free_noncontiguous(buf->dev, buf->size, > + buf->dma_sgt, buf->dma_addr); > +} > + > static void vb2_dc_put(void *buf_priv) nit: Unrelated to this patch or series, but could be a follow-up clean-up: Could we rename this and the newly added function to include mmap in the name, since it's only for MMAP buffers? Best regards, Tomasz