From nobody Fri Sep 20 11:46:28 2024 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 E7904E7490B for ; Mon, 2 Oct 2023 12:07:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237198AbjJBMHO (ORCPT ); Mon, 2 Oct 2023 08:07:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37446 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237008AbjJBMGf (ORCPT ); Mon, 2 Oct 2023 08:06:35 -0400 Received: from madras.collabora.co.uk (madras.collabora.co.uk [46.235.227.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5DD32D3; Mon, 2 Oct 2023 05:06:32 -0700 (PDT) Received: from benjamin-XPS-13-9310.. (unknown [IPv6:2a01:e0a:120:3210:9537:67ca:c85e:d0ae]) (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 D97756607313; Mon, 2 Oct 2023 13:06:30 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1696248391; bh=SAeY42mn7okUVm4y/MjfOqXArg04FnSae3v/ubK/uiU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=X6zsPuoQKjf6cZ/I8dEFANqv5kYJaRUCnnH4RW3j2/Bh5dr5aNE/7xIAPWX1e5rKn ObvovcbuR1nE+oRCDKI79rHKSAF2zsi5/DSDEcFtAfnYkPLdt9WUg3Gcv69LnBgVUQ 7X20b3yHWSzgwmhIloEn6NNSwfJ//GOWSxt677CyZkOvrC+ttpfKhQCt3fadixv7xs 4IC3+aXKW0mI5+zsVKcyYt/r2nWNFS4zuL23h12AWimupBq6txoRTy+NuasqPc0w9m wv/IkFfrBRWlJDNo8fKV8ryY2L+Gpk53rtP14U40t8jwujrT1tdmRbEUA3lybvOCE0 noLwN3fXKcsjA== 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 v9 12/53] media: videobuf2: Be more flexible on the number of queue stored buffers Date: Mon, 2 Oct 2023 14:05:36 +0200 Message-Id: <20231002120617.119602-13-benjamin.gaignard@collabora.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231002120617.119602-1-benjamin.gaignard@collabora.com> References: <20231002120617.119602-1-benjamin.gaignard@collabora.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add 'max_num_buffers' field in vb2_queue struct to let drivers decide how many buffers could be stored in a queue. This require '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 Signed-off-by: Hans Verkuil Signed-off-by: Hans V= erkuil --- changes in version 9: - Correctly initialize max_num_buffers in vb2_core_queue_init() .../media/common/videobuf2/videobuf2-core.c | 41 +++++++++++++++---- .../media/common/videobuf2/videobuf2-v4l2.c | 4 +- include/media/videobuf2-core.h | 4 +- 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/medi= a/common/videobuf2/videobuf2-core.c index 9c9eef6ee423..098966846e12 100644 --- a/drivers/media/common/videobuf2/videobuf2-core.c +++ b/drivers/media/common/videobuf2/videobuf2-core.c @@ -412,7 +412,7 @@ static void init_buffer_cache_hints(struct vb2_queue *q= , struct vb2_buffer *vb) */ static void vb2_queue_add_buffer(struct vb2_queue *q, struct vb2_buffer *v= b, unsigned int index) { - WARN_ON(index >=3D VB2_MAX_FRAME || q->bufs[index]); + WARN_ON(index >=3D q->max_num_buffers || q->bufs[index]); =20 q->bufs[index] =3D vb; vb->index =3D index; @@ -444,9 +444,9 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum = vb2_memory memory, struct vb2_buffer *vb; int ret; =20 - /* Ensure that q->num_buffers+num_buffers is below VB2_MAX_FRAME */ + /* Ensure that the number of already queue + num_buffers is below q->max_= num_buffers */ num_buffers =3D min_t(unsigned int, num_buffers, - VB2_MAX_FRAME - q->num_buffers); + q->max_num_buffers - q->num_buffers); =20 for (buffer =3D 0; buffer < num_buffers; ++buffer) { /* Allocate vb2 buffer structures */ @@ -805,7 +805,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memo= ry memory, unsigned plane_sizes[VB2_MAX_PLANES] =3D { }; bool non_coherent_mem =3D flags & V4L2_MEMORY_FLAG_NON_COHERENT; unsigned int i; - int ret; + int ret =3D 0; =20 if (q->streaming) { dprintk(q, 1, "streaming active\n"); @@ -849,17 +849,22 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_me= mory memory, /* * Make sure the requested values and current defaults are sane. */ - WARN_ON(q->min_buffers_needed > VB2_MAX_FRAME); num_buffers =3D max_t(unsigned int, *count, q->min_buffers_needed); - num_buffers =3D min_t(unsigned int, num_buffers, VB2_MAX_FRAME); + num_buffers =3D min_t(unsigned int, num_buffers, q->max_num_buffers); memset(q->alloc_devs, 0, sizeof(q->alloc_devs)); /* * Set this now to ensure that drivers see the correct q->memory value * in the queue_setup op. */ mutex_lock(&q->mmap_lock); + if (!q->bufs) + q->bufs =3D kcalloc(q->max_num_buffers, sizeof(*q->bufs), GFP_KERNEL); + if (!q->bufs) + ret =3D -ENOMEM; q->memory =3D memory; mutex_unlock(&q->mmap_lock); + if (ret) + return ret; set_queue_coherency(q, non_coherent_mem); =20 /* @@ -965,9 +970,9 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_= memory memory, unsigned plane_sizes[VB2_MAX_PLANES] =3D { }; bool non_coherent_mem =3D flags & V4L2_MEMORY_FLAG_NON_COHERENT; bool no_previous_buffers =3D !q->num_buffers; - int ret; + int ret =3D 0; =20 - if (q->num_buffers =3D=3D VB2_MAX_FRAME) { + if (q->num_buffers =3D=3D q->max_num_buffers) { dprintk(q, 1, "maximum number of buffers already allocated\n"); return -ENOBUFS; } @@ -984,7 +989,13 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2= _memory memory, */ mutex_lock(&q->mmap_lock); q->memory =3D memory; + if (!q->bufs) + q->bufs =3D kcalloc(q->max_num_buffers, sizeof(*q->bufs), GFP_KERNEL); + if (!q->bufs) + ret =3D -ENOMEM; mutex_unlock(&q->mmap_lock); + if (ret) + return ret; q->waiting_for_buffers =3D !q->is_output; set_queue_coherency(q, non_coherent_mem); } else { @@ -996,7 +1007,7 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2= _memory memory, return -EINVAL; } =20 - num_buffers =3D min(*count, VB2_MAX_FRAME - q->num_buffers); + num_buffers =3D min(*count, q->max_num_buffers - q->num_buffers); =20 if (requested_planes && requested_sizes) { num_planes =3D requested_planes; @@ -2455,6 +2466,12 @@ int vb2_core_queue_init(struct vb2_queue *q) /* * Sanity check */ + if (!q->max_num_buffers) + q->max_num_buffers =3D VB2_MAX_FRAME; + + /* The maximum is limited by offset cookie encoding pattern */ + q->max_num_buffers =3D min_t(unsigned int, q->max_num_buffers, BUFFER_IND= EX_MASK + 1); + if (WARN_ON(!q) || WARN_ON(!q->ops) || WARN_ON(!q->mem_ops) || @@ -2464,6 +2481,10 @@ int vb2_core_queue_init(struct vb2_queue *q) WARN_ON(!q->ops->buf_queue)) return -EINVAL; =20 + if (WARN_ON(q->max_num_buffers > BUFFER_INDEX_MASK + 1) || + WARN_ON(q->min_buffers_needed > q->max_num_buffers)) + return -EINVAL; + if (WARN_ON(q->requires_requests && !q->supports_requests)) return -EINVAL; =20 @@ -2510,6 +2531,8 @@ 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); + q->bufs =3D NULL; mutex_unlock(&q->mmap_lock); } EXPORT_SYMBOL_GPL(vb2_core_queue_release); diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/medi= a/common/videobuf2/videobuf2-v4l2.c index 3395e702ad1f..278ea1107b01 100644 --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c @@ -1156,7 +1156,7 @@ int _vb2_fop_release(struct file *file, struct mutex = *lock) =20 if (lock) mutex_lock(lock); - if (file->private_data =3D=3D vdev->queue->owner) { + if (!vdev->queue->owner || file->private_data =3D=3D vdev->queue->owner) { vb2_queue_release(vdev->queue); vdev->queue->owner =3D NULL; } @@ -1284,7 +1284,7 @@ void vb2_video_unregister_device(struct video_device = *vdev) */ get_device(&vdev->dev); video_unregister_device(vdev); - if (vdev->queue && vdev->queue->owner) { + if (vdev->queue) { struct mutex *lock =3D vdev->queue->lock ? vdev->queue->lock : vdev->lock; =20 diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index cd3ff1cd759d..1d6d68e8a711 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_num_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_num_buffers; =20 struct list_head queued_list; unsigned int queued_count; --=20 2.39.2