Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753504AbdHUMVu (ORCPT ); Mon, 21 Aug 2017 08:21:50 -0400 Received: from mailout1.w1.samsung.com ([210.118.77.11]:37460 "EHLO mailout1.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752695AbdHUMVq (ORCPT ); Mon, 21 Aug 2017 08:21:46 -0400 X-AuditID: cbfec7f1-f793a6d00000326b-58-599ad0563fd5 Subject: Re: [PATCH 1/7 v3] media: vb2: add bidirectional flag in vb2_queue To: Stanimir Varbanov , Mauro Carvalho Chehab , Hans Verkuil Cc: Pawel Osciak , Kyungmin Park , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org From: Marek Szyprowski Message-id: <9757cfb2-66b3-7c8e-bb60-25b14706fbe9@samsung.com> Date: Mon, 21 Aug 2017 14:21:40 +0200 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.2.1 MIME-version: 1.0 In-reply-to: <20170821113410.17542-1-stanimir.varbanov@linaro.org> Content-type: text/plain; charset="utf-8"; format="flowed" Content-transfer-encoding: 7bit Content-language: en-US X-Brightmail-Tracker: H4sIAAAAAAAAA02SeUgUYRjG+XZmZ8fNlWm9XjTLNoQy8iilQVNLIgai849QE2zRYbW82PHs j/Bajy1SV0NdsgRTUpRqNVFR1PXYMm8tsESrRSVJzKzMoy3XMfC/3/c9D8/7Ph8fiUkbhA5k VGwCq4yVR8sIMd7UtzZ87NqINtijPfsI3V80J6AHM76K6MKOQRE93vqQoO89fymkq3WbArp4 cU1EZ2X3CE6TjK42j2Cm3rURjHH9C8Hcb6xFzIpuP9P/c0V0mQgRn4pgo6OSWKW7/w1x5Pz4 Koqfv5SinixHaWgjQI1IEigvKF9yVyOLLbSDkelnhBqJSSlVhaD3bcfOYQWBsaYc8S4v6HqU i/FCNYIPTz5iZkFKzSP4u3bHzNbUeXgx24ubTTaUCsFy1eh2FEbVISjQbArMLoLyBPWimjCz hPKHsR9PRWbGKRcofbyyPc6WCoXyiiwR79kLv4umcTNbUIGQ3l65zRjlA3MmlZDnA9BQt4jx bA+ZqsntLYDqE0HT9BjOl3YCXSfG1zkL+YW6HbaGBUOjiOd9MF50F+c5H0GG6ijPpQiGFiU8 +0K3YXRnrhVomkowPl4CudlS3sJA3fqfnfgzoK8vFPAvN4BgY2gBL0DO2l3VtLvqaHfV0e6q U4HwWmTDJnIxCpY77sbJY7jEWIVbeFyMDm19pTcmw3IzWnrlo0cUiWSWEg+lNlgqlCdxqTF6 BCQms5F0tW1dSSLkqbdZZVyYMjGa5fTIkcRl9hK/kOxgKaWQJ7C3WDaeVf5XBaSFQxrKzLn4 bUYPOkd3TfH11mTFhKo5UHJhIWg47H2Z0rume8/Nw36FsQd/2Va+1rom5Vh1WvoG9ZTSBVdn XcoCTqSkt3trjN/z49XJdrYT3IxzlCnYimmpD9U0LzXrA7IMJeFTkw2HxJ8HjCc/PfBeDTto slluDxA6WTAturyRK+dwGc5Fyj1dMSUn/wfe739oRgMAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrGIsWRmVeSWpSXmKPExsVy+t/xq7phF2ZFGqw8zm5xavIzJouzTW/Y LSbuP8tucXnXHDaLng1bWS2WbfrDZDHl7U92i5a2I0wOHB6bVnWyedy5tofN4/Gvl2wefVtW MXp83iTncerrZ/YAtig3m4zUxJTUIoXUvOT8lMy8dFul0BA3XQslhbzE3FRbpQhd35AgJYWy xJxSIM/IAA04OAe4Byvp2yW4ZTy//J2x4Ll/RdfNuYwNjL/tuxg5OSQETCQOzutghrDFJC7c W8/WxcjFISSwhFHi6L+bjBDOc0aJyfPPMIJUCQt4S2x8epQFJCEi0Moo0bXlBVgVs8AaRom7 zx4wQ7ScYZRYtOY8O0gLm4ChRNfbLjYQm1fATuLSlxVgcRYBVYkZ8z+DjRUViJG4NvMOK0SN oMSPyfdYQGxOASeJxr2LwWxmATOJLy8Ps0LY8hKb17xlhrDFJZpbb7JMYBSchaR9FpKWWUha ZiFpWcDIsopRJLW0ODc9t9hIrzgxt7g0L10vOT93EyMwTrcd+7llB2PXu+BDjAIcjEo8vDfy Z0UKsSaWFVfmHmKU4GBWEuE9uAcoxJuSWFmVWpQfX1Sak1p8iNEU6LmJzFKiyfnAFJJXEm9o YmhuaWhkbGFhbmSkJM6rfrkpUkggPbEkNTs1tSC1CKaPiYNTqoFx8ZdsRY8cuR0fdzezPlvh +4pRyOq3gI9tc9Ia22WTtQQXtMoKfKvY0vXKKUXxkfhP9j+Hg7nfvs2w2r1nysSd6/Z+miL3 e9b2gNa+7MZKlulzTZbefpbJPYVnT8EuuaLKTVKC+lcjk9b+9VvWLfb3VGjKnFWO09eu1Zi0 tPX6xWWzI59ExbyMUGIpzkg01GIuKk4EAGMXx9LpAgAA X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20170821122142eucas1p1f1b2bbcc2bf7c588ecf7395e129544d0 X-Msg-Generator: CA X-Sender-IP: 182.198.249.180 X-Local-Sender: =?UTF-8?B?TWFyZWsgU3p5cHJvd3NraRtTUlBPTC1LZXJuZWwgKFRQKRs=?= =?UTF-8?B?7IK87ISx7KCE7J6QG1NlbmlvciBTb2Z0d2FyZSBFbmdpbmVlcg==?= X-Global-Sender: =?UTF-8?B?TWFyZWsgU3p5cHJvd3NraRtTUlBPTC1LZXJuZWwgKFRQKRtT?= =?UTF-8?B?YW1zdW5nIEVsZWN0cm9uaWNzG1NlbmlvciBTb2Z0d2FyZSBFbmdpbmVlcg==?= X-Sender-Code: =?UTF-8?B?QzEwG0VIURtDMTBDRDAyQ0QwMjczOTI=?= CMS-TYPE: 201P X-CMS-RootMailID: 20170821113451epcas5p14ba601f0848c8198c269f8da53129595 X-RootMTR: 20170821113451epcas5p14ba601f0848c8198c269f8da53129595 References: <20170818141606.4835-2-stanimir.varbanov@linaro.org> <20170821113410.17542-1-stanimir.varbanov@linaro.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 9986 Lines: 227 Hi Stanimir, On 2017-08-21 13:34, Stanimir Varbanov wrote: > This change is intended to give to the v4l2 drivers a choice to > change the default behavior of the v4l2-core DMA mapping direction > from DMA_TO/FROM_DEVICE (depending on the buffer type CAPTURE or > OUTPUT) to DMA_BIDIRECTIONAL during queue_init time. > > Initially the issue with DMA mapping direction has been found in > Venus encoder driver where the hardware (firmware side) adds few > lines padding on bottom of the image buffer, and the consequence > is triggering of IOMMU protection faults. > > This will help supporting venus encoder (and probably other drivers > in the future) which wants to map output type of buffers as > read/write. > > Signed-off-by: Stanimir Varbanov Thanks for the patch. Acked-by: Marek Szyprowski While touching this, I would love to unify set_page_dirty_lock() related code in videobuf2-dc, videobuf2-sg and videobuf2-vmalloc. IMHO the pattern used in videobuf2-vmalloc should be copied to videobuf2-sg (currently checks for dma_dir for every single page) and videobuf2-dc (currently it lacks any checks and calls set_page_dirty_lock() unconditionally). If you have a little bit of spare time, please prepare a separate patch for the above mentioned fix. > --- > v3: update V4L2 dma-sg/contig and vmalloc memory type ops with a > check for DMA_BIDIRECTIONAL. > v2: move dma_dir into private section. > > drivers/media/v4l2-core/videobuf2-core.c | 17 ++++++++--------- > drivers/media/v4l2-core/videobuf2-dma-contig.c | 3 ++- > drivers/media/v4l2-core/videobuf2-dma-sg.c | 6 ++++-- > drivers/media/v4l2-core/videobuf2-vmalloc.c | 6 ++++-- > include/media/videobuf2-core.h | 13 +++++++++++++ > 5 files changed, 31 insertions(+), 14 deletions(-) > > diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c > index 0924594989b4..cb115ba6a1d2 100644 > --- a/drivers/media/v4l2-core/videobuf2-core.c > +++ b/drivers/media/v4l2-core/videobuf2-core.c > @@ -194,8 +194,6 @@ static void __enqueue_in_driver(struct vb2_buffer *vb); > static int __vb2_buf_mem_alloc(struct vb2_buffer *vb) > { > struct vb2_queue *q = vb->vb2_queue; > - enum dma_data_direction dma_dir = > - q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE; > void *mem_priv; > int plane; > int ret = -ENOMEM; > @@ -209,7 +207,7 @@ static int __vb2_buf_mem_alloc(struct vb2_buffer *vb) > > mem_priv = call_ptr_memop(vb, alloc, > q->alloc_devs[plane] ? : q->dev, > - q->dma_attrs, size, dma_dir, q->gfp_flags); > + q->dma_attrs, size, q->dma_dir, q->gfp_flags); > if (IS_ERR_OR_NULL(mem_priv)) { > if (mem_priv) > ret = PTR_ERR(mem_priv); > @@ -978,8 +976,6 @@ static int __prepare_userptr(struct vb2_buffer *vb, const void *pb) > void *mem_priv; > unsigned int plane; > int ret = 0; > - enum dma_data_direction dma_dir = > - q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE; > bool reacquired = vb->planes[0].mem_priv == NULL; > > memset(planes, 0, sizeof(planes[0]) * vb->num_planes); > @@ -1030,7 +1026,7 @@ static int __prepare_userptr(struct vb2_buffer *vb, const void *pb) > mem_priv = call_ptr_memop(vb, get_userptr, > q->alloc_devs[plane] ? : q->dev, > planes[plane].m.userptr, > - planes[plane].length, dma_dir); > + planes[plane].length, q->dma_dir); > if (IS_ERR(mem_priv)) { > dprintk(1, "failed acquiring userspace memory for plane %d\n", > plane); > @@ -1096,8 +1092,6 @@ static int __prepare_dmabuf(struct vb2_buffer *vb, const void *pb) > void *mem_priv; > unsigned int plane; > int ret = 0; > - enum dma_data_direction dma_dir = > - q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE; > bool reacquired = vb->planes[0].mem_priv == NULL; > > memset(planes, 0, sizeof(planes[0]) * vb->num_planes); > @@ -1156,7 +1150,7 @@ static int __prepare_dmabuf(struct vb2_buffer *vb, const void *pb) > /* Acquire each plane's memory */ > mem_priv = call_ptr_memop(vb, attach_dmabuf, > q->alloc_devs[plane] ? : q->dev, > - dbuf, planes[plane].length, dma_dir); > + dbuf, planes[plane].length, q->dma_dir); > if (IS_ERR(mem_priv)) { > dprintk(1, "failed to attach dmabuf\n"); > ret = PTR_ERR(mem_priv); > @@ -2003,6 +1997,11 @@ int vb2_core_queue_init(struct vb2_queue *q) > if (q->buf_struct_size == 0) > q->buf_struct_size = sizeof(struct vb2_buffer); > > + if (q->bidirectional) > + q->dma_dir = DMA_BIDIRECTIONAL; > + else > + q->dma_dir = q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE; > + > return 0; > } > EXPORT_SYMBOL_GPL(vb2_core_queue_init); > diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/v4l2-core/videobuf2-dma-contig.c > index 5b90a66b9e78..9f389f36566d 100644 > --- a/drivers/media/v4l2-core/videobuf2-dma-contig.c > +++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c > @@ -508,7 +508,8 @@ static void *vb2_dc_get_userptr(struct device *dev, unsigned long vaddr, > buf->dma_dir = dma_dir; > > offset = vaddr & ~PAGE_MASK; > - vec = vb2_create_framevec(vaddr, size, dma_dir == DMA_FROM_DEVICE); > + vec = vb2_create_framevec(vaddr, size, dma_dir == DMA_FROM_DEVICE || > + dma_dir == DMA_BIDIRECTIONAL); > if (IS_ERR(vec)) { > ret = PTR_ERR(vec); > goto fail_buf; > diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c b/drivers/media/v4l2-core/videobuf2-dma-sg.c > index 54f33938d45b..6808231a6bdc 100644 > --- a/drivers/media/v4l2-core/videobuf2-dma-sg.c > +++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c > @@ -239,7 +239,8 @@ static void *vb2_dma_sg_get_userptr(struct device *dev, unsigned long vaddr, > buf->offset = vaddr & ~PAGE_MASK; > buf->size = size; > buf->dma_sgt = &buf->sg_table; > - vec = vb2_create_framevec(vaddr, size, buf->dma_dir == DMA_FROM_DEVICE); > + vec = vb2_create_framevec(vaddr, size, dma_dir == DMA_FROM_DEVICE || > + dma_dir == DMA_BIDIRECTIONAL); > if (IS_ERR(vec)) > goto userptr_fail_pfnvec; > buf->vec = vec; > @@ -292,7 +293,8 @@ static void vb2_dma_sg_put_userptr(void *buf_priv) > vm_unmap_ram(buf->vaddr, buf->num_pages); > sg_free_table(buf->dma_sgt); > while (--i >= 0) { > - if (buf->dma_dir == DMA_FROM_DEVICE) > + if (buf->dma_dir == DMA_FROM_DEVICE || > + buf->dma_dir == DMA_BIDIRECTIONAL) > set_page_dirty_lock(buf->pages[i]); > } > vb2_destroy_framevec(buf->vec); > diff --git a/drivers/media/v4l2-core/videobuf2-vmalloc.c b/drivers/media/v4l2-core/videobuf2-vmalloc.c > index 6bc130fe84f6..3a7c80cd1a17 100644 > --- a/drivers/media/v4l2-core/videobuf2-vmalloc.c > +++ b/drivers/media/v4l2-core/videobuf2-vmalloc.c > @@ -87,7 +87,8 @@ static void *vb2_vmalloc_get_userptr(struct device *dev, unsigned long vaddr, > buf->dma_dir = dma_dir; > offset = vaddr & ~PAGE_MASK; > buf->size = size; > - vec = vb2_create_framevec(vaddr, size, dma_dir == DMA_FROM_DEVICE); > + vec = vb2_create_framevec(vaddr, size, dma_dir == DMA_FROM_DEVICE || > + dma_dir == DMA_BIDIRECTIONAL); > if (IS_ERR(vec)) { > ret = PTR_ERR(vec); > goto fail_pfnvec_create; > @@ -137,7 +138,8 @@ static void vb2_vmalloc_put_userptr(void *buf_priv) > pages = frame_vector_pages(buf->vec); > if (vaddr) > vm_unmap_ram((void *)vaddr, n_pages); > - if (buf->dma_dir == DMA_FROM_DEVICE) > + if (buf->dma_dir == DMA_FROM_DEVICE || > + buf->dma_dir == DMA_BIDIRECTIONAL) > for (i = 0; i < n_pages; i++) > set_page_dirty_lock(pages[i]); > } else { > diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h > index cb97c224be73..ef9b64398c8c 100644 > --- a/include/media/videobuf2-core.h > +++ b/include/media/videobuf2-core.h > @@ -427,6 +427,16 @@ struct vb2_buf_ops { > * @dev: device to use for the default allocation context if the driver > * doesn't fill in the @alloc_devs array. > * @dma_attrs: DMA attributes to use for the DMA. > + * @bidirectional: when this flag is set the DMA direction for the buffers of > + * this queue will be overridden with DMA_BIDIRECTIONAL direction. > + * This is useful in cases where the hardware (firmware) writes to > + * a buffer which is mapped as read (DMA_TO_DEVICE), or reads from > + * buffer which is mapped for write (DMA_FROM_DEVICE) in order > + * to satisfy some internal hardware restrictions or adds a padding > + * needed by the processing algorithm. In case the DMA mapping is > + * not bidirectional but the hardware (firmware) trying to access > + * the buffer (in the opposite direction) this could lead to an > + * IOMMU protection faults. > * @fileio_read_once: report EOF after reading the first buffer > * @fileio_write_immediately: queue buffer after each write() call > * @allow_zero_bytesused: allow bytesused == 0 to be passed to the driver > @@ -465,6 +475,7 @@ struct vb2_buf_ops { > * Private elements (won't appear at the uAPI book): > * @mmap_lock: private mutex used when buffers are allocated/freed/mmapped > * @memory: current memory type used > + * @dma_dir: DMA mapping direction. > * @bufs: videobuf buffer structures > * @num_buffers: number of allocated/used buffers > * @queued_list: list of buffers currently queued from userspace > @@ -495,6 +506,7 @@ struct vb2_queue { > unsigned int io_modes; > struct device *dev; > unsigned long dma_attrs; > + unsigned bidirectional:1; > unsigned fileio_read_once:1; > unsigned fileio_write_immediately:1; > unsigned allow_zero_bytesused:1; > @@ -516,6 +528,7 @@ struct vb2_queue { > /* private: internal use only */ > struct mutex mmap_lock; > unsigned int memory; > + enum dma_data_direction dma_dir; > struct vb2_buffer *bufs[VB2_MAX_FRAME]; > unsigned int num_buffers; > Best regards -- Marek Szyprowski, PhD Samsung R&D Institute Poland