From patchwork Thu Aug 24 09:21:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Gaignard X-Patchwork-Id: 716741 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 51574EE49A5 for ; Thu, 24 Aug 2023 09:22:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240688AbjHXJVx (ORCPT ); Thu, 24 Aug 2023 05:21:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57300 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235850AbjHXJVq (ORCPT ); Thu, 24 Aug 2023 05:21:46 -0400 Received: from madras.collabora.co.uk (madras.collabora.co.uk [46.235.227.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6303FE67; Thu, 24 Aug 2023 02:21:44 -0700 (PDT) Received: from benjamin-XPS-13-9310.. (unknown [IPv6:2a01:e0a:120:3210:672:c310:4c8a:3a97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: benjamin.gaignard) by madras.collabora.co.uk (Postfix) with ESMTPSA id 212A2660726A; Thu, 24 Aug 2023 10:21:42 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1692868902; bh=cn8IhtAp7t/KmadvHHA388VFOzyoMeHQwyTqRoV/2lA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NLkGbF95bKcuL65/8uVA9VQvwHahygMS28IywoUqfH1UxvGLsDpMUOkUh6LE9pT/N nrwyK2bx/d++LRCJ84DbsJzolb2pTfpQzigx0dqWD+qF1NPsctWQB1BBSzTcNLACCI /Fc8lHDDRNtvp095Dt8F6u9fCN8ar4m7KQePKzM/b8PuMhhwbZdvfHMc+BKPg3KSNq +agwmyVBnMXqZLG7kkfTIvLNVIUzeyDQPe7H+c5UU7nKprBxxTl8Trq7FNr2QvHOc3 +5p2RASI/s8THaLMfaFRjTbhRAtBg+pf5n+ErJO6wHcajmBL6m+z7l/7gvne5klc74 4xCkDPuQUnbnA== From: Benjamin Gaignard To: mchehab@kernel.org, tfiga@chromium.org, m.szyprowski@samsung.com, ming.qian@nxp.com, ezequiel@vanguardiasur.com.ar, p.zabel@pengutronix.de, gregkh@linuxfoundation.org, hverkuil-cisco@xs4all.nl, nicolas.dufresne@collabora.com Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-arm-msm@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-staging@lists.linux.dev, kernel@collabora.com, Benjamin Gaignard Subject: [PATCH v5 01/10] media: videobuf2: Rework offset 'cookie' encoding pattern Date: Thu, 24 Aug 2023 11:21:24 +0200 Message-Id: <20230824092133.39510-2-benjamin.gaignard@collabora.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230824092133.39510-1-benjamin.gaignard@collabora.com> References: <20230824092133.39510-1-benjamin.gaignard@collabora.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Change how offset 'cookie' field value is computed to make possible to use more buffers (up to 0xffff). With this encoding pattern we know the maximum number that a queue could store so we can check ing at queue init time. It also make easier and faster to find buffer and plane from using the offset field. Signed-off-by: Benjamin Gaignard --- v5: - I haven't change DST_QUEUE_OFF_BASE definition because it used in v4l2-mem2mem and s5p_mfc driver with a shift. .../media/common/videobuf2/videobuf2-core.c | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c index cf6727d9c81f..e06905533ef4 100644 --- a/drivers/media/common/videobuf2/videobuf2-core.c +++ b/drivers/media/common/videobuf2/videobuf2-core.c @@ -31,6 +31,10 @@ #include +#define PLANE_INDEX_SHIFT 3 +#define PLANE_INDEX_MASK 0x7 +#define MAX_BUFFERS 0xffff + static int debug; module_param(debug, int, 0644); @@ -358,21 +362,23 @@ static void __setup_offsets(struct vb2_buffer *vb) unsigned int plane; unsigned long off = 0; - if (vb->index) { - struct vb2_buffer *prev = q->bufs[vb->index - 1]; - struct vb2_plane *p = &prev->planes[prev->num_planes - 1]; - - off = PAGE_ALIGN(p->m.offset + p->length); - } + /* + * Offsets cookies value have the following constraints: + * - a buffer could have up to 8 planes. + * - v4l2 mem2mem use bit 30 to distinguish between source and destination buffers. + * - must be page aligned + * That led to this bit mapping: + * |30 |29 15|14 12|11 0| + * |DST_QUEUE_OFF_BASE|buffer index|plane index| 0 | + * where there is 16 bits to store buffer index. + */ + off = vb->index << (PLANE_INDEX_SHIFT + PAGE_SHIFT); for (plane = 0; plane < vb->num_planes; ++plane) { - vb->planes[plane].m.offset = off; + vb->planes[plane].m.offset = off + (plane << PAGE_SHIFT); dprintk(q, 3, "buffer %d, plane %d offset 0x%08lx\n", vb->index, plane, off); - - off += vb->planes[plane].length; - off = PAGE_ALIGN(off); } } @@ -2209,21 +2215,15 @@ static int __find_plane_by_offset(struct vb2_queue *q, unsigned long off, return -EBUSY; } - /* - * Go over all buffers and their planes, comparing the given offset - * with an offset assigned to each plane. If a match is found, - * return its buffer and plane numbers. - */ - for (buffer = 0; buffer < q->num_buffers; ++buffer) { - vb = q->bufs[buffer]; + /* Get buffer and plane from the offset */ + buffer = (off >> (PLANE_INDEX_SHIFT + PAGE_SHIFT)) & MAX_BUFFERS; + plane = (off >> PAGE_SHIFT) & PLANE_INDEX_MASK; - for (plane = 0; plane < vb->num_planes; ++plane) { - if (vb->planes[plane].m.offset == off) { - *_buffer = buffer; - *_plane = plane; - return 0; - } - } + vb = q->bufs[buffer]; + if (vb->planes[plane].m.offset == off) { + *_buffer = buffer; + *_plane = plane; + return 0; } return -EINVAL; From patchwork Thu Aug 24 09:21:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Gaignard X-Patchwork-Id: 716740 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 60F75EE49AB for ; Thu, 24 Aug 2023 09:22:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240694AbjHXJVy (ORCPT ); Thu, 24 Aug 2023 05:21:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57334 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240708AbjHXJVs (ORCPT ); Thu, 24 Aug 2023 05:21:48 -0400 Received: from madras.collabora.co.uk (madras.collabora.co.uk [46.235.227.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 63EFF172D; Thu, 24 Aug 2023 02:21:44 -0700 (PDT) Received: from benjamin-XPS-13-9310.. (unknown [IPv6:2a01:e0a:120:3210:672:c310:4c8a:3a97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: benjamin.gaignard) by madras.collabora.co.uk (Postfix) with ESMTPSA id A9032660727D; Thu, 24 Aug 2023 10:21:42 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1692868903; bh=bUvpfgtRxG1LItjFj4GDb1Q2kGtqKyNzaGH/3Tpnx6M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bS1ud3gV9oi3vyYdDksifkjX2EU4eHvEiwBjslN0eQsfyapB0TgxmLmSv5NyaPmGq 7km0yMUGRMcQdrqjZ/3fRxmYBv6bJ2U1UskaUY0C9cjGTuZ7evWmmYPqK/RtXyjocl GPmQDUVQ/LKLQkdeFPmhkKrtTWDzrv4a7zoKMD0eP6VYfGDygOcIjKU6N8cfMczZ7s sqL0JHY5N/wiupWbuZEBkZen/d3W0jwq4C2qy/Bj4an1uQWfyZIzR9skSFV39U/nhE i9r+N6MD49yUFtRn4bm0k2/jFbYvh8I8qFTV4TMEAQuB8udiDBg+OfGI2g0ufgGHlG tl6zfPf6PhpSg== From: Benjamin Gaignard To: mchehab@kernel.org, tfiga@chromium.org, m.szyprowski@samsung.com, ming.qian@nxp.com, ezequiel@vanguardiasur.com.ar, p.zabel@pengutronix.de, gregkh@linuxfoundation.org, hverkuil-cisco@xs4all.nl, nicolas.dufresne@collabora.com Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-arm-msm@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-staging@lists.linux.dev, kernel@collabora.com, Benjamin Gaignard Subject: [PATCH v5 02/10] media: videobuf2: Access vb2_queue bufs array through helper functions Date: Thu, 24 Aug 2023 11:21:25 +0200 Message-Id: <20230824092133.39510-3-benjamin.gaignard@collabora.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230824092133.39510-1-benjamin.gaignard@collabora.com> References: <20230824092133.39510-1-benjamin.gaignard@collabora.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org The first step before changing how vb2 buffers are stored into queue is to avoid direct access to bufs arrays. This patch adds 2 helpers functions to add and remove vb2 buffers from a queue. With these 2 and vb2_get_buffer(), bufs field of struct vb2_queue becomes like a private member of the structure. After each call to vb2_get_buffer() we need to be sure that we get a valid pointer so check the return value of all of them. Signed-off-by: Benjamin Gaignard # Conflicts: # drivers/media/common/videobuf2/videobuf2-core.c --- .../media/common/videobuf2/videobuf2-core.c | 203 ++++++++++++++---- .../media/common/videobuf2/videobuf2-v4l2.c | 28 ++- drivers/media/platform/amphion/vpu_dbg.c | 22 +- .../platform/mediatek/jpeg/mtk_jpeg_core.c | 6 +- .../vcodec/decoder/vdec/vdec_vp9_req_lat_if.c | 2 +- drivers/media/platform/st/sti/hva/hva-v4l2.c | 4 + drivers/media/test-drivers/visl/visl-dec.c | 28 ++- .../staging/media/atomisp/pci/atomisp_ioctl.c | 2 +- 8 files changed, 230 insertions(+), 65 deletions(-) diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c index e06905533ef4..8aa13591b782 100644 --- a/drivers/media/common/videobuf2/videobuf2-core.c +++ b/drivers/media/common/videobuf2/videobuf2-core.c @@ -403,6 +403,37 @@ static void init_buffer_cache_hints(struct vb2_queue *q, struct vb2_buffer *vb) vb->skip_cache_sync_on_finish = 1; } +/** + * vb2_queue_add_buffer() - add a buffer to a queue + * @q: pointer to &struct vb2_queue with videobuf2 queue. + * @vb: pointer to &struct vb2_buffer to be added to the queue. + * @index: index where add vb2_buffer in the queue + */ +static bool vb2_queue_add_buffer(struct vb2_queue *q, struct vb2_buffer *vb, int index) +{ + if (index < VB2_MAX_FRAME && !q->bufs[index]) { + q->bufs[index] = vb; + vb->index = index; + vb->vb2_queue = q; + return true; + } + + return false; +} + +/** + * vb2_queue_remove_buffer() - remove a buffer from a queue + * @q: pointer to &struct vb2_queue with videobuf2 queue. + * @vb: pointer to &struct vb2_buffer to be removed from the queue. + */ +static void vb2_queue_remove_buffer(struct vb2_queue *q, struct vb2_buffer *vb) +{ + if (vb->index < VB2_MAX_FRAME) { + q->bufs[vb->index] = NULL; + vb->vb2_queue = NULL; + } +} + /* * __vb2_queue_alloc() - allocate vb2 buffer structures and (for MMAP type) * video buffer memory for all buffers/planes on the queue and initializes the @@ -431,9 +462,7 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum vb2_memory memory, } vb->state = VB2_BUF_STATE_DEQUEUED; - vb->vb2_queue = q; vb->num_planes = num_planes; - vb->index = q->num_buffers + buffer; vb->type = q->type; vb->memory = memory; init_buffer_cache_hints(q, vb); @@ -443,7 +472,11 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum vb2_memory memory, } call_void_bufop(q, init_buffer, vb); - q->bufs[vb->index] = vb; + if (!vb2_queue_add_buffer(q, vb, q->num_buffers + buffer)) { + dprintk(q, 1, "failed adding buffer %d to queue\n", buffer); + kfree(vb); + break; + } /* Allocate video buffer memory for the MMAP type */ if (memory == VB2_MEMORY_MMAP) { @@ -451,7 +484,7 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum vb2_memory memory, if (ret) { dprintk(q, 1, "failed allocating memory for buffer %d\n", buffer); - q->bufs[vb->index] = NULL; + vb2_queue_remove_buffer(q, vb); kfree(vb); break; } @@ -466,7 +499,7 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum vb2_memory memory, dprintk(q, 1, "buffer %d %p initialization failed\n", buffer, vb); __vb2_buf_mem_free(vb); - q->bufs[vb->index] = NULL; + vb2_queue_remove_buffer(q, vb); kfree(vb); break; } @@ -489,7 +522,7 @@ static void __vb2_free_mem(struct vb2_queue *q, unsigned int buffers) for (buffer = q->num_buffers - buffers; buffer < q->num_buffers; ++buffer) { - vb = q->bufs[buffer]; + vb = vb2_get_buffer(q, buffer); if (!vb) continue; @@ -517,7 +550,7 @@ static void __vb2_queue_free(struct vb2_queue *q, unsigned int buffers) /* Call driver-provided cleanup function for each buffer, if provided */ for (buffer = q->num_buffers - buffers; buffer < q->num_buffers; ++buffer) { - struct vb2_buffer *vb = q->bufs[buffer]; + struct vb2_buffer *vb = vb2_get_buffer(q, buffer); if (vb && vb->planes[0].mem_priv) call_void_vb_qop(vb, buf_cleanup, vb); @@ -557,15 +590,20 @@ static void __vb2_queue_free(struct vb2_queue *q, unsigned int buffers) q->cnt_unprepare_streaming = 0; } for (buffer = 0; buffer < q->num_buffers; ++buffer) { - struct vb2_buffer *vb = q->bufs[buffer]; - bool unbalanced = vb->cnt_mem_alloc != vb->cnt_mem_put || - vb->cnt_mem_prepare != vb->cnt_mem_finish || - vb->cnt_mem_get_userptr != vb->cnt_mem_put_userptr || - vb->cnt_mem_attach_dmabuf != vb->cnt_mem_detach_dmabuf || - vb->cnt_mem_map_dmabuf != vb->cnt_mem_unmap_dmabuf || - vb->cnt_buf_queue != vb->cnt_buf_done || - vb->cnt_buf_prepare != vb->cnt_buf_finish || - vb->cnt_buf_init != vb->cnt_buf_cleanup; + struct vb2_buffer *vb = vb2_get_buffer(q, buffer); + bool unbalanced; + + if (!vb) + continue; + + unbalanced = vb->cnt_mem_alloc != vb->cnt_mem_put || + vb->cnt_mem_prepare != vb->cnt_mem_finish || + vb->cnt_mem_get_userptr != vb->cnt_mem_put_userptr || + vb->cnt_mem_attach_dmabuf != vb->cnt_mem_detach_dmabuf || + vb->cnt_mem_map_dmabuf != vb->cnt_mem_unmap_dmabuf || + vb->cnt_buf_queue != vb->cnt_buf_done || + vb->cnt_buf_prepare != vb->cnt_buf_finish || + vb->cnt_buf_init != vb->cnt_buf_cleanup; if (unbalanced || debug) { pr_info(" counters for queue %p, buffer %d:%s\n", @@ -597,8 +635,13 @@ static void __vb2_queue_free(struct vb2_queue *q, unsigned int buffers) /* Free vb2 buffers */ for (buffer = q->num_buffers - buffers; buffer < q->num_buffers; ++buffer) { - kfree(q->bufs[buffer]); - q->bufs[buffer] = NULL; + struct vb2_buffer *vb = vb2_get_buffer(q, buffer); + + if (!vb) + continue; + + vb2_queue_remove_buffer(q, vb); + kfree(vb); } q->num_buffers -= buffers; @@ -634,7 +677,12 @@ static bool __buffers_in_use(struct vb2_queue *q) { unsigned int buffer; for (buffer = 0; buffer < q->num_buffers; ++buffer) { - if (vb2_buffer_in_use(q, q->bufs[buffer])) + struct vb2_buffer *vb = vb2_get_buffer(q, buffer); + + if (!vb) + continue; + + if (vb2_buffer_in_use(q, vb)) return true; } return false; @@ -642,7 +690,10 @@ static bool __buffers_in_use(struct vb2_queue *q) void vb2_core_querybuf(struct vb2_queue *q, unsigned int index, void *pb) { - call_void_bufop(q, fill_user_buffer, q->bufs[index], pb); + struct vb2_buffer *vb = vb2_get_buffer(q, index); + + if (vb) + call_void_bufop(q, fill_user_buffer, vb, pb); } EXPORT_SYMBOL_GPL(vb2_core_querybuf); @@ -1553,7 +1604,13 @@ int vb2_core_prepare_buf(struct vb2_queue *q, unsigned int index, void *pb) struct vb2_buffer *vb; int ret; - vb = q->bufs[index]; + vb = vb2_get_buffer(q, index); + + if (!vb) { + dprintk(q, 1, "can't find the requested buffer\n"); + return -EINVAL; + } + if (vb->state != VB2_BUF_STATE_DEQUEUED) { dprintk(q, 1, "invalid buffer state %s\n", vb2_state_name(vb->state)); @@ -1624,7 +1681,11 @@ static int vb2_start_streaming(struct vb2_queue *q) * correctly return them to vb2. */ for (i = 0; i < q->num_buffers; ++i) { - vb = q->bufs[i]; + vb = vb2_get_buffer(q, i); + + if (!vb) + continue; + if (vb->state == VB2_BUF_STATE_ACTIVE) vb2_buffer_done(vb, VB2_BUF_STATE_QUEUED); } @@ -1652,7 +1713,12 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb, return -EIO; } - vb = q->bufs[index]; + vb = vb2_get_buffer(q, index); + + if (!vb) { + dprintk(q, 1, "can't find the requested buffer\n"); + return -EINVAL; + } if (!req && vb->state != VB2_BUF_STATE_IN_REQUEST && q->requires_requests) { @@ -2028,12 +2094,18 @@ static void __vb2_queue_cancel(struct vb2_queue *q) * to vb2 in stop_streaming(). */ if (WARN_ON(atomic_read(&q->owned_by_drv_count))) { - for (i = 0; i < q->num_buffers; ++i) - if (q->bufs[i]->state == VB2_BUF_STATE_ACTIVE) { + for (i = 0; i < q->num_buffers; ++i) { + struct vb2_buffer *vb = vb2_get_buffer(q, i); + + if (!vb) + continue; + + if (vb->state == VB2_BUF_STATE_ACTIVE) { pr_warn("driver bug: stop_streaming operation is leaving buf %p in active state\n", - q->bufs[i]); - vb2_buffer_done(q->bufs[i], VB2_BUF_STATE_ERROR); + vb); + vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); } + } /* Must be zero now */ WARN_ON(atomic_read(&q->owned_by_drv_count)); } @@ -2067,9 +2139,14 @@ static void __vb2_queue_cancel(struct vb2_queue *q) * be changed, so we can't move the buf_finish() to __vb2_dqbuf(). */ for (i = 0; i < q->num_buffers; ++i) { - struct vb2_buffer *vb = q->bufs[i]; - struct media_request *req = vb->req_obj.req; + struct vb2_buffer *vb; + struct media_request *req; + + vb = vb2_get_buffer(q, i); + if (!vb) + continue; + req = vb->req_obj.req; /* * If a request is associated with this buffer, then * call buf_request_cancel() to give the driver to complete() @@ -2219,7 +2296,10 @@ static int __find_plane_by_offset(struct vb2_queue *q, unsigned long off, buffer = (off >> (PLANE_INDEX_SHIFT + PAGE_SHIFT)) & MAX_BUFFERS; plane = (off >> PAGE_SHIFT) & PLANE_INDEX_MASK; - vb = q->bufs[buffer]; + vb = vb2_get_buffer(q, buffer); + if (!vb) + return -EINVAL; + if (vb->planes[plane].m.offset == off) { *_buffer = buffer; *_plane = plane; @@ -2262,7 +2342,12 @@ int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type, return -EINVAL; } - vb = q->bufs[index]; + vb = vb2_get_buffer(q, index); + + if (!vb) { + dprintk(q, 1, "can't find the requested buffer\n"); + return -EINVAL; + } if (plane >= vb->num_planes) { dprintk(q, 1, "buffer plane out of range\n"); @@ -2339,7 +2424,13 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma) if (ret) goto unlock; - vb = q->bufs[buffer]; + vb = vb2_get_buffer(q, buffer); + + if (!vb) { + dprintk(q, 1, "can't find the requested buffer\n"); + ret = -EINVAL; + goto unlock; + } /* * MMAP requires page_aligned buffers. @@ -2396,7 +2487,12 @@ unsigned long vb2_get_unmapped_area(struct vb2_queue *q, if (ret) goto unlock; - vb = q->bufs[buffer]; + vb = vb2_get_buffer(q, buffer); + if (!vb) { + dprintk(q, 1, "can't find the requested buffer\n"); + ret = -EINVAL; + goto unlock; + } vaddr = vb2_plane_vaddr(vb, plane); mutex_unlock(&q->mmap_lock); @@ -2625,6 +2721,7 @@ struct vb2_fileio_data { static int __vb2_init_fileio(struct vb2_queue *q, int read) { struct vb2_fileio_data *fileio; + struct vb2_buffer *vb; int i, ret; unsigned int count = 0; @@ -2679,7 +2776,13 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read) * Check if plane_count is correct * (multiplane buffers are not supported). */ - if (q->bufs[0]->num_planes != 1) { + vb = vb2_get_buffer(q, 0); + if (!vb) { + ret = -EBUSY; + goto err_reqbufs; + } + + if (vb->num_planes != 1) { ret = -EBUSY; goto err_reqbufs; } @@ -2688,12 +2791,17 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read) * Get kernel address of each buffer. */ for (i = 0; i < q->num_buffers; i++) { - fileio->bufs[i].vaddr = vb2_plane_vaddr(q->bufs[i], 0); + vb = vb2_get_buffer(q, i); + + if (!vb) + continue; + + fileio->bufs[i].vaddr = vb2_plane_vaddr(vb, 0); if (fileio->bufs[i].vaddr == NULL) { ret = -EINVAL; goto err_reqbufs; } - fileio->bufs[i].size = vb2_plane_size(q->bufs[i], 0); + fileio->bufs[i].size = vb2_plane_size(vb, 0); } /* @@ -2821,15 +2929,18 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_ fileio->cur_index = index; buf = &fileio->bufs[index]; - b = q->bufs[index]; + b = vb2_get_buffer(q, index); + + if (!b) + return -EINVAL; /* * Get number of bytes filled by the driver */ buf->pos = 0; buf->queued = 0; - buf->size = read ? vb2_get_plane_payload(q->bufs[index], 0) - : vb2_plane_size(q->bufs[index], 0); + buf->size = read ? vb2_get_plane_payload(b, 0) + : vb2_plane_size(b, 0); /* Compensate for data_offset on read in the multiplanar case. */ if (is_multiplanar && read && b->planes[0].data_offset < buf->size) { @@ -2872,8 +2983,12 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_ * Queue next buffer if required. */ if (buf->pos == buf->size || (!read && fileio->write_immediately)) { - struct vb2_buffer *b = q->bufs[index]; + struct vb2_buffer *b = vb2_get_buffer(q, index); + if (!b) { + dprintk(q, 1, "can't find the requested buffer\n"); + return -EINVAL; + } /* * Check if this is the last buffer to read. */ @@ -2899,7 +3014,7 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_ */ buf->pos = 0; buf->queued = 1; - buf->size = vb2_plane_size(q->bufs[index], 0); + buf->size = vb2_plane_size(b, 0); fileio->q_count += 1; /* * If we are queuing up buffers for the first time, then @@ -2970,7 +3085,9 @@ static int vb2_thread(void *data) * Call vb2_dqbuf to get buffer back. */ if (prequeue) { - vb = q->bufs[index++]; + vb = vb2_get_buffer(q, index++); + if (!vb) + continue; prequeue--; } else { call_void_qop(q, wait_finish, q); @@ -2979,7 +3096,7 @@ static int vb2_thread(void *data) call_void_qop(q, wait_prepare, q); dprintk(q, 5, "file io: vb2_dqbuf result: %d\n", ret); if (!ret) - vb = q->bufs[index]; + vb = vb2_get_buffer(q, index); } if (ret || threadio->stop) break; diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c index c7a54d82a55e..724135d41f7f 100644 --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c @@ -383,8 +383,7 @@ static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct media_device *md return -EINVAL; } - if (q->bufs[b->index] == NULL) { - /* Should never happen */ + if (!vb2_get_buffer(q, b->index)) { dprintk(q, 1, "%s: buffer is NULL\n", opname); return -EINVAL; } @@ -394,7 +393,7 @@ static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct media_device *md return -EINVAL; } - vb = q->bufs[b->index]; + vb = vb2_get_buffer(q, b->index); vbuf = to_vb2_v4l2_buffer(vb); ret = __verify_planes_array(vb, b); if (ret) @@ -628,11 +627,18 @@ static const struct vb2_buf_ops v4l2_buf_ops = { struct vb2_buffer *vb2_find_buffer(struct vb2_queue *q, u64 timestamp) { unsigned int i; + struct vb2_buffer *vb2; - for (i = 0; i < q->num_buffers; i++) - if (q->bufs[i]->copied_timestamp && - q->bufs[i]->timestamp == timestamp) - return vb2_get_buffer(q, i); + for (i = 0; i < q->num_buffers; i++) { + vb2 = vb2_get_buffer(q, i); + + if (!vb2) + continue; + + if (vb2->copied_timestamp && + vb2->timestamp == timestamp) + return vb2; + } return NULL; } EXPORT_SYMBOL_GPL(vb2_find_buffer); @@ -664,7 +670,13 @@ int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b) dprintk(q, 1, "buffer index out of range\n"); return -EINVAL; } - vb = q->bufs[b->index]; + vb = vb2_get_buffer(q, b->index); + + if (!vb) { + dprintk(q, 1, "can't find the requested buffer\n"); + return -EINVAL; + } + ret = __verify_planes_array(vb, b); if (!ret) vb2_core_querybuf(q, b->index, b); diff --git a/drivers/media/platform/amphion/vpu_dbg.c b/drivers/media/platform/amphion/vpu_dbg.c index 982c2c777484..a462d6fe4ea9 100644 --- a/drivers/media/platform/amphion/vpu_dbg.c +++ b/drivers/media/platform/amphion/vpu_dbg.c @@ -140,11 +140,18 @@ static int vpu_dbg_instance(struct seq_file *s, void *data) vq = v4l2_m2m_get_src_vq(inst->fh.m2m_ctx); for (i = 0; i < vq->num_buffers; i++) { - struct vb2_buffer *vb = vq->bufs[i]; - struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + struct vb2_buffer *vb; + struct vb2_v4l2_buffer *vbuf; + + vb = vb2_get_buffer(vq, i); + if (!vb) + continue; if (vb->state == VB2_BUF_STATE_DEQUEUED) continue; + + vbuf = to_vb2_v4l2_buffer(vb); + num = scnprintf(str, sizeof(str), "output [%2d] state = %10s, %8s\n", i, vb2_stat_name[vb->state], @@ -155,11 +162,18 @@ static int vpu_dbg_instance(struct seq_file *s, void *data) vq = v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx); for (i = 0; i < vq->num_buffers; i++) { - struct vb2_buffer *vb = vq->bufs[i]; - struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + struct vb2_buffer *vb; + struct vb2_v4l2_buffer *vbuf; + + vb = vb2_get_buffer(vq, i); + if (!vb) + continue; if (vb->state == VB2_BUF_STATE_DEQUEUED) continue; + + vbuf = to_vb2_v4l2_buffer(vb); + num = scnprintf(str, sizeof(str), "capture[%2d] state = %10s, %8s\n", i, vb2_stat_name[vb->state], diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c index 621038aab116..62910a1b8a98 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c @@ -603,7 +603,11 @@ static int mtk_jpeg_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) return -EINVAL; } - vb = vq->bufs[buf->index]; + vb = vb2_get_buffer(vq, buf->index); + if (!vb) { + dev_err(ctx->jpeg->dev, "buffer not found\n"); + return -EINVAL; + } jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(vb); jpeg_src_buf->bs_size = buf->m.planes[0].bytesused; diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c index e393e3e668f8..3d2ae0e1b5b6 100644 --- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c @@ -1696,7 +1696,7 @@ static int vdec_vp9_slice_setup_core_buffer(struct vdec_vp9_slice_instance *inst /* update internal buffer's width/height */ for (i = 0; i < vq->num_buffers; i++) { - if (vb == vq->bufs[i]) { + if (vb == vb2_get_buffer(vq, i)) { instance->dpb[i].width = w; instance->dpb[i].height = h; break; diff --git a/drivers/media/platform/st/sti/hva/hva-v4l2.c b/drivers/media/platform/st/sti/hva/hva-v4l2.c index 3a848ca32a0e..326be09bdb55 100644 --- a/drivers/media/platform/st/sti/hva/hva-v4l2.c +++ b/drivers/media/platform/st/sti/hva/hva-v4l2.c @@ -577,6 +577,10 @@ static int hva_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) } vb2_buf = vb2_get_buffer(vq, buf->index); + if (!vb2_buf) { + dev_dbg(dev, "%s buffer index %d not found\n", ctx->name, buf->index); + return -EINVAL; + } stream = to_hva_stream(to_vb2_v4l2_buffer(vb2_buf)); stream->bytesused = buf->bytesused; } diff --git a/drivers/media/test-drivers/visl/visl-dec.c b/drivers/media/test-drivers/visl/visl-dec.c index 318d675e5668..ba20ea998d19 100644 --- a/drivers/media/test-drivers/visl/visl-dec.c +++ b/drivers/media/test-drivers/visl/visl-dec.c @@ -290,13 +290,20 @@ static void visl_tpg_fill(struct visl_ctx *ctx, struct visl_run *run) for (i = 0; i < out_q->num_buffers; i++) { char entry[] = "index: %u, state: %s, request_fd: %d, "; u32 old_len = len; - char *q_status = visl_get_vb2_state(out_q->bufs[i]->state); + struct vb2_buffer *vb2; + char *q_status; + + vb2 = vb2_get_buffer(out_q, i); + if (!vb2) + continue; + + q_status = visl_get_vb2_state(vb2->state); len += scnprintf(&buf[len], TPG_STR_BUF_SZ - len, entry, i, q_status, - to_vb2_v4l2_buffer(out_q->bufs[i])->request_fd); + to_vb2_v4l2_buffer(vb2)->request_fd); - len += visl_fill_bytesused(to_vb2_v4l2_buffer(out_q->bufs[i]), + len += visl_fill_bytesused(to_vb2_v4l2_buffer(vb2), &buf[len], TPG_STR_BUF_SZ - len); @@ -342,13 +349,20 @@ static void visl_tpg_fill(struct visl_ctx *ctx, struct visl_run *run) len = 0; for (i = 0; i < cap_q->num_buffers; i++) { u32 old_len = len; - char *q_status = visl_get_vb2_state(cap_q->bufs[i]->state); + struct vb2_buffer *vb2; + char *q_status; + + vb2 = vb2_get_buffer(cap_q, i); + if (!vb2) + continue; + + q_status = visl_get_vb2_state(vb2->state); len += scnprintf(&buf[len], TPG_STR_BUF_SZ - len, "index: %u, status: %s, timestamp: %llu, is_held: %d", - cap_q->bufs[i]->index, q_status, - cap_q->bufs[i]->timestamp, - to_vb2_v4l2_buffer(cap_q->bufs[i])->is_held); + vb2->index, q_status, + vb2->timestamp, + to_vb2_v4l2_buffer(vb2)->is_held); tpg_gen_text(&ctx->tpg, basep, line++ * line_height, 16, &buf[old_len]); frame_dprintk(ctx->dev, run->dst->sequence, "%s", &buf[old_len]); diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c index d2174156573a..4b65c69fa60d 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c +++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c @@ -1061,7 +1061,7 @@ static int atomisp_dqbuf_wrapper(struct file *file, void *fh, struct v4l2_buffer if (ret) return ret; - vb = pipe->vb_queue.bufs[buf->index]; + vb = vb2_get_buffer(&pipe->vb_queue, buf->index); frame = vb_to_frame(vb); buf->reserved = asd->frame_status[buf->index]; From patchwork Thu Aug 24 09:21:26 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Gaignard X-Patchwork-Id: 717093 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DB751EE49B3 for ; Thu, 24 Aug 2023 09:22:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240739AbjHXJW2 (ORCPT ); Thu, 24 Aug 2023 05:22:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57348 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240712AbjHXJVt (ORCPT ); Thu, 24 Aug 2023 05:21:49 -0400 Received: from madras.collabora.co.uk (madras.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e5ab]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0D67A198E; Thu, 24 Aug 2023 02:21:45 -0700 (PDT) Received: from benjamin-XPS-13-9310.. (unknown [IPv6:2a01:e0a:120:3210:672:c310:4c8a:3a97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: benjamin.gaignard) by madras.collabora.co.uk (Postfix) with ESMTPSA id 2C6396607298; Thu, 24 Aug 2023 10:21:43 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1692868903; bh=GJNKi5NuuSLWK7PozA+X2l2tr8rdGL1VU7W/PWSM0Qg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CbsU2h3lrlKgQ+EQRrW9BO2PmU4sBpRUUMKjJ5yDvZlXAe5751vX0SNbK0P8zClve PXQ1rFMhIqBHRIgEl/3yuwZhn2VpGXBSEyis6htorrAx/4kAB4e0ztKhYcW+XjABAx ZMo26KoTk+gY+6qI4bDf/srreA9r06uvOe+VY5xFpA5IVQ02/fLLbnt0e05vgrIL0u FRCvcUonoN1kqZQ+8d5fG8vYc925yp3mDXx5fhreZ1sGzzC/bCsV82839Llc0i/6jr Ow7M+XeWY/bNjU+h2n7qBpM+qUzx4m1Te0UphNfuZREUP9W/A9xePZqP1+5QBkVa7m lrb2MwIqm6hXw== From: Benjamin Gaignard To: mchehab@kernel.org, tfiga@chromium.org, m.szyprowski@samsung.com, ming.qian@nxp.com, ezequiel@vanguardiasur.com.ar, p.zabel@pengutronix.de, gregkh@linuxfoundation.org, hverkuil-cisco@xs4all.nl, nicolas.dufresne@collabora.com Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-arm-msm@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-staging@lists.linux.dev, kernel@collabora.com, Benjamin Gaignard Subject: [PATCH v5 03/10] media: videobuf2: Be more flexible on the number of queue stored buffers Date: Thu, 24 Aug 2023 11:21:26 +0200 Message-Id: <20230824092133.39510-4-benjamin.gaignard@collabora.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230824092133.39510-1-benjamin.gaignard@collabora.com> References: <20230824092133.39510-1-benjamin.gaignard@collabora.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add 'max_allowed_buffers' field in vb2_queue struct to let drivers decide how many buffers could be stored in a queue. This request 'bufs' array to be allocated at queue init time and freed when releasing the queue. By default VB2_MAX_FRAME remains the limit. Signed-off-by: Benjamin Gaignard --- .../media/common/videobuf2/videobuf2-core.c | 25 +++++++++++++------ include/media/videobuf2-core.h | 4 ++- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c index 8aa13591b782..70e36389b704 100644 --- a/drivers/media/common/videobuf2/videobuf2-core.c +++ b/drivers/media/common/videobuf2/videobuf2-core.c @@ -411,7 +411,7 @@ static void init_buffer_cache_hints(struct vb2_queue *q, struct vb2_buffer *vb) */ static bool vb2_queue_add_buffer(struct vb2_queue *q, struct vb2_buffer *vb, int index) { - if (index < VB2_MAX_FRAME && !q->bufs[index]) { + if (index < q->max_allowed_buffers && !q->bufs[index]) { q->bufs[index] = vb; vb->index = index; vb->vb2_queue = q; @@ -428,7 +428,7 @@ static bool vb2_queue_add_buffer(struct vb2_queue *q, struct vb2_buffer *vb, int */ static void vb2_queue_remove_buffer(struct vb2_queue *q, struct vb2_buffer *vb) { - if (vb->index < VB2_MAX_FRAME) { + if (vb->index < q->max_allowed_buffers) { q->bufs[vb->index] = NULL; vb->vb2_queue = NULL; } @@ -449,9 +449,9 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum vb2_memory memory, struct vb2_buffer *vb; int ret; - /* Ensure that q->num_buffers+num_buffers is below VB2_MAX_FRAME */ + /* Ensure that q->num_buffers+num_buffers is below q->max_allowed_buffers */ num_buffers = min_t(unsigned int, num_buffers, - VB2_MAX_FRAME - q->num_buffers); + q->max_allowed_buffers - q->num_buffers); for (buffer = 0; buffer < num_buffers; ++buffer) { /* Allocate vb2 buffer structures */ @@ -852,9 +852,9 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory, /* * Make sure the requested values and current defaults are sane. */ - WARN_ON(q->min_buffers_needed > VB2_MAX_FRAME); + WARN_ON(q->min_buffers_needed > q->max_allowed_buffers); num_buffers = max_t(unsigned int, *count, q->min_buffers_needed); - num_buffers = min_t(unsigned int, num_buffers, VB2_MAX_FRAME); + num_buffers = min_t(unsigned int, num_buffers, q->max_allowed_buffers); memset(q->alloc_devs, 0, sizeof(q->alloc_devs)); /* * Set this now to ensure that drivers see the correct q->memory value @@ -970,7 +970,7 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory, bool no_previous_buffers = !q->num_buffers; int ret; - if (q->num_buffers == VB2_MAX_FRAME) { + if (q->num_buffers == q->max_allowed_buffers) { dprintk(q, 1, "maximum number of buffers already allocated\n"); return -ENOBUFS; } @@ -999,7 +999,7 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory, return -EINVAL; } - num_buffers = min(*count, VB2_MAX_FRAME - q->num_buffers); + num_buffers = min(*count, q->max_allowed_buffers - q->num_buffers); if (requested_planes && requested_sizes) { num_planes = requested_planes; @@ -2541,6 +2541,14 @@ int vb2_core_queue_init(struct vb2_queue *q) q->memory = VB2_MEMORY_UNKNOWN; + if (!q->max_allowed_buffers) + q->max_allowed_buffers = VB2_MAX_FRAME; + + /* The maximum is limited by offset cookie encoding pattern */ + q->max_allowed_buffers = min_t(unsigned int, q->max_allowed_buffers, MAX_BUFFERS); + + q->bufs = kcalloc(q->max_allowed_buffers, sizeof(*q->bufs), GFP_KERNEL); + if (q->buf_struct_size == 0) q->buf_struct_size = sizeof(struct vb2_buffer); @@ -2565,6 +2573,7 @@ void vb2_core_queue_release(struct vb2_queue *q) __vb2_queue_cancel(q); mutex_lock(&q->mmap_lock); __vb2_queue_free(q, q->num_buffers); + kfree(q->bufs); mutex_unlock(&q->mmap_lock); } EXPORT_SYMBOL_GPL(vb2_core_queue_release); diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index 4b6a9d2ea372..ee9161b9fd64 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -558,6 +558,7 @@ struct vb2_buf_ops { * @dma_dir: DMA mapping direction. * @bufs: videobuf2 buffer structures * @num_buffers: number of allocated/used buffers + * @max_allowed_buffers: upper limit of number of allocated/used buffers * @queued_list: list of buffers currently queued from userspace * @queued_count: number of buffers queued and ready for streaming. * @owned_by_drv_count: number of buffers owned by the driver @@ -619,8 +620,9 @@ struct vb2_queue { struct mutex mmap_lock; unsigned int memory; enum dma_data_direction dma_dir; - struct vb2_buffer *bufs[VB2_MAX_FRAME]; + struct vb2_buffer **bufs; unsigned int num_buffers; + unsigned int max_allowed_buffers; struct list_head queued_list; unsigned int queued_count; From patchwork Thu Aug 24 09:21:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Gaignard X-Patchwork-Id: 717092 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CB383EE49B0 for ; Thu, 24 Aug 2023 09:22:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240743AbjHXJW3 (ORCPT ); Thu, 24 Aug 2023 05:22:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57362 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240713AbjHXJVt (ORCPT ); Thu, 24 Aug 2023 05:21:49 -0400 Received: from madras.collabora.co.uk (madras.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e5ab]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 54DB4199E; Thu, 24 Aug 2023 02:21:45 -0700 (PDT) Received: from benjamin-XPS-13-9310.. (unknown [IPv6:2a01:e0a:120:3210:672:c310:4c8a:3a97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: benjamin.gaignard) by madras.collabora.co.uk (Postfix) with ESMTPSA id AAF4966072B4; Thu, 24 Aug 2023 10:21:43 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1692868904; bh=3JGoPEgNPk/j++UXJL853HPLU3bnOyEVrktPVlhrFiQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OlkydnIanfve6JAqumj9VSjFzCE21gsthbcuD7qoDwaSprEzlb3ofp6jz9Bf/5gFB tXS6nHlcPWfKV2HScyExM7DB5E4JOiXVF9pqWGiZ73slvWOgdsHiux0wPsVRWZM3MA kvk176fMYbztwEIsNKD4eKgiNd2ElJsJkb/c6lCosTNKgb9mfo4ZvGxIvEBPeXuYmT zX6+zttn8zlwTWIYePxp15UsBIJmyichnjNAV6+rg3nLixi5V0psjdoKOuNwmYlpzC kTKirJ2eopvLA+Ua2iBSE+QzFZ8qlIod02Y8zueV1MjyWnFKOi7t63c6tI8i77Jnv1 GrzS4SMHhtJDg== From: Benjamin Gaignard To: mchehab@kernel.org, tfiga@chromium.org, m.szyprowski@samsung.com, ming.qian@nxp.com, ezequiel@vanguardiasur.com.ar, p.zabel@pengutronix.de, gregkh@linuxfoundation.org, hverkuil-cisco@xs4all.nl, nicolas.dufresne@collabora.com Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-arm-msm@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-staging@lists.linux.dev, kernel@collabora.com, Benjamin Gaignard Subject: [PATCH v5 04/10] media: verisilicon: Refactor postprocessor to store more buffers Date: Thu, 24 Aug 2023 11:21:27 +0200 Message-Id: <20230824092133.39510-5-benjamin.gaignard@collabora.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230824092133.39510-1-benjamin.gaignard@collabora.com> References: <20230824092133.39510-1-benjamin.gaignard@collabora.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Since vb2 queue can store than VB2_MAX_FRAME buffers postprocessor buffer storage must be capable to store more buffers too. Change static dec_q array to allocated array to be capable to store up to queue 'max_allowed_buffers'. Keep allocating queue 'num_buffers' at queue setup time but also allows to allocate postprocessors buffers on the fly. Signed-off-by: Benjamin Gaignard --- v5: - Use a static buffer array instead of an allocated one. drivers/media/platform/verisilicon/hantro.h | 7 +- .../media/platform/verisilicon/hantro_drv.c | 4 +- .../media/platform/verisilicon/hantro_hw.h | 4 +- .../platform/verisilicon/hantro_postproc.c | 93 +++++++++++++++---- .../media/platform/verisilicon/hantro_v4l2.c | 2 +- 5 files changed, 85 insertions(+), 25 deletions(-) diff --git a/drivers/media/platform/verisilicon/hantro.h b/drivers/media/platform/verisilicon/hantro.h index 77aee9489516..0948b04a9f8d 100644 --- a/drivers/media/platform/verisilicon/hantro.h +++ b/drivers/media/platform/verisilicon/hantro.h @@ -469,11 +469,14 @@ hantro_get_dst_buf(struct hantro_ctx *ctx) bool hantro_needs_postproc(const struct hantro_ctx *ctx, const struct hantro_fmt *fmt); +dma_addr_t +hantro_postproc_get_dec_buf_addr(struct hantro_ctx *ctx, int index); + static inline dma_addr_t hantro_get_dec_buf_addr(struct hantro_ctx *ctx, struct vb2_buffer *vb) { if (hantro_needs_postproc(ctx, ctx->vpu_dst_fmt)) - return ctx->postproc.dec_q[vb->index].dma; + return hantro_postproc_get_dec_buf_addr(ctx, vb->index); return vb2_dma_contig_plane_dma_addr(vb, 0); } @@ -485,8 +488,8 @@ vb2_to_hantro_decoded_buf(struct vb2_buffer *buf) void hantro_postproc_disable(struct hantro_ctx *ctx); void hantro_postproc_enable(struct hantro_ctx *ctx); +int hantro_postproc_init(struct hantro_ctx *ctx); void hantro_postproc_free(struct hantro_ctx *ctx); -int hantro_postproc_alloc(struct hantro_ctx *ctx); int hanto_postproc_enum_framesizes(struct hantro_ctx *ctx, struct v4l2_frmsizeenum *fsize); diff --git a/drivers/media/platform/verisilicon/hantro_drv.c b/drivers/media/platform/verisilicon/hantro_drv.c index 423fc85d79ee..18f56edee3fc 100644 --- a/drivers/media/platform/verisilicon/hantro_drv.c +++ b/drivers/media/platform/verisilicon/hantro_drv.c @@ -234,8 +234,10 @@ queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq) * The Kernel needs access to the JPEG destination buffer for the * JPEG encoder to fill in the JPEG headers. */ - if (!ctx->is_encoder) + if (!ctx->is_encoder) { dst_vq->dma_attrs |= DMA_ATTR_NO_KERNEL_MAPPING; + dst_vq->max_allowed_buffers = MAX_POSTPROC_BUFFERS; + } dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; dst_vq->io_modes = VB2_MMAP | VB2_DMABUF; diff --git a/drivers/media/platform/verisilicon/hantro_hw.h b/drivers/media/platform/verisilicon/hantro_hw.h index 7f33f7b07ce4..292a76ef643e 100644 --- a/drivers/media/platform/verisilicon/hantro_hw.h +++ b/drivers/media/platform/verisilicon/hantro_hw.h @@ -40,6 +40,8 @@ #define AV1_MAX_FRAME_BUF_COUNT (V4L2_AV1_TOTAL_REFS_PER_FRAME + 1) +#define MAX_POSTPROC_BUFFERS 64 + struct hantro_dev; struct hantro_ctx; struct hantro_buf; @@ -336,7 +338,7 @@ struct hantro_av1_dec_hw_ctx { * @dec_q: References buffers, in decoder format. */ struct hantro_postproc_ctx { - struct hantro_aux_buf dec_q[VB2_MAX_FRAME]; + struct hantro_aux_buf dec_q[MAX_POSTPROC_BUFFERS]; }; /** diff --git a/drivers/media/platform/verisilicon/hantro_postproc.c b/drivers/media/platform/verisilicon/hantro_postproc.c index 0224ff68ab3f..e624cd98f41b 100644 --- a/drivers/media/platform/verisilicon/hantro_postproc.c +++ b/drivers/media/platform/verisilicon/hantro_postproc.c @@ -177,9 +177,11 @@ static int hantro_postproc_g2_enum_framesizes(struct hantro_ctx *ctx, void hantro_postproc_free(struct hantro_ctx *ctx) { struct hantro_dev *vpu = ctx->dev; + struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx; + struct vb2_queue *queue = &m2m_ctx->cap_q_ctx.q; unsigned int i; - for (i = 0; i < VB2_MAX_FRAME; ++i) { + for (i = 0; i < queue->max_allowed_buffers; ++i) { struct hantro_aux_buf *priv = &ctx->postproc.dec_q[i]; if (priv->cpu) { @@ -190,20 +192,17 @@ void hantro_postproc_free(struct hantro_ctx *ctx) } } -int hantro_postproc_alloc(struct hantro_ctx *ctx) +static unsigned int hantro_postproc_buffer_size(struct hantro_ctx *ctx) { - struct hantro_dev *vpu = ctx->dev; - struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx; - struct vb2_queue *cap_queue = &m2m_ctx->cap_q_ctx.q; - unsigned int num_buffers = cap_queue->num_buffers; struct v4l2_pix_format_mplane pix_mp; const struct hantro_fmt *fmt; - unsigned int i, buf_size; + unsigned int buf_size; /* this should always pick native format */ fmt = hantro_get_default_fmt(ctx, false, ctx->bit_depth, HANTRO_AUTO_POSTPROC); if (!fmt) - return -EINVAL; + return 0; + v4l2_fill_pixfmt_mp(&pix_mp, fmt->fourcc, ctx->src_fmt.width, ctx->src_fmt.height); @@ -221,23 +220,77 @@ int hantro_postproc_alloc(struct hantro_ctx *ctx) buf_size += hantro_av1_mv_size(pix_mp.width, pix_mp.height); - for (i = 0; i < num_buffers; ++i) { - struct hantro_aux_buf *priv = &ctx->postproc.dec_q[i]; + return buf_size; +} + +static int hantro_postproc_alloc(struct hantro_ctx *ctx, int index) +{ + struct hantro_dev *vpu = ctx->dev; + struct hantro_aux_buf *priv = &ctx->postproc.dec_q[index]; + unsigned int buf_size = hantro_postproc_buffer_size(ctx); + + if (!buf_size) + return -EINVAL; + + /* + * The buffers on this queue are meant as intermediate + * buffers for the decoder, so no mapping is needed. + */ + priv->attrs = DMA_ATTR_NO_KERNEL_MAPPING; + priv->cpu = dma_alloc_attrs(vpu->dev, buf_size, &priv->dma, + GFP_KERNEL, priv->attrs); + if (!priv->cpu) + return -ENOMEM; + priv->size = buf_size; + + return 0; +} - /* - * The buffers on this queue are meant as intermediate - * buffers for the decoder, so no mapping is needed. - */ - priv->attrs = DMA_ATTR_NO_KERNEL_MAPPING; - priv->cpu = dma_alloc_attrs(vpu->dev, buf_size, &priv->dma, - GFP_KERNEL, priv->attrs); - if (!priv->cpu) - return -ENOMEM; - priv->size = buf_size; +int hantro_postproc_init(struct hantro_ctx *ctx) +{ + struct v4l2_m2m_ctx *m2m_ctx = ctx->fh.m2m_ctx; + struct vb2_queue *cap_queue = &m2m_ctx->cap_q_ctx.q; + unsigned int num_buffers = cap_queue->num_buffers; + unsigned int i; + int ret; + + for (i = 0; i < num_buffers; i++) { + ret = hantro_postproc_alloc(ctx, i); + if (ret) + return ret; } + return 0; } +dma_addr_t +hantro_postproc_get_dec_buf_addr(struct hantro_ctx *ctx, int index) +{ + struct hantro_aux_buf *priv = &ctx->postproc.dec_q[index]; + unsigned int buf_size = hantro_postproc_buffer_size(ctx); + struct hantro_dev *vpu = ctx->dev; + int ret; + + if (priv->size < buf_size && priv->cpu) { + /* buffer is too small, release it */ + dma_free_attrs(vpu->dev, priv->size, priv->cpu, + priv->dma, priv->attrs); + priv->cpu = NULL; + } + + if (!priv->cpu) { + /* buffer not already allocated, try getting a new one */ + ret = hantro_postproc_alloc(ctx, index); + if (ret) + return 0; + } + + if (!priv->cpu) + return 0; + + return priv->dma; +} + static void hantro_postproc_g1_disable(struct hantro_ctx *ctx) { struct hantro_dev *vpu = ctx->dev; diff --git a/drivers/media/platform/verisilicon/hantro_v4l2.c b/drivers/media/platform/verisilicon/hantro_v4l2.c index b3ae037a50f6..f0d8b165abcd 100644 --- a/drivers/media/platform/verisilicon/hantro_v4l2.c +++ b/drivers/media/platform/verisilicon/hantro_v4l2.c @@ -933,7 +933,7 @@ static int hantro_start_streaming(struct vb2_queue *q, unsigned int count) } if (hantro_needs_postproc(ctx, ctx->vpu_dst_fmt)) { - ret = hantro_postproc_alloc(ctx); + ret = hantro_postproc_init(ctx); if (ret) goto err_codec_exit; } From patchwork Thu Aug 24 09:21:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Gaignard X-Patchwork-Id: 716738 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A70E7EE49B2 for ; Thu, 24 Aug 2023 09:22:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240733AbjHXJW0 (ORCPT ); Thu, 24 Aug 2023 05:22:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57366 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240714AbjHXJVt (ORCPT ); Thu, 24 Aug 2023 05:21:49 -0400 Received: from madras.collabora.co.uk (madras.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e5ab]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5CBBD19A1; Thu, 24 Aug 2023 02:21:46 -0700 (PDT) Received: from benjamin-XPS-13-9310.. (unknown [IPv6:2a01:e0a:120:3210:672:c310:4c8a:3a97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: benjamin.gaignard) by madras.collabora.co.uk (Postfix) with ESMTPSA id 3838366072EB; Thu, 24 Aug 2023 10:21:44 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1692868904; bh=gAzQ/SGzIm4inZNC+PXcs+p3IPzDsrNiBUGyKW1mkfg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=F6waHdxdia1zqInJtPnx5YVX8gzCDUgqXlgC2p9XYvyvZpgnlm5pfVqx3baByiGWp UBbz62SDaYTQqD7vYK86qBALS3Y6h693Zk7UJHG8XRJ4EjwoLyUWJ8uqrHk3QFTH/R IDw3xOCLINT5483bkrKhTAshOvuPXbpdoEPerio+X7+kCC7Ej8l5sc5fZCWVrjB6iS 3ggH/AJhLP3QvGWPmuZwIVNacicf7+HKGjRZ0BbuC+fKkDQqJRvufwJ3ADPVFKS6LB JInOtJnsqfBdgS0pMaQmN75971EELaMHalJKFgxr2uYhgZybUZji/GHpE9zdIMJb+N 3HVmtd4Gt2OxQ== From: Benjamin Gaignard To: mchehab@kernel.org, tfiga@chromium.org, m.szyprowski@samsung.com, ming.qian@nxp.com, ezequiel@vanguardiasur.com.ar, p.zabel@pengutronix.de, gregkh@linuxfoundation.org, hverkuil-cisco@xs4all.nl, nicolas.dufresne@collabora.com Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-arm-msm@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-staging@lists.linux.dev, kernel@collabora.com, Benjamin Gaignard Subject: [PATCH v5 05/10] media: verisilicon: Store chroma and motion vectors offset Date: Thu, 24 Aug 2023 11:21:28 +0200 Message-Id: <20230824092133.39510-6-benjamin.gaignard@collabora.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230824092133.39510-1-benjamin.gaignard@collabora.com> References: <20230824092133.39510-1-benjamin.gaignard@collabora.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Store computed values of chroma and motion vectors offset because they depends on width and height values which change if the resolution change. Signed-off-by: Benjamin Gaignard --- drivers/media/platform/verisilicon/hantro.h | 2 ++ drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/verisilicon/hantro.h b/drivers/media/platform/verisilicon/hantro.h index 0948b04a9f8d..6f5eb975d0e3 100644 --- a/drivers/media/platform/verisilicon/hantro.h +++ b/drivers/media/platform/verisilicon/hantro.h @@ -328,6 +328,8 @@ struct hantro_vp9_decoded_buffer_info { /* Info needed when the decoded frame serves as a reference frame. */ unsigned short width; unsigned short height; + size_t chroma_offset; + size_t mv_offset; u32 bit_depth : 4; }; diff --git a/drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c b/drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c index 6fc4b555517f..6db1c32fce4d 100644 --- a/drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c +++ b/drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c @@ -158,9 +158,11 @@ static void config_output(struct hantro_ctx *ctx, chroma_addr = luma_addr + chroma_offset(ctx, dec_params); hantro_write_addr(ctx->dev, G2_OUT_CHROMA_ADDR, chroma_addr); + dst->vp9.chroma_offset = chroma_offset(ctx, dec_params); mv_addr = luma_addr + mv_offset(ctx, dec_params); hantro_write_addr(ctx->dev, G2_OUT_MV_ADDR, mv_addr); + dst->vp9.mv_offset = mv_offset(ctx, dec_params); } struct hantro_vp9_ref_reg { @@ -195,7 +197,7 @@ static void config_ref(struct hantro_ctx *ctx, luma_addr = hantro_get_dec_buf_addr(ctx, &buf->base.vb.vb2_buf); hantro_write_addr(ctx->dev, ref_reg->y_base, luma_addr); - chroma_addr = luma_addr + chroma_offset(ctx, dec_params); + chroma_addr = luma_addr + buf->vp9.chroma_offset; hantro_write_addr(ctx->dev, ref_reg->c_base, chroma_addr); } @@ -238,7 +240,7 @@ static void config_ref_registers(struct hantro_ctx *ctx, config_ref(ctx, dst, &ref_regs[2], dec_params, dec_params->alt_frame_ts); mv_addr = hantro_get_dec_buf_addr(ctx, &mv_ref->base.vb.vb2_buf) + - mv_offset(ctx, dec_params); + mv_ref->vp9.mv_offset; hantro_write_addr(ctx->dev, G2_REF_MV_ADDR(0), mv_addr); hantro_reg_write(ctx->dev, &vp9_last_sign_bias, From patchwork Thu Aug 24 09:21:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Gaignard X-Patchwork-Id: 717094 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 90F01EE49AB for ; Thu, 24 Aug 2023 09:22:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240706AbjHXJWY (ORCPT ); Thu, 24 Aug 2023 05:22:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57372 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240715AbjHXJVt (ORCPT ); Thu, 24 Aug 2023 05:21:49 -0400 Received: from madras.collabora.co.uk (madras.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e5ab]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6308419A2; Thu, 24 Aug 2023 02:21:46 -0700 (PDT) Received: from benjamin-XPS-13-9310.. (unknown [IPv6:2a01:e0a:120:3210:672:c310:4c8a:3a97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: benjamin.gaignard) by madras.collabora.co.uk (Postfix) with ESMTPSA id BCF0A6607308; Thu, 24 Aug 2023 10:21:44 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1692868905; bh=PWkYPK7UJF1YmVd+lrdWvCWfZPTYmEC52Q6H6L/2CpY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=R/SPv0Dy0iBRcsZbWmQFlUA6N4JHkxVqimQXCK3Lrr/717kH60Foss4GfNKFEBoSD 1eodB6aWnxkSYjmgQj1eb6RxTj5F2+wRcc/I9JdPUKSNqbnC0U0I2sUda+Orre4sdq BRXGCoqrWFY9E49TGHO0geQ8pmo9Mp2I+G9cghz6PzPFO7+OvbR4r8x9OJPYwGfVDk Mdlx2jizNtqDtc5/LEbHtQ2bcwG/zow8v5zRXt948YmcJ/wG9wfJfPDy5bpD+sHjET LY34+TAEByasLjenXpSJNT+0qjHJzwhFyT9W6vWYpSuTh1Uox7OFoMGrp6GFp5PzFe jixgUT6/iNg+A== From: Benjamin Gaignard To: mchehab@kernel.org, tfiga@chromium.org, m.szyprowski@samsung.com, ming.qian@nxp.com, ezequiel@vanguardiasur.com.ar, p.zabel@pengutronix.de, gregkh@linuxfoundation.org, hverkuil-cisco@xs4all.nl, nicolas.dufresne@collabora.com Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-arm-msm@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-staging@lists.linux.dev, kernel@collabora.com, Benjamin Gaignard Subject: [PATCH v5 06/10] media: verisilicon: vp9: Use destination buffer height to compute chroma offset Date: Thu, 24 Aug 2023 11:21:29 +0200 Message-Id: <20230824092133.39510-7-benjamin.gaignard@collabora.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230824092133.39510-1-benjamin.gaignard@collabora.com> References: <20230824092133.39510-1-benjamin.gaignard@collabora.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Source and destination buffer height may not be the same because alignment constraint are different. Use destination height to compute chroma offset because we target this buffer as hardware output. Signed-off-by: Benjamin Gaignard Fixes: e2da465455ce ("media: hantro: Support VP9 on the G2 core") --- drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c b/drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c index 6db1c32fce4d..1f3f5e7ce978 100644 --- a/drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c +++ b/drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c @@ -93,9 +93,7 @@ static int start_prepare_run(struct hantro_ctx *ctx, const struct v4l2_ctrl_vp9_ static size_t chroma_offset(const struct hantro_ctx *ctx, const struct v4l2_ctrl_vp9_frame *dec_params) { - int bytes_per_pixel = dec_params->bit_depth == 8 ? 1 : 2; - - return ctx->src_fmt.width * ctx->src_fmt.height * bytes_per_pixel; + return ctx->dst_fmt.width * ctx->dst_fmt.height * ctx->bit_depth / 8; } static size_t mv_offset(const struct hantro_ctx *ctx, From patchwork Thu Aug 24 09:21:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Gaignard X-Patchwork-Id: 717095 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1FA7AC7EE43 for ; Thu, 24 Aug 2023 09:22:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240692AbjHXJWX (ORCPT ); Thu, 24 Aug 2023 05:22:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57444 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240720AbjHXJVt (ORCPT ); Thu, 24 Aug 2023 05:21:49 -0400 Received: from madras.collabora.co.uk (madras.collabora.co.uk [46.235.227.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0DEB119A0; Thu, 24 Aug 2023 02:21:47 -0700 (PDT) Received: from benjamin-XPS-13-9310.. (unknown [IPv6:2a01:e0a:120:3210:672:c310:4c8a:3a97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: benjamin.gaignard) by madras.collabora.co.uk (Postfix) with ESMTPSA id 42D116607324; Thu, 24 Aug 2023 10:21:45 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1692868905; bh=7SuYFFsy0UMAkQQkxSlRxpuDU3mFA9H4F51e8vN5B0Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oW8M0zme51EF2mG+W34pgdyjpdQHpfMyMUr6LW6PIKBgj8IArSpUTgUzgiXQD1Stl QkLf3jZeNZM/ExuwvJpAE1hrtB1bMt7qi+tJYdr4lCGVKJxR1/lv20PLQB1fC3E2tV 3gIUY1/HxFsfqx3bgnQqAvYQInBM+i9W0C86fk5eDifFIrmEnq6AObhn+i/LHGosMb mx1RK1HxYnXHIyGU00aYeRkoYv5fU25gESjqHrSGitBNSEW5FZk2KRGHqJ0ZFL8wRd Ah9uOscxkilvMJkG8dbuUGKdjILYM5mXxJKOHrUO4togCQoceF/lH3uLK1fkGFzh5Q zugcb//lCquSQ== From: Benjamin Gaignard To: mchehab@kernel.org, tfiga@chromium.org, m.szyprowski@samsung.com, ming.qian@nxp.com, ezequiel@vanguardiasur.com.ar, p.zabel@pengutronix.de, gregkh@linuxfoundation.org, hverkuil-cisco@xs4all.nl, nicolas.dufresne@collabora.com Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-arm-msm@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-staging@lists.linux.dev, kernel@collabora.com, Benjamin Gaignard Subject: [PATCH v5 07/10] media: verisilicon: postproc: Fix down scale test Date: Thu, 24 Aug 2023 11:21:30 +0200 Message-Id: <20230824092133.39510-8-benjamin.gaignard@collabora.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230824092133.39510-1-benjamin.gaignard@collabora.com> References: <20230824092133.39510-1-benjamin.gaignard@collabora.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Do not allow down scaling if the source buffer resolution is smaller than destination one. Signed-off-by: Benjamin Gaignard Fixes: fbb6c848dd89 ("media: destage Hantro VPU driver") --- Note: Marek has propose exactly the same fix in this patch: [PATCH] media: verisilicon: Do not enable G2 postproc downscale if source is narrower than destination drivers/media/platform/verisilicon/hantro_postproc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/verisilicon/hantro_postproc.c b/drivers/media/platform/verisilicon/hantro_postproc.c index e624cd98f41b..77d8ecfbe12f 100644 --- a/drivers/media/platform/verisilicon/hantro_postproc.c +++ b/drivers/media/platform/verisilicon/hantro_postproc.c @@ -107,7 +107,7 @@ static void hantro_postproc_g1_enable(struct hantro_ctx *ctx) static int down_scale_factor(struct hantro_ctx *ctx) { - if (ctx->src_fmt.width == ctx->dst_fmt.width) + if (ctx->src_fmt.width <= ctx->dst_fmt.width) return 0; return DIV_ROUND_CLOSEST(ctx->src_fmt.width, ctx->dst_fmt.width); From patchwork Thu Aug 24 09:21:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Gaignard X-Patchwork-Id: 716739 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 09980C83003 for ; Thu, 24 Aug 2023 09:22:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238302AbjHXJWV (ORCPT ); Thu, 24 Aug 2023 05:22:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57400 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240719AbjHXJVt (ORCPT ); Thu, 24 Aug 2023 05:21:49 -0400 Received: from madras.collabora.co.uk (madras.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e5ab]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 47DAC19A3; Thu, 24 Aug 2023 02:21:47 -0700 (PDT) Received: from benjamin-XPS-13-9310.. (unknown [IPv6:2a01:e0a:120:3210:672:c310:4c8a:3a97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: benjamin.gaignard) by madras.collabora.co.uk (Postfix) with ESMTPSA id C6EE46607340; Thu, 24 Aug 2023 10:21:45 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1692868906; bh=WDraZOgWi0izES0K9FdWnGrtWWF6tf7zOBBP/EoWBNg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Zq9oiDXUjZcdi9+7nMSjADzQn8H64qzRmsMgacOvIpUXGf8y0ICuEm9Xqb4im9sUF pKfE95AJtjfFIwNGSF0gm4P3pXcTi0LrGqMfKE2HZ/jiXDXzOfVK/6at/WKYNrSnnU n92uen5xlNd7B4cYgy/q/c6JSkvcQlxf+OnweOKN37FT+06nx56F2awaSXUFXOmBKk /eRQwbANk83lM6PMixAYlmYeP5jkb7eKhLBnXEmaC0Wff5AZEHwjj2ELaH2NHAsrNb SGFqxz8R8WiMJ/KD7B74Ig7/cdSZGDCBFj2FoBoi8eyr0/j9jrQcupPWVEvVVYV2Kq pnZXs+BDx1Qpw== From: Benjamin Gaignard To: mchehab@kernel.org, tfiga@chromium.org, m.szyprowski@samsung.com, ming.qian@nxp.com, ezequiel@vanguardiasur.com.ar, p.zabel@pengutronix.de, gregkh@linuxfoundation.org, hverkuil-cisco@xs4all.nl, nicolas.dufresne@collabora.com Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-arm-msm@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-staging@lists.linux.dev, kernel@collabora.com, Benjamin Gaignard Subject: [PATCH v5 08/10] media: verisilicon: vp9: Allow to change resolution while streaming Date: Thu, 24 Aug 2023 11:21:31 +0200 Message-Id: <20230824092133.39510-9-benjamin.gaignard@collabora.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230824092133.39510-1-benjamin.gaignard@collabora.com> References: <20230824092133.39510-1-benjamin.gaignard@collabora.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Remove all checks that prohibit to set a new format while streaming. This allow to change dynamically the resolution if the pixel format remains the same. Signed-off-by: Benjamin Gaignard --- .../media/platform/verisilicon/hantro_v4l2.c | 24 +++---------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/drivers/media/platform/verisilicon/hantro_v4l2.c b/drivers/media/platform/verisilicon/hantro_v4l2.c index f0d8b165abcd..27a1e77cca38 100644 --- a/drivers/media/platform/verisilicon/hantro_v4l2.c +++ b/drivers/media/platform/verisilicon/hantro_v4l2.c @@ -514,25 +514,14 @@ static int hantro_set_fmt_out(struct hantro_ctx *ctx, return ret; if (!ctx->is_encoder) { - struct vb2_queue *peer_vq; - /* * In order to support dynamic resolution change, * the decoder admits a resolution change, as long - * as the pixelformat remains. Can't be done if streaming. - */ - if (vb2_is_streaming(vq) || (vb2_is_busy(vq) && - pix_mp->pixelformat != ctx->src_fmt.pixelformat)) - return -EBUSY; - /* - * Since format change on the OUTPUT queue will reset - * the CAPTURE queue, we can't allow doing so - * when the CAPTURE queue has buffers allocated. + * as the pixelformat remains. */ - peer_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, - V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); - if (vb2_is_busy(peer_vq)) + if (vb2_is_streaming(vq) && pix_mp->pixelformat != ctx->src_fmt.pixelformat) { return -EBUSY; + } } else { /* * The encoder doesn't admit a format change if @@ -577,15 +566,8 @@ static int hantro_set_fmt_out(struct hantro_ctx *ctx, static int hantro_set_fmt_cap(struct hantro_ctx *ctx, struct v4l2_pix_format_mplane *pix_mp) { - struct vb2_queue *vq; int ret; - /* Change not allowed if queue is busy. */ - vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, - V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); - if (vb2_is_busy(vq)) - return -EBUSY; - if (ctx->is_encoder) { struct vb2_queue *peer_vq; From patchwork Thu Aug 24 09:21:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Gaignard X-Patchwork-Id: 716736 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1F805EE49B8 for ; Thu, 24 Aug 2023 09:22:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240745AbjHXJW3 (ORCPT ); Thu, 24 Aug 2023 05:22:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57428 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240586AbjHXJVv (ORCPT ); Thu, 24 Aug 2023 05:21:51 -0400 Received: from madras.collabora.co.uk (madras.collabora.co.uk [46.235.227.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4C8C219A4; Thu, 24 Aug 2023 02:21:48 -0700 (PDT) Received: from benjamin-XPS-13-9310.. (unknown [IPv6:2a01:e0a:120:3210:672:c310:4c8a:3a97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: benjamin.gaignard) by madras.collabora.co.uk (Postfix) with ESMTPSA id 4CABB6607359; Thu, 24 Aug 2023 10:21:46 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1692868906; bh=LwrSxMfFk/jqG93NZTcLWUZ/reWl4kmU9UYVlGmP5BY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QHIxp6+ecPCgD4LqXc5SdAI/cxAXQLLakBKi8N2xYlAsLD76pT/38eHzbVjp24Tgs isXey9eaf3NZ+te1HT0UuUG1La3IhFEp+W9t8kQYOtWBBkd/hcicT+pMIS6cKR7MXJ jh56hldALdQy9m8X3Scb6OfEsYJlhWTHSmf2Jlg8ZNUjVMyhxdeSAeAhtrp5D0S3eP C0AMWdVu5WuuTfANEgaicK4j4S00nsYLtKMSWK8odPBR3HE55ZvngSy16sHqxi2rcX 8vjhYJetQgWUQs0cjDk9/fBJPtdFQnq8dVhvNOGOzmgJ3OfA+ZrHNUkmpkOx8oxfzA 4CFy1Xc6SvVDw== From: Benjamin Gaignard To: mchehab@kernel.org, tfiga@chromium.org, m.szyprowski@samsung.com, ming.qian@nxp.com, ezequiel@vanguardiasur.com.ar, p.zabel@pengutronix.de, gregkh@linuxfoundation.org, hverkuil-cisco@xs4all.nl, nicolas.dufresne@collabora.com Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-arm-msm@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-staging@lists.linux.dev, kernel@collabora.com, Benjamin Gaignard Subject: [PATCH v5 09/10] media: v4l2: Add DELETE_BUFS ioctl Date: Thu, 24 Aug 2023 11:21:32 +0200 Message-Id: <20230824092133.39510-10-benjamin.gaignard@collabora.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230824092133.39510-1-benjamin.gaignard@collabora.com> References: <20230824092133.39510-1-benjamin.gaignard@collabora.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org VIDIOC_DELETE_BUFS ioctl allows to delete buffers from a queue. The number of buffers to delete in given by count field of struct v4l2_delete_buffers and the range start at the index specified in the same structure. Signed-off-by: Benjamin Gaignard --- .../userspace-api/media/v4l/user-func.rst | 1 + .../media/v4l/vidioc-delete-bufs.rst | 73 +++++++++++++++++++ .../media/common/videobuf2/videobuf2-core.c | 34 +++++++++ .../media/common/videobuf2/videobuf2-v4l2.c | 16 ++++ drivers/media/v4l2-core/v4l2-dev.c | 1 + drivers/media/v4l2-core/v4l2-ioctl.c | 17 +++++ include/media/v4l2-ioctl.h | 4 + include/media/videobuf2-core.h | 9 +++ include/media/videobuf2-v4l2.h | 11 +++ include/uapi/linux/videodev2.h | 17 +++++ 10 files changed, 183 insertions(+) create mode 100644 Documentation/userspace-api/media/v4l/vidioc-delete-bufs.rst diff --git a/Documentation/userspace-api/media/v4l/user-func.rst b/Documentation/userspace-api/media/v4l/user-func.rst index 15ff0bf7bbe6..3fd567695477 100644 --- a/Documentation/userspace-api/media/v4l/user-func.rst +++ b/Documentation/userspace-api/media/v4l/user-func.rst @@ -17,6 +17,7 @@ Function Reference vidioc-dbg-g-chip-info vidioc-dbg-g-register vidioc-decoder-cmd + vidioc-delete-bufs vidioc-dqevent vidioc-dv-timings-cap vidioc-encoder-cmd diff --git a/Documentation/userspace-api/media/v4l/vidioc-delete-bufs.rst b/Documentation/userspace-api/media/v4l/vidioc-delete-bufs.rst new file mode 100644 index 000000000000..a55fe6331fc8 --- /dev/null +++ b/Documentation/userspace-api/media/v4l/vidioc-delete-bufs.rst @@ -0,0 +1,73 @@ +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later +.. c:namespace:: V4L + +.. _VIDIOC_DELETE_BUFS: + +************************ +ioctl VIDIOC_DELETE_BUFS +************************ + +Name +==== + +VIDIOC_DELETE_BUFS - Deletes buffers from a queue + +Synopsis +======== + +.. c:macro:: VIDIOC_DELETE_BUFs + +``int ioctl(int fd, VIDIOC_DELETE_BUFs, struct v4l2_delete_buffers *argp)`` + +Arguments +========= + +``fd`` + File descriptor returned by :c:func:`open()`. + +``argp`` + Pointer to struct :c:type:`v4l2_delete_buffers`. + +Description +=========== + +Applications can optionally call the :ref:`VIDIOC_DELETE_BUFS` ioctl to +delete buffers from a queue. + +.. c:type:: v4l2_delete_buffers + +.. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.5cm}| + +.. flat-table:: struct v4l2_delete_buffers + :header-rows: 0 + :stub-columns: 0 + :widths: 1 1 2 + + * - __u32 + - ``index`` + - The starting buffer index to delete. + * - __u32 + - ``count`` + - The number of buffers to be deleted. + * - __u32 + - ``type`` + - Type of the stream or buffers, this is the same as the struct + :c:type:`v4l2_format` ``type`` field. See + :c:type:`v4l2_buf_type` for valid values. + * - __u32 + - ``reserved``\ [13] + - A place holder for future extensions. Drivers and applications + must set the array to zero. + +Return Value +============ + +On success 0 is returned, on error -1 and the ``errno`` variable is set +appropriately. The generic error codes are described at the +:ref:`Generic Error Codes ` chapter. + +EBUSY + File I/O is in progress. + +EINVAL + The buffer ``index`` doesn't exist in the queue. diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c index 70e36389b704..3d915b4c33b2 100644 --- a/drivers/media/common/videobuf2/videobuf2-core.c +++ b/drivers/media/common/videobuf2/videobuf2-core.c @@ -1634,6 +1634,40 @@ int vb2_core_prepare_buf(struct vb2_queue *q, unsigned int index, void *pb) } EXPORT_SYMBOL_GPL(vb2_core_prepare_buf); +int vb2_core_delete_buf(struct vb2_queue *q, unsigned int index) +{ + struct vb2_buffer *vb; + + vb = vb2_get_buffer(q, index); + if (!vb) { + dprintk(q, 1, "invalid buffer index %d\n", index); + return -EINVAL; + } + + if (vb->state != VB2_BUF_STATE_DEQUEUED) { + dprintk(q, 1, "can't delete non dequeued buffer index %d\n", index); + return -EINVAL; + } + + if (vb->planes[0].mem_priv) + call_void_vb_qop(vb, buf_cleanup, vb); + + /* Free MMAP buffers or release USERPTR buffers */ + if (q->memory == VB2_MEMORY_MMAP) + __vb2_buf_mem_free(vb); + else if (q->memory == VB2_MEMORY_DMABUF) + __vb2_buf_dmabuf_put(vb); + else + __vb2_buf_userptr_put(vb); + + vb2_queue_remove_buffer(q, vb); + kfree(vb); + + dprintk(q, 2, "buffer %d deleted\n", index); + return 0; +} +EXPORT_SYMBOL_GPL(vb2_core_delete_buf); + /* * vb2_start_streaming() - Attempt to start streaming. * @q: videobuf2 queue diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c index 724135d41f7f..ffe6b66a27f1 100644 --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c @@ -751,6 +751,22 @@ int vb2_prepare_buf(struct vb2_queue *q, struct media_device *mdev, } EXPORT_SYMBOL_GPL(vb2_prepare_buf); +int vb2_delete_bufs(struct vb2_queue *q, struct v4l2_delete_buffers *d) +{ + unsigned int index; + int ret = 0; + + for (index = d->index; index < d->index + d->count; index++) { + ret = vb2_core_delete_buf(q, index); + if (ret) + break; + } + + d->index = index; + return ret; +} +EXPORT_SYMBOL_GPL(vb2_delete_bufs); + int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create) { unsigned requested_planes = 1; diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index f81279492682..215654fd6581 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -720,6 +720,7 @@ static void determine_valid_ioctls(struct video_device *vdev) SET_VALID_IOCTL(ops, VIDIOC_PREPARE_BUF, vidioc_prepare_buf); SET_VALID_IOCTL(ops, VIDIOC_STREAMON, vidioc_streamon); SET_VALID_IOCTL(ops, VIDIOC_STREAMOFF, vidioc_streamoff); + SET_VALID_IOCTL(ops, VIDIOC_DELETE_BUFS, vidioc_delete_bufs); } if (is_vid || is_vbi || is_meta) { diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index f4d9d6279094..32336b9bb7e4 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -489,6 +489,13 @@ static void v4l_print_create_buffers(const void *arg, bool write_only) v4l_print_format(&p->format, write_only); } +static void v4l_print_delete_buffers(const void *arg, bool write_only) +{ + const struct v4l2_delete_buffers *p = arg; + + pr_cont("index=%d, count=%d\n", p->index, p->count); +} + static void v4l_print_streamparm(const void *arg, bool write_only) { const struct v4l2_streamparm *p = arg; @@ -2160,6 +2167,15 @@ static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops, return ret ? ret : ops->vidioc_prepare_buf(file, fh, b); } +static int v4l_delete_bufs(const struct v4l2_ioctl_ops *ops, + struct file *file, void *fh, void *arg) +{ + struct v4l2_delete_buffers *delete = arg; + int ret = check_fmt(file, delete->type); + + return ret ? ret : ops->vidioc_delete_bufs(file, fh, delete); +} + static int v4l_g_parm(const struct v4l2_ioctl_ops *ops, struct file *file, void *fh, void *arg) { @@ -2909,6 +2925,7 @@ static const struct v4l2_ioctl_info v4l2_ioctls[] = { IOCTL_INFO(VIDIOC_ENUM_FREQ_BANDS, v4l_enum_freq_bands, v4l_print_freq_band, 0), IOCTL_INFO(VIDIOC_DBG_G_CHIP_INFO, v4l_dbg_g_chip_info, v4l_print_dbg_chip_info, INFO_FL_CLEAR(v4l2_dbg_chip_info, match)), IOCTL_INFO(VIDIOC_QUERY_EXT_CTRL, v4l_query_ext_ctrl, v4l_print_query_ext_ctrl, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_query_ext_ctrl, id)), + IOCTL_INFO(VIDIOC_DELETE_BUFS, v4l_delete_bufs, v4l_print_delete_buffers, INFO_FL_QUEUE), }; #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h index edb733f21604..55afbde54211 100644 --- a/include/media/v4l2-ioctl.h +++ b/include/media/v4l2-ioctl.h @@ -163,6 +163,8 @@ struct v4l2_fh; * :ref:`VIDIOC_CREATE_BUFS ` ioctl * @vidioc_prepare_buf: pointer to the function that implements * :ref:`VIDIOC_PREPARE_BUF ` ioctl + * @vidioc_delete_bufs: pointer to the function that implements + * :ref:`VIDIOC_DELETE_BUFS ` ioctl * @vidioc_overlay: pointer to the function that implements * :ref:`VIDIOC_OVERLAY ` ioctl * @vidioc_g_fbuf: pointer to the function that implements @@ -422,6 +424,8 @@ struct v4l2_ioctl_ops { struct v4l2_create_buffers *b); int (*vidioc_prepare_buf)(struct file *file, void *fh, struct v4l2_buffer *b); + int (*vidioc_delete_bufs)(struct file *file, void *fh, + struct v4l2_delete_buffers *d); int (*vidioc_overlay)(struct file *file, void *fh, unsigned int i); int (*vidioc_g_fbuf)(struct file *file, void *fh, diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index ee9161b9fd64..c9ecc4214982 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -843,6 +843,15 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory, */ int vb2_core_prepare_buf(struct vb2_queue *q, unsigned int index, void *pb); +/** + * vb2_core_delete_buf() - + * @q: pointer to &struct vb2_queue with videobuf2 queue. + * @index: id number of the buffer. + * + * Return: returns zero on success; an error code otherwise. + */ +int vb2_core_delete_buf(struct vb2_queue *q, unsigned int index); + /** * vb2_core_qbuf() - Queue a buffer from userspace * diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h index 5a845887850b..2ef68fdf388f 100644 --- a/include/media/videobuf2-v4l2.h +++ b/include/media/videobuf2-v4l2.h @@ -118,6 +118,17 @@ int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create); */ int vb2_prepare_buf(struct vb2_queue *q, struct media_device *mdev, struct v4l2_buffer *b); +/** + * vb2_delete_bufs() - Delete buffers from the queue + * + * @q: pointer to &struct vb2_queue with videobuf2 queue. + * @d: delete parameter, passed from userspace to + * &v4l2_ioctl_ops->vidioc_delete_bufs handler in driver + * + * The return values from this function are intended to be directly returned + * from &v4l2_ioctl_ops->vidioc_delete_bufs handler in driver. + */ +int vb2_delete_bufs(struct vb2_queue *q, struct v4l2_delete_buffers *d); /** * vb2_qbuf() - Queue a buffer from userspace diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 78260e5d9985..4807b38e2a6f 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -2616,6 +2616,21 @@ struct v4l2_create_buffers { __u32 reserved[6]; }; +/** + * struct v4l2_delete_buffers - VIDIOC_DELETE_BUFS argument + * @index: the first buffer to be deleted + * @count: number of buffers to delete + * @type: enum v4l2_buf_type; buffer type (type == *_MPLANE for + * multiplanar buffers); + * @reserved: futur extensions + */ +struct v4l2_delete_buffers { + __u32 index; + __u32 count; + __u32 type; + __u32 reserved[13]; +}; + /* * I O C T L C O D E S F O R V I D E O D E V I C E S * @@ -2715,6 +2730,8 @@ struct v4l2_create_buffers { #define VIDIOC_DBG_G_CHIP_INFO _IOWR('V', 102, struct v4l2_dbg_chip_info) #define VIDIOC_QUERY_EXT_CTRL _IOWR('V', 103, struct v4l2_query_ext_ctrl) +#define VIDIOC_DELETE_BUFS _IOWR('V', 104, struct v4l2_delete_buffers) + /* Reminder: when adding new ioctls please add support for them to drivers/media/v4l2-core/v4l2-compat-ioctl32.c as well! */ From patchwork Thu Aug 24 09:21:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Gaignard X-Patchwork-Id: 716737 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0E420EE49B5 for ; Thu, 24 Aug 2023 09:22:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240751AbjHXJWa (ORCPT ); Thu, 24 Aug 2023 05:22:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57416 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232333AbjHXJVu (ORCPT ); Thu, 24 Aug 2023 05:21:50 -0400 Received: from madras.collabora.co.uk (madras.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e5ab]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5660019A5; Thu, 24 Aug 2023 02:21:48 -0700 (PDT) Received: from benjamin-XPS-13-9310.. (unknown [IPv6:2a01:e0a:120:3210:672:c310:4c8a:3a97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: benjamin.gaignard) by madras.collabora.co.uk (Postfix) with ESMTPSA id C936B6607377; Thu, 24 Aug 2023 10:21:46 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1692868907; bh=KdHmT/N4nUXTUxaDIqPZRUYfKvngYsyv9h4im11GNyE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=AX5+5UF6aH3FUNfnQYB6RIdCmMMJCd/9T1Uni+Qh7I8j8JmCKvhqNK5fyQL1vEQ+l EhtS/J07iJ/ewdsPOUrGnBHobOdQ6IQ4PKYmBrSXP7rNw1a0YoHhypbvvuQFP+2uTD c1Elx5Xv5wfSj9FoUzMM2zIosFyvAHqoD6U0L0qM28q1guznpEnKjF0pdG8H1BvueC weBw9Y/HMe1gaR2KXslLvJnXf2zWp4GXLYGE62121n/Ms8vZ9DODIMZMZZVdCjR9xu PRA05uEIa39VBxy1YFtBbNDn3mR6VUhSWJgWVXx9qyc+hvWqa7ycAIMeteSqJMPDRg nW/iKyv0iX06g== From: Benjamin Gaignard To: mchehab@kernel.org, tfiga@chromium.org, m.szyprowski@samsung.com, ming.qian@nxp.com, ezequiel@vanguardiasur.com.ar, p.zabel@pengutronix.de, gregkh@linuxfoundation.org, hverkuil-cisco@xs4all.nl, nicolas.dufresne@collabora.com Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, linux-arm-msm@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-staging@lists.linux.dev, kernel@collabora.com, Benjamin Gaignard Subject: [PATCH v5 10/10] media: v4l2: Add mem2mem helpers for DELETE_BUFS ioctl Date: Thu, 24 Aug 2023 11:21:33 +0200 Message-Id: <20230824092133.39510-11-benjamin.gaignard@collabora.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230824092133.39510-1-benjamin.gaignard@collabora.com> References: <20230824092133.39510-1-benjamin.gaignard@collabora.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Create v4l2-mem2mem helpers for VIDIOC_DELETE_BUFS ioctl. Signed-off-by: Benjamin Gaignard --- .../media/platform/verisilicon/hantro_v4l2.c | 1 + drivers/media/test-drivers/vim2m.c | 1 + drivers/media/v4l2-core/v4l2-mem2mem.c | 20 +++++++++++++++++++ include/media/v4l2-mem2mem.h | 12 +++++++++++ 4 files changed, 34 insertions(+) diff --git a/drivers/media/platform/verisilicon/hantro_v4l2.c b/drivers/media/platform/verisilicon/hantro_v4l2.c index 27a1e77cca38..0fd1c2fc78c8 100644 --- a/drivers/media/platform/verisilicon/hantro_v4l2.c +++ b/drivers/media/platform/verisilicon/hantro_v4l2.c @@ -756,6 +756,7 @@ const struct v4l2_ioctl_ops hantro_ioctl_ops = { .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, + .vidioc_delete_bufs = v4l2_m2m_ioctl_delete_bufs, .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, diff --git a/drivers/media/test-drivers/vim2m.c b/drivers/media/test-drivers/vim2m.c index 3e3b424b4860..3014b8ee13d0 100644 --- a/drivers/media/test-drivers/vim2m.c +++ b/drivers/media/test-drivers/vim2m.c @@ -960,6 +960,7 @@ static const struct v4l2_ioctl_ops vim2m_ioctl_ops = { .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, .vidioc_create_bufs = v4l2_m2m_ioctl_create_bufs, + .vidioc_delete_buf = v4l2_m2m_ioctl_delete_buf, .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, .vidioc_streamon = v4l2_m2m_ioctl_streamon, diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c index 0cc30397fbad..d1d59943680f 100644 --- a/drivers/media/v4l2-core/v4l2-mem2mem.c +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c @@ -831,6 +831,17 @@ int v4l2_m2m_prepare_buf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, } EXPORT_SYMBOL_GPL(v4l2_m2m_prepare_buf); +int v4l2_m2m_delete_bufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, + struct v4l2_delete_buffers *d) +{ + struct vb2_queue *vq; + + vq = v4l2_m2m_get_vq(m2m_ctx, d->type); + + return vb2_delete_bufs(vq, d); +} +EXPORT_SYMBOL_GPL(v4l2_m2m_delete_bufs); + int v4l2_m2m_create_bufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_create_buffers *create) { @@ -1377,6 +1388,15 @@ int v4l2_m2m_ioctl_create_bufs(struct file *file, void *priv, } EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_create_bufs); +int v4l2_m2m_ioctl_delete_bufs(struct file *file, void *priv, + struct v4l2_delete_buffers *d) +{ + struct v4l2_fh *fh = file->private_data; + + return v4l2_m2m_delete_bufs(file, fh->m2m_ctx, d); +} +EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_delete_bufs); + int v4l2_m2m_ioctl_querybuf(struct file *file, void *priv, struct v4l2_buffer *buf) { diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h index d6c8eb2b5201..161f85c42dc8 100644 --- a/include/media/v4l2-mem2mem.h +++ b/include/media/v4l2-mem2mem.h @@ -381,6 +381,16 @@ int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, int v4l2_m2m_prepare_buf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_buffer *buf); +/** + * v4l2_m2m_delete_bufs() - delete buffers from the queue + * + * @file: pointer to struct &file + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * @d: pointer to struct &v4l2_delete_buffers + */ +int v4l2_m2m_delete_bufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, + struct v4l2_delete_buffers *d); + /** * v4l2_m2m_create_bufs() - create a source or destination buffer, depending * on the type @@ -860,6 +870,8 @@ int v4l2_m2m_ioctl_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *rb); int v4l2_m2m_ioctl_create_bufs(struct file *file, void *fh, struct v4l2_create_buffers *create); +int v4l2_m2m_ioctl_delete_bufs(struct file *file, void *priv, + struct v4l2_delete_buffers *d); int v4l2_m2m_ioctl_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf); int v4l2_m2m_ioctl_expbuf(struct file *file, void *fh,