Re: [PATCH v6 35/36] videobuf2: use sgtable-based scatterlist wrappers
On 2020-06-18 16:39, Marek Szyprowski wrote: Use recently introduced common wrappers operating directly on the struct sg_table objects and scatterlist page iterators to make the code a bit more compact, robust, easier to follow and copy/paste safe. No functional change, because the code already properly did all the scaterlist related calls. Signed-off-by: Marek Szyprowski --- .../common/videobuf2/videobuf2-dma-contig.c | 41 --- .../media/common/videobuf2/videobuf2-dma-sg.c | 32 ++- .../common/videobuf2/videobuf2-vmalloc.c | 12 ++ 3 files changed, 34 insertions(+), 51 deletions(-) diff --git a/drivers/media/common/videobuf2/videobuf2-dma-contig.c b/drivers/media/common/videobuf2/videobuf2-dma-contig.c index f4b4a7c135eb..ba01a8692d88 100644 --- a/drivers/media/common/videobuf2/videobuf2-dma-contig.c +++ b/drivers/media/common/videobuf2/videobuf2-dma-contig.c @@ -48,16 +48,15 @@ struct vb2_dc_buf { static unsigned long vb2_dc_get_contiguous_size(struct sg_table *sgt) { - struct scatterlist *s; dma_addr_t expected = sg_dma_address(sgt->sgl); - unsigned int i; + struct sg_dma_page_iter dma_iter; unsigned long size = 0; - for_each_sg(sgt->sgl, s, sgt->nents, i) { - if (sg_dma_address(s) != expected) + for_each_sgtable_dma_page(sgt, _iter, 0) { + if (sg_page_iter_dma_address(_iter) != expected) break; - expected = sg_dma_address(s) + sg_dma_len(s); - size += sg_dma_len(s); + expected += PAGE_SIZE; + size += PAGE_SIZE; Same comment as for the DRM version. In fact, given that it's the same function with the same purpose, might it be worth hoisting out as a generic helper for the sg_table API itself? } return size; } [...] diff --git a/drivers/media/common/videobuf2/videobuf2-dma-sg.c b/drivers/media/common/videobuf2/videobuf2-dma-sg.c index 92072a08af25..6ddf953efa11 100644 --- a/drivers/media/common/videobuf2/videobuf2-dma-sg.c +++ b/drivers/media/common/videobuf2/videobuf2-dma-sg.c @@ -142,9 +142,8 @@ static void *vb2_dma_sg_alloc(struct device *dev, unsigned long dma_attrs, * No need to sync to the device, this will happen later when the * prepare() memop is called. */ - sgt->nents = dma_map_sg_attrs(buf->dev, sgt->sgl, sgt->orig_nents, - buf->dma_dir, DMA_ATTR_SKIP_CPU_SYNC); - if (!sgt->nents) + if (dma_map_sgtable(buf->dev, sgt, buf->dma_dir, + DMA_ATTR_SKIP_CPU_SYNC)) { As 0-day's explosions of nonsense imply, there's a rogue bracket here... goto fail_map; buf->handler.refcount = >refcount; @@ -180,8 +179,8 @@ static void vb2_dma_sg_put(void *buf_priv) if (refcount_dec_and_test(>refcount)) { dprintk(1, "%s: Freeing buffer of %d pages\n", __func__, buf->num_pages); - dma_unmap_sg_attrs(buf->dev, sgt->sgl, sgt->orig_nents, - buf->dma_dir, DMA_ATTR_SKIP_CPU_SYNC); + dma_unmap_sgtable(buf->dev, sgt, buf->dma_dir, + DMA_ATTR_SKIP_CPU_SYNC); if (buf->vaddr) vm_unmap_ram(buf->vaddr, buf->num_pages); sg_free_table(buf->dma_sgt); @@ -202,8 +201,7 @@ static void vb2_dma_sg_prepare(void *buf_priv) if (buf->db_attach) return; - dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->orig_nents, - buf->dma_dir); + dma_sync_sgtable_for_device(buf->dev, sgt, buf->dma_dir); } static void vb2_dma_sg_finish(void *buf_priv) @@ -215,7 +213,7 @@ static void vb2_dma_sg_finish(void *buf_priv) if (buf->db_attach) return; - dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir); + dma_sync_sgtable_for_cpu(buf->dev, sgt, buf->dma_dir); } static void *vb2_dma_sg_get_userptr(struct device *dev, unsigned long vaddr, @@ -258,9 +256,8 @@ static void *vb2_dma_sg_get_userptr(struct device *dev, unsigned long vaddr, * No need to sync to the device, this will happen later when the * prepare() memop is called. */ - sgt->nents = dma_map_sg_attrs(buf->dev, sgt->sgl, sgt->orig_nents, - buf->dma_dir, DMA_ATTR_SKIP_CPU_SYNC); - if (!sgt->nents) + if (dma_map_sgtable(buf->dev, sgt, buf->dma_dir, + DMA_ATTR_SKIP_CPU_SYNC)) { ... and here. Robin. ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v6 35/36] videobuf2: use sgtable-based scatterlist wrappers
Hi Marek, I love your patch! Yet something to improve: [auto build test ERROR on next-20200618] [also build test ERROR on v5.8-rc1] [cannot apply to linuxtv-media/master staging/staging-testing drm-exynos/exynos-drm-next drm-intel/for-linux-next linus/master v5.8-rc1 v5.7 v5.7-rc7] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Marek-Szyprowski/DRM-fix-struct-sg_table-nents-vs-orig_nents-misuse/20200619-000417 base:ce2cc8efd7a40cbd17841add878cb691d0ce0bba config: alpha-allyesconfig (attached as .config) compiler: alpha-linux-gcc (GCC) 9.3.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=alpha If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All error/warnings (new ones prefixed by >>): drivers/media/common/videobuf2/videobuf2-dma-sg.c: In function 'vb2_dma_sg_alloc': >> drivers/media/common/videobuf2/videobuf2-dma-sg.c:173:13: error: invalid >> storage class for function 'vb2_dma_sg_put' 173 | static void vb2_dma_sg_put(void *buf_priv) | ^~ >> drivers/media/common/videobuf2/videobuf2-dma-sg.c:173:1: warning: ISO C90 >> forbids mixed declarations and code [-Wdeclaration-after-statement] 173 | static void vb2_dma_sg_put(void *buf_priv) | ^~ >> drivers/media/common/videobuf2/videobuf2-dma-sg.c:195:13: error: invalid >> storage class for function 'vb2_dma_sg_prepare' 195 | static void vb2_dma_sg_prepare(void *buf_priv) | ^~ >> drivers/media/common/videobuf2/videobuf2-dma-sg.c:207:13: error: invalid >> storage class for function 'vb2_dma_sg_finish' 207 | static void vb2_dma_sg_finish(void *buf_priv) | ^ >> drivers/media/common/videobuf2/videobuf2-dma-sg.c:219:14: error: invalid >> storage class for function 'vb2_dma_sg_get_userptr' 219 | static void *vb2_dma_sg_get_userptr(struct device *dev, unsigned long vaddr, | ^~ drivers/media/common/videobuf2/videobuf2-dma-sg.c: In function 'vb2_dma_sg_get_userptr': >> drivers/media/common/videobuf2/videobuf2-dma-sg.c:278:13: error: invalid >> storage class for function 'vb2_dma_sg_put_userptr' 278 | static void vb2_dma_sg_put_userptr(void *buf_priv) | ^~ drivers/media/common/videobuf2/videobuf2-dma-sg.c:278:1: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement] 278 | static void vb2_dma_sg_put_userptr(void *buf_priv) | ^~ >> drivers/media/common/videobuf2/videobuf2-dma-sg.c:298:14: error: invalid >> storage class for function 'vb2_dma_sg_vaddr' 298 | static void *vb2_dma_sg_vaddr(void *buf_priv) | ^~~~ >> drivers/media/common/videobuf2/videobuf2-dma-sg.c:315:21: error: invalid >> storage class for function 'vb2_dma_sg_num_users' 315 | static unsigned int vb2_dma_sg_num_users(void *buf_priv) | ^~~~ >> drivers/media/common/videobuf2/videobuf2-dma-sg.c:322:12: error: invalid >> storage class for function 'vb2_dma_sg_mmap' 322 | static int vb2_dma_sg_mmap(void *buf_priv, struct vm_area_struct *vma) |^~~ >> drivers/media/common/videobuf2/videobuf2-dma-sg.c:358:12: error: invalid >> storage class for function 'vb2_dma_sg_dmabuf_ops_attach' 358 | static int vb2_dma_sg_dmabuf_ops_attach(struct dma_buf *dbuf, |^~~~ >> drivers/media/common/videobuf2/videobuf2-dma-sg.c:396:13: error: invalid >> storage class for function 'vb2_dma_sg_dmabuf_ops_detach' 396 | static void vb2_dma_sg_dmabuf_ops_detach(struct dma_buf *dbuf, | ^~~~ drivers/media/common/videobuf2/videobuf2-dma-sg.c: In function 'vb2_dma_sg_dmabuf_ops_detach': >> drivers/media/common/videobuf2/videobuf2-dma-sg.c:409:3: error: too few >> arguments to function 'dma_unmap_sgtable' 409 | dma_unmap_sgtable(db_attach->dev, sgt, attach->dma_dir); | ^ In file included from include/linux/dma-buf.h:20, from include/media/videobuf2-core.h:18, from include/media/videobuf2-v4l2.h:16, from drivers/media/common/videobuf2/videobuf2-dma-sg.c:21: include/linux/dma-mapping.h:651:20: note: declared here 651 | static inline void dma_unmap_sgtable(struct device *dev, struct sg_table *sgt, |
[PATCH v6 35/36] videobuf2: use sgtable-based scatterlist wrappers
Use recently introduced common wrappers operating directly on the struct sg_table objects and scatterlist page iterators to make the code a bit more compact, robust, easier to follow and copy/paste safe. No functional change, because the code already properly did all the scaterlist related calls. Signed-off-by: Marek Szyprowski --- .../common/videobuf2/videobuf2-dma-contig.c | 41 --- .../media/common/videobuf2/videobuf2-dma-sg.c | 32 ++- .../common/videobuf2/videobuf2-vmalloc.c | 12 ++ 3 files changed, 34 insertions(+), 51 deletions(-) diff --git a/drivers/media/common/videobuf2/videobuf2-dma-contig.c b/drivers/media/common/videobuf2/videobuf2-dma-contig.c index f4b4a7c135eb..ba01a8692d88 100644 --- a/drivers/media/common/videobuf2/videobuf2-dma-contig.c +++ b/drivers/media/common/videobuf2/videobuf2-dma-contig.c @@ -48,16 +48,15 @@ struct vb2_dc_buf { static unsigned long vb2_dc_get_contiguous_size(struct sg_table *sgt) { - struct scatterlist *s; dma_addr_t expected = sg_dma_address(sgt->sgl); - unsigned int i; + struct sg_dma_page_iter dma_iter; unsigned long size = 0; - for_each_sg(sgt->sgl, s, sgt->nents, i) { - if (sg_dma_address(s) != expected) + for_each_sgtable_dma_page(sgt, _iter, 0) { + if (sg_page_iter_dma_address(_iter) != expected) break; - expected = sg_dma_address(s) + sg_dma_len(s); - size += sg_dma_len(s); + expected += PAGE_SIZE; + size += PAGE_SIZE; } return size; } @@ -99,8 +98,7 @@ static void vb2_dc_prepare(void *buf_priv) if (!sgt || buf->db_attach) return; - dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->orig_nents, - buf->dma_dir); + dma_sync_sgtable_for_device(buf->dev, sgt, buf->dma_dir); } static void vb2_dc_finish(void *buf_priv) @@ -112,7 +110,7 @@ static void vb2_dc_finish(void *buf_priv) if (!sgt || buf->db_attach) return; - dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir); + dma_sync_sgtable_for_cpu(buf->dev, sgt, buf->dma_dir); } /*/ @@ -273,8 +271,8 @@ static void vb2_dc_dmabuf_ops_detach(struct dma_buf *dbuf, * memory locations do not require any explicit cache * maintenance prior or after being used by the device. */ - dma_unmap_sg_attrs(db_attach->dev, sgt->sgl, sgt->orig_nents, - attach->dma_dir, DMA_ATTR_SKIP_CPU_SYNC); + dma_unmap_sgtable(db_attach->dev, sgt, attach->dma_dir, + DMA_ATTR_SKIP_CPU_SYNC); sg_free_table(sgt); kfree(attach); db_attach->priv = NULL; @@ -299,8 +297,8 @@ static struct sg_table *vb2_dc_dmabuf_ops_map( /* release any previous cache */ if (attach->dma_dir != DMA_NONE) { - dma_unmap_sg_attrs(db_attach->dev, sgt->sgl, sgt->orig_nents, - attach->dma_dir, DMA_ATTR_SKIP_CPU_SYNC); + dma_unmap_sgtable(db_attach->dev, sgt, attach->dma_dir, + DMA_ATTR_SKIP_CPU_SYNC); attach->dma_dir = DMA_NONE; } @@ -308,9 +306,8 @@ static struct sg_table *vb2_dc_dmabuf_ops_map( * mapping to the client with new direction, no cache sync * required see comment in vb2_dc_dmabuf_ops_detach() */ - sgt->nents = dma_map_sg_attrs(db_attach->dev, sgt->sgl, sgt->orig_nents, - dma_dir, DMA_ATTR_SKIP_CPU_SYNC); - if (!sgt->nents) { + if (dma_map_sgtable(db_attach->dev, sgt, dma_dir, + DMA_ATTR_SKIP_CPU_SYNC)) { pr_err("failed to map scatterlist\n"); mutex_unlock(lock); return ERR_PTR(-EIO); @@ -423,8 +420,8 @@ static void vb2_dc_put_userptr(void *buf_priv) * No need to sync to CPU, it's already synced to the CPU * since the finish() memop will have been called before this. */ - dma_unmap_sg_attrs(buf->dev, sgt->sgl, sgt->orig_nents, - buf->dma_dir, DMA_ATTR_SKIP_CPU_SYNC); + dma_unmap_sgtable(buf->dev, sgt, buf->dma_dir, + DMA_ATTR_SKIP_CPU_SYNC); pages = frame_vector_pages(buf->vec); /* sgt should exist only if vector contains pages... */ BUG_ON(IS_ERR(pages)); @@ -521,9 +518,8 @@ static void *vb2_dc_get_userptr(struct device *dev, unsigned long vaddr, * No need to sync to the device, this will happen later when the * prepare() memop is called. */ - sgt->nents = dma_map_sg_attrs(buf->dev, sgt->sgl,