From patchwork Tue Oct 31 15:27:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Gaignard X-Patchwork-Id: 13441653 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 E58D4C4167B for ; Tue, 31 Oct 2023 15:27:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344814AbjJaP1f (ORCPT ); Tue, 31 Oct 2023 11:27:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43792 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344783AbjJaP1e (ORCPT ); Tue, 31 Oct 2023 11:27:34 -0400 Received: from madras.collabora.co.uk (madras.collabora.co.uk [46.235.227.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 21DDFE4 for ; Tue, 31 Oct 2023 08:27:32 -0700 (PDT) Received: from benjamin-XPS-13-9310.. (unknown [IPv6:2a01:e0a:120:3210:c562:2ef4:80c0:92f]) (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 9C27E66073A3; Tue, 31 Oct 2023 15:27:30 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1698766050; bh=k4/zDXxdjixxu0KdG6/i32m6c9v6+ezV2jMmBXNxNTU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=V0TIUat3eymdL2rFCTa8sqSmC8Z56W4S9QCsdUJ2Ixei7X09ouqoIJ3Aw3/5zho2S s0nPRoHugtbc37n3W2/Fa8hkrb693f8uNylMiRtWkURfwqfw7TOc9A7XRNgJhOWeM4 /k57klwglhKaj+4PL+gXHu2VdWjYcDXTkwzpsnqa82+t1SRNUOv3kcUeiSJi5fO9xY xJunakdgBKof8p5o7OuvNM0ItMWNCSEMDP7+i9g27pky0JB1sU24hAIDrn8gMws6Sm wbzzMPQ3cOkiJ8Sf6sMMmIU35iAbWXoBbsfotAsCm34ckKMdUPZ44q8mlXIi8IJ9p0 eVmMAiWjcNKIg== From: Benjamin Gaignard To: hverkuil-cisco@xs4all.nl, nicolas.dufresne@collabora.com, mchehab@kernel.org Cc: linux-media@vger.kernel.org, kernel@collabora.com, Benjamin Gaignard Subject: [PATCH v5 1/4] v4l-utils: Add max_num_buffers field to v4l2_create_buffers struct Date: Tue, 31 Oct 2023 16:27:19 +0100 Message-Id: <20231031152722.84444-2-benjamin.gaignard@collabora.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231031152722.84444-1-benjamin.gaignard@collabora.com> References: <20231031152722.84444-1-benjamin.gaignard@collabora.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add 'max_num_buffers' field to 'struct v4l2_create_buffers' and define V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS. Signed-off-by: Benjamin Gaignard --- include/linux/videodev2.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 27680a39..e7312cfb 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -991,6 +991,7 @@ struct v4l2_requestbuffers { #define V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS (1 << 4) #define V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF (1 << 5) #define V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS (1 << 6) +#define V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS (1 << 7) /** * struct v4l2_plane - plane info for multi-planar buffers @@ -2545,6 +2546,9 @@ struct v4l2_dbg_chip_info { * @flags: additional buffer management attributes (ignored unless the * queue has V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS capability * and configured for MMAP streaming I/O). + * @max_num_buffers: if V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS capability flag is set + * this field indicate the maximum possible number of buffers + * for this queue. * @reserved: future extensions */ struct v4l2_create_buffers { @@ -2554,7 +2558,8 @@ struct v4l2_create_buffers { struct v4l2_format format; __u32 capabilities; __u32 flags; - __u32 reserved[6]; + __u32 max_num_buffers; + __u32 reserved[5]; }; /* From patchwork Tue Oct 31 15:27:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Gaignard X-Patchwork-Id: 13441655 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 45B6DC41535 for ; Tue, 31 Oct 2023 15:27:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235093AbjJaP1h (ORCPT ); Tue, 31 Oct 2023 11:27:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43818 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344774AbjJaP1f (ORCPT ); Tue, 31 Oct 2023 11:27:35 -0400 Received: from madras.collabora.co.uk (madras.collabora.co.uk [46.235.227.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5B307F3 for ; Tue, 31 Oct 2023 08:27:32 -0700 (PDT) Received: from benjamin-XPS-13-9310.. (unknown [IPv6:2a01:e0a:120:3210:c562:2ef4:80c0:92f]) (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 E6A5366073AC; Tue, 31 Oct 2023 15:27:30 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1698766051; bh=XHEiW/XU21n00Bo7uZKln25/ZuLDUVVEzY+oMZhl4+I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nbgXfuv+jVMKfQuq2GUJh5mo0r9UBPL2+RiBz7JXgo+Oit2fefAx0yCE76GOThOL3 Qp4ol8wpT7yT7ibAVNWf+3ZtArXXFCksv/6I4R3bcneUvlNg/Mtj5EZNYhAmBCSxS4 eLCf9aXV5c2WXHsqZWs/y6exduBt2/BfI/ZOK9q+iNRBdd61JSSyrYf0YJMxeRKJPA 3lBGFKtWIZhMgu/+m0udSwAyG1KZ/C2ZqsUXHVpkAzjNWo9UaXoyXVKx5VF7KwWUiX 46ubhiuY3Jyg5nJHpYjcSoONigyHn+h3soZQWXDeolbordzScjr3P68Jxkwwx++Giy Zwh0r/VmJeGLQ== From: Benjamin Gaignard To: hverkuil-cisco@xs4all.nl, nicolas.dufresne@collabora.com, mchehab@kernel.org Cc: linux-media@vger.kernel.org, kernel@collabora.com, Benjamin Gaignard Subject: [PATCH v5 2/4] v4l2-compliance: Test queue maximum buffers allocation Date: Tue, 31 Oct 2023 16:27:20 +0100 Message-Id: <20231031152722.84444-3-benjamin.gaignard@collabora.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231031152722.84444-1-benjamin.gaignard@collabora.com> References: <20231031152722.84444-1-benjamin.gaignard@collabora.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org If V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS is set v4l2_create_buffers 'max_num_buffers' field reports the maximum number of buffers supported by the queue. Add a test to allocate this maximum value and make sure that one more allocation is failing. Display the flag in v4l2-ctl. Signed-off-by: Benjamin Gaignard --- version 5: - change g_max_buffers() to g_max_num_buffers(). - change v4l_queue_g_max_buffers() to v4l_queue_g_max_num_buffers(). - rename struct v4l_queue max_buffers field to max_num_buffers. - fix V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS name in bufcap_def array. - only test MMAP streaming mode. - rework test code. utils/common/cv4l-helpers.h | 1 + utils/common/v4l-helpers.h | 5 +++ utils/common/v4l2-info.cpp | 1 + utils/v4l2-compliance/v4l2-compliance.cpp | 1 + utils/v4l2-compliance/v4l2-compliance.h | 1 + utils/v4l2-compliance/v4l2-test-buffers.cpp | 41 +++++++++++++++++++++ 6 files changed, 50 insertions(+) diff --git a/utils/common/cv4l-helpers.h b/utils/common/cv4l-helpers.h index 91a04146..199aca36 100644 --- a/utils/common/cv4l-helpers.h +++ b/utils/common/cv4l-helpers.h @@ -743,6 +743,7 @@ public: unsigned g_type() const { return v4l_queue_g_type(this); } unsigned g_memory() const { return v4l_queue_g_memory(this); } unsigned g_buffers() const { return v4l_queue_g_buffers(this); } + unsigned g_max_num_buffers() const { return v4l_queue_g_max_num_buffers(this); } unsigned g_num_planes() const { return v4l_queue_g_num_planes(this); } unsigned g_capabilities() const { return v4l_queue_g_capabilities(this); } unsigned g_length(unsigned plane) const { return v4l_queue_g_length(this, plane); } diff --git a/utils/common/v4l-helpers.h b/utils/common/v4l-helpers.h index f8e96d58..cf0e92df 100644 --- a/utils/common/v4l-helpers.h +++ b/utils/common/v4l-helpers.h @@ -1429,6 +1429,7 @@ struct v4l_queue { unsigned mappings; unsigned num_planes; unsigned capabilities; + unsigned max_num_buffers; __u32 lengths[VIDEO_MAX_PLANES]; __u32 mem_offsets[VIDEO_MAX_FRAME][VIDEO_MAX_PLANES]; @@ -1453,6 +1454,7 @@ static inline void v4l_queue_init(struct v4l_queue *q, static inline unsigned v4l_queue_g_type(const struct v4l_queue *q) { return q->type; } static inline unsigned v4l_queue_g_memory(const struct v4l_queue *q) { return q->memory; } static inline unsigned v4l_queue_g_buffers(const struct v4l_queue *q) { return q->buffers; } +static inline unsigned v4l_queue_g_max_num_buffers(const struct v4l_queue *q) { return q->max_num_buffers; } static inline unsigned v4l_queue_g_mappings(const struct v4l_queue *q) { return q->mappings; } static inline unsigned v4l_queue_g_num_planes(const struct v4l_queue *q) { return q->num_planes; } static inline unsigned v4l_queue_g_capabilities(const struct v4l_queue *q) { return q->capabilities; } @@ -1587,6 +1589,9 @@ static inline int v4l_queue_create_bufs(struct v4l_fd *f, if (ret) return ret; q->capabilities = createbufs.capabilities; + q->max_num_buffers = 32; + if (q->capabilities & V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS) + q->max_num_buffers = createbufs.max_num_buffers; q->buffers += createbufs.count; return v4l_queue_querybufs(f, q, q->buffers - createbufs.count); } diff --git a/utils/common/v4l2-info.cpp b/utils/common/v4l2-info.cpp index 4f8c2aa7..5fc92005 100644 --- a/utils/common/v4l2-info.cpp +++ b/utils/common/v4l2-info.cpp @@ -206,6 +206,7 @@ static constexpr flag_def bufcap_def[] = { { V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS, "orphaned-bufs" }, { V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF, "m2m-hold-capture-buf" }, { V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS, "mmap-cache-hints" }, + { V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS, "set-max-num-buffers" }, { 0, nullptr } }; diff --git a/utils/v4l2-compliance/v4l2-compliance.cpp b/utils/v4l2-compliance/v4l2-compliance.cpp index ac6a8f80..a165ef5a 100644 --- a/utils/v4l2-compliance/v4l2-compliance.cpp +++ b/utils/v4l2-compliance/v4l2-compliance.cpp @@ -1453,6 +1453,7 @@ void testNode(struct node &node, struct node &node_m2m_cap, struct node &expbuf_ printf("Buffer ioctls%s:\n", suffix); printf("\ttest VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: %s\n", ok(testReqBufs(&node))); + printf("\ttest CREATE_BUFS maximum buffers: %s\n", ok(testCreateBufsMax(&node))); // Reopen after each streaming test to reset the streaming state // in case of any errors in the preceeding test. node.reopen(); diff --git a/utils/v4l2-compliance/v4l2-compliance.h b/utils/v4l2-compliance/v4l2-compliance.h index 7e3860c8..4f9aa17e 100644 --- a/utils/v4l2-compliance/v4l2-compliance.h +++ b/utils/v4l2-compliance/v4l2-compliance.h @@ -383,6 +383,7 @@ int testReqBufs(struct node *node); int testReadWrite(struct node *node); int testExpBuf(struct node *node); int testBlockingWait(struct node *node); +int testCreateBufsMax(struct node *node); // 32-bit architecture, 32/64-bit time_t tests int testTime32_64(struct node *node); diff --git a/utils/v4l2-compliance/v4l2-test-buffers.cpp b/utils/v4l2-compliance/v4l2-test-buffers.cpp index 6d592c9b..e3c3db46 100644 --- a/utils/v4l2-compliance/v4l2-test-buffers.cpp +++ b/utils/v4l2-compliance/v4l2-test-buffers.cpp @@ -761,6 +761,47 @@ int testReqBufs(struct node *node) return 0; } +int testCreateBufsMax(struct node *node) +{ + unsigned int i; + int ret; + + node->reopen(); + + cv4l_queue q(0, 0); + + for (i = 1; i <= V4L2_BUF_TYPE_LAST; i++) { + if (!(node->valid_buftypes & (1 << i))) + continue; + + q.init(i, V4L2_MEMORY_USERPTR); + ret = q.create_bufs(node, 1); + if (!ret && (q.g_capabilities() & V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS)) { + fail_on_test(q.create_bufs(node, q.g_max_buffers() - q.g_buffers())); + ret = q.create_bufs(node, 1); + fail_on_test(ret != ENOBUFS && (q.g_max_buffers() == q.g_buffers())); + } + + q.init(i, V4L2_MEMORY_MMAP); + ret = q.create_bufs(node, 1); + if (!ret && (q.g_capabilities() & V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS)) { + fail_on_test(q.create_bufs(node, q.g_max_buffers() - q.g_buffers())); + ret = q.create_bufs(node, 1); + fail_on_test(ret != ENOBUFS && (q.g_max_buffers() == q.g_buffers())); + } + + q.init(i, V4L2_MEMORY_DMABUF); + ret = q.create_bufs(node, 1); + if (!ret && (q.g_capabilities() & V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS)) { + fail_on_test(q.create_bufs(node, q.g_max_buffers() - q.g_buffers())); + ret = q.create_bufs(node, 1); + fail_on_test(ret != ENOBUFS && (q.g_max_buffers() == q.g_buffers())); + } + } + + return 0; +} + int testExpBuf(struct node *node) { bool have_expbuf = false; From patchwork Tue Oct 31 15:27:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Gaignard X-Patchwork-Id: 13441654 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 BE2EDC4167D for ; Tue, 31 Oct 2023 15:27:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344834AbjJaP1g (ORCPT ); Tue, 31 Oct 2023 11:27:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43808 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344792AbjJaP1e (ORCPT ); Tue, 31 Oct 2023 11:27:34 -0400 Received: from madras.collabora.co.uk (madras.collabora.co.uk [46.235.227.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BB945F4 for ; Tue, 31 Oct 2023 08:27:32 -0700 (PDT) Received: from benjamin-XPS-13-9310.. (unknown [IPv6:2a01:e0a:120:3210:c562:2ef4:80c0:92f]) (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 3BB1766073AD; Tue, 31 Oct 2023 15:27:31 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1698766051; bh=c7sHDpUD8KDZ/igbZBf8X/yhmzecELmuq/1rc3G8Zsk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=S55O9WHf22zs8Xud5iJcJ2YXPPDJVJvr6rcC1DbV+1DGT53q0g0/r+b4lg/JKUjHT bbJugWb86GnwrOEcVwIgHrRJ5tTpueA0uHeZYtunCrWwvKS2nvw4RQs2dUz/+KI2d0 2mY10IWwA0KBaNpxpTk56+L2Mq9zp1HDe6X8Jq/C/IPBBOBhzYnj6ZHgI1BZoCwlPn iMF6N0vdHkLAyYAsKpi6/8+b2XzHyQ7UBB3WRB/pdgpQQF1E+7CdbJUhpl2lsmRVwG V1m3gwymFVxV2ekzyq3EjeAVkYHSY3WVU6Bj1h8ve0MGF/8tAM5i1clBkEUWIikF8h WrKL/2uVLniaw== From: Benjamin Gaignard To: hverkuil-cisco@xs4all.nl, nicolas.dufresne@collabora.com, mchehab@kernel.org Cc: linux-media@vger.kernel.org, kernel@collabora.com, Benjamin Gaignard Subject: [PATCH v5 3/4] v4l2-utils: Add VIDIOC_DELETE_BUFS ioctl Date: Tue, 31 Oct 2023 16:27:21 +0100 Message-Id: <20231031152722.84444-4-benjamin.gaignard@collabora.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231031152722.84444-1-benjamin.gaignard@collabora.com> References: <20231031152722.84444-1-benjamin.gaignard@collabora.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add VIDIOC_DELETE_BUFS ioctl and it associated structure. Define V4L2_BUF_CAP_SUPPORTS_DELETE_BUFS to signal that queue support feature. Signed-off-by: Benjamin Gaignard --- include/linux/videodev2.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index e7312cfb..25690223 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -992,6 +992,7 @@ struct v4l2_requestbuffers { #define V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF (1 << 5) #define V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS (1 << 6) #define V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS (1 << 7) +#define V4L2_BUF_CAP_SUPPORTS_DELETE_BUFS (1 << 8) /** * struct v4l2_plane - plane info for multi-planar buffers @@ -2562,6 +2563,20 @@ struct v4l2_create_buffers { __u32 reserved[5]; }; +/** + * 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 + * @reserved: future 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 * @@ -2661,6 +2676,7 @@ 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 Tue Oct 31 15:27:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Gaignard X-Patchwork-Id: 13441656 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 CC2C2C4332F for ; Tue, 31 Oct 2023 15:27:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344982AbjJaP1h (ORCPT ); Tue, 31 Oct 2023 11:27:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43856 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231691AbjJaP1g (ORCPT ); Tue, 31 Oct 2023 11:27:36 -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 1AC2DFC for ; Tue, 31 Oct 2023 08:27:33 -0700 (PDT) Received: from benjamin-XPS-13-9310.. (unknown [IPv6:2a01:e0a:120:3210:c562:2ef4:80c0:92f]) (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 8539C66073AE; Tue, 31 Oct 2023 15:27:31 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1698766051; bh=9HbToHk5C511pzDLCfR+pNxQxQRxo/q/4e/zj81d4ss=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cufgcoKn4vcwS514CxuAtnQ2I/cXE4fJ1peisOV1RZ77YNsevQgJvAOjgrZWLnaCK gFDXi2h8FzvHG6SgGVXgqWsO2usxibBrMNVHtVTSIm3WCAcWjDD6RHBqInzbJDXHqg Ve417fzb49JP6Pj3FWIuJewmrJKnONOZR6MWS1cwakJNlSI/LOkMoV91Ii6cliSecx Pvcf1LRVlg5Zfc7Ma94jFTrL2CAJseEk6NOXowTTjTiMbJ4iJb0Mo9YTszGkL/gQoe r8kTdosjneyccqv2TRsNRiDdufIQwesqj8mFOH9DYjzEZdAuTsKB2kcJ0v1113Piab pJznpoKDIPWNw== From: Benjamin Gaignard To: hverkuil-cisco@xs4all.nl, nicolas.dufresne@collabora.com, mchehab@kernel.org Cc: linux-media@vger.kernel.org, kernel@collabora.com, Benjamin Gaignard Subject: [PATCH v5 4/4] v4l2-compliance: Add a test for DELETE_BUFS ioctl Date: Tue, 31 Oct 2023 16:27:22 +0100 Message-Id: <20231031152722.84444-5-benjamin.gaignard@collabora.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231031152722.84444-1-benjamin.gaignard@collabora.com> References: <20231031152722.84444-1-benjamin.gaignard@collabora.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Add new test for DELETE_BUFS ioctl. It create buffers and check if they could be removed from queue. It also check that removing non existing buffer or a queued buffer failed. Signed-off-by: Benjamin Gaignard --- version 5: - add V4L2_BUF_CAP_SUPPORTS_DELETE_BUFS in bufcap_def array. utils/common/cv4l-helpers.h | 4 + utils/common/v4l-helpers.h | 17 +++ utils/common/v4l2-info.cpp | 1 + utils/v4l2-compliance/v4l2-compliance.cpp | 1 + utils/v4l2-compliance/v4l2-compliance.h | 1 + utils/v4l2-compliance/v4l2-test-buffers.cpp | 121 ++++++++++++++++---- 6 files changed, 125 insertions(+), 20 deletions(-) diff --git a/utils/common/cv4l-helpers.h b/utils/common/cv4l-helpers.h index 199aca36..5fe23cc6 100644 --- a/utils/common/cv4l-helpers.h +++ b/utils/common/cv4l-helpers.h @@ -760,6 +760,10 @@ public: { return v4l_queue_reqbufs(fd->g_v4l_fd(), this, count, flags); } + int delete_bufs(cv4l_fd *fd, unsigned index = 0, unsigned count = 0) + { + return v4l_queue_delete_bufs(fd->g_v4l_fd(), this, index, count); + } bool has_create_bufs(cv4l_fd *fd) const { return v4l_queue_has_create_bufs(fd->g_v4l_fd(), this); diff --git a/utils/common/v4l-helpers.h b/utils/common/v4l-helpers.h index cf0e92df..dca11e2d 100644 --- a/utils/common/v4l-helpers.h +++ b/utils/common/v4l-helpers.h @@ -1510,6 +1510,23 @@ static inline void *v4l_queue_g_dataptr(const struct v4l_queue *q, unsigned inde return v4l_queue_g_mmapping(q, index, plane); } +static inline int v4l_queue_delete_bufs(struct v4l_fd *f, struct v4l_queue *q, unsigned index, unsigned count) +{ + struct v4l2_delete_buffers deletebufs; + int ret; + + memset(&deletebufs, 0, sizeof(deletebufs)); + deletebufs.type = q->type; + deletebufs.index = index; + deletebufs.count = count; + + ret = v4l_ioctl(f, VIDIOC_DELETE_BUFS, &deletebufs); + if (!ret) + q->buffers -= deletebufs.count; + + return ret; +} + static inline int v4l_queue_querybufs(struct v4l_fd *f, struct v4l_queue *q, unsigned from) { unsigned b, p; diff --git a/utils/common/v4l2-info.cpp b/utils/common/v4l2-info.cpp index 5fc92005..9ff107d9 100644 --- a/utils/common/v4l2-info.cpp +++ b/utils/common/v4l2-info.cpp @@ -207,6 +207,7 @@ static constexpr flag_def bufcap_def[] = { { V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF, "m2m-hold-capture-buf" }, { V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS, "mmap-cache-hints" }, { V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS, "set-max-num-buffers" }, + { V4L2_BUF_CAP_SUPPORTS_DELETE_BUFS, "delete-bufs" }, { 0, nullptr } }; diff --git a/utils/v4l2-compliance/v4l2-compliance.cpp b/utils/v4l2-compliance/v4l2-compliance.cpp index a165ef5a..c1e519ea 100644 --- a/utils/v4l2-compliance/v4l2-compliance.cpp +++ b/utils/v4l2-compliance/v4l2-compliance.cpp @@ -1454,6 +1454,7 @@ void testNode(struct node &node, struct node &node_m2m_cap, struct node &expbuf_ printf("Buffer ioctls%s:\n", suffix); printf("\ttest VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: %s\n", ok(testReqBufs(&node))); printf("\ttest CREATE_BUFS maximum buffers: %s\n", ok(testCreateBufsMax(&node))); + printf("\ttest VIDIOC_DELETE_BUFS: %s\n", ok(testDeleteBufs(&node))); // Reopen after each streaming test to reset the streaming state // in case of any errors in the preceeding test. node.reopen(); diff --git a/utils/v4l2-compliance/v4l2-compliance.h b/utils/v4l2-compliance/v4l2-compliance.h index 4f9aa17e..9ec07494 100644 --- a/utils/v4l2-compliance/v4l2-compliance.h +++ b/utils/v4l2-compliance/v4l2-compliance.h @@ -384,6 +384,7 @@ int testReadWrite(struct node *node); int testExpBuf(struct node *node); int testBlockingWait(struct node *node); int testCreateBufsMax(struct node *node); +int testDeleteBufs(struct node *node); // 32-bit architecture, 32/64-bit time_t tests int testTime32_64(struct node *node); diff --git a/utils/v4l2-compliance/v4l2-test-buffers.cpp b/utils/v4l2-compliance/v4l2-test-buffers.cpp index e3c3db46..4eb2d8f4 100644 --- a/utils/v4l2-compliance/v4l2-test-buffers.cpp +++ b/utils/v4l2-compliance/v4l2-test-buffers.cpp @@ -529,6 +529,97 @@ static int testCanSetSameTimings(struct node *node) return 0; } +int testDeleteBufs(struct node *node) +{ + int ret; + unsigned i; + + node->reopen(); + + for (i = 1; i <= V4L2_BUF_TYPE_LAST; i++) { + struct v4l2_delete_buffers delbufs = { }; + + if (!(node->valid_buftypes & (1 << i))) + continue; + + cv4l_queue q(i, V4L2_MEMORY_MMAP); + + if (testSetupVbi(node, i)) + continue; + + q.init(i, V4L2_MEMORY_MMAP); + ret = q.create_bufs(node, 0); + fail_on_test_val(ret && ret != EINVAL, ret); + if (!(q.g_capabilities() & V4L2_BUF_CAP_SUPPORTS_DELETE_BUFS)) + continue; + + memset(&delbufs, 0xff, sizeof(delbufs)); + delbufs.index = 0; + delbufs.count = 0; + delbufs.type = q.g_type(); + fail_on_test(doioctl(node, VIDIOC_DELETE_BUFS, &delbufs)); + fail_on_test(check_0(delbufs.reserved, sizeof(delbufs.reserved))); + + if (!ret) { + unsigned buffers; + buffer buf(q); + + /* Create only 1 buffer */ + fail_on_test(q.create_bufs(node, 1)); + buffers = q.g_buffers(); + fail_on_test(buffers == 0); + /* Delete buffer index 1 must fail */ + fail_on_test(q.delete_bufs(node, 1, buffers) != EINVAL); + /* Delete buffer index 0 is valid */ + fail_on_test(q.delete_bufs(node, 0, buffers)); + /* Delete buffer index 0 again must fail */ + fail_on_test(q.delete_bufs(node, 0, 1) != EINVAL); + /* Create 3 buffers indexes 0 to 2 */ + fail_on_test(q.create_bufs(node, 3)); + /* Delete them one by one */ + fail_on_test(q.delete_bufs(node, 2, 1)); + fail_on_test(q.delete_bufs(node, 0, 1)); + fail_on_test(q.delete_bufs(node, 1, 1)); + /* Delete buffer index 0 again must fail */ + fail_on_test(q.delete_bufs(node, 0, 1) != EINVAL); + + /* Create 5 buffers indexes 0 to 4*/ + fail_on_test(q.create_bufs(node, 5)); + /* Delete buffers index 1 and 2 */ + fail_on_test(q.delete_bufs(node, 1, 2)); + /* Add 3 more buffers should be indexes 5 to 7*/ + fail_on_test(q.create_bufs(node, 3)); + /* Query buffers: + * 1 and 2 have been deleted they must fail + * 5 to 7 must exist*/ + fail_on_test(buf.querybuf(node, 1) != EINVAL); + fail_on_test(buf.querybuf(node, 2) != EINVAL); + fail_on_test(buf.querybuf(node, 5)); + fail_on_test(buf.querybuf(node, 6)); + fail_on_test(buf.querybuf(node, 7)); + /* Delete existing buffer index 7 with bad type must fail */ + memset(&delbufs, 0xff, sizeof(delbufs)); + delbufs.index = 7; + delbufs.count = 1; + delbufs.type = 0; + fail_on_test(doioctl(node, VIDIOC_DELETE_BUFS, &delbufs) != EINVAL); + + /* Delete crossing max allowed buffers boundary must fail */ + fail_on_test(q.delete_bufs(node, q.g_max_num_buffers() - 2, 8) != EINVAL); + + /* Delete overflow must fail */ + fail_on_test(q.delete_bufs(node, 3, 0xfffffff) != EINVAL); + + /* Create 2 buffers, that must fill the hole */ + fail_on_test(q.create_bufs(node, 2)); + /* Remove all buffers */ + fail_on_test(q.delete_bufs(node, 0, 8)); + } + } + + return 0; +} + int testReqBufs(struct node *node) { struct v4l2_create_buffers crbufs = { }; @@ -773,29 +864,19 @@ int testCreateBufsMax(struct node *node) for (i = 1; i <= V4L2_BUF_TYPE_LAST; i++) { if (!(node->valid_buftypes & (1 << i))) continue; - - q.init(i, V4L2_MEMORY_USERPTR); - ret = q.create_bufs(node, 1); - if (!ret && (q.g_capabilities() & V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS)) { - fail_on_test(q.create_bufs(node, q.g_max_buffers() - q.g_buffers())); - ret = q.create_bufs(node, 1); - fail_on_test(ret != ENOBUFS && (q.g_max_buffers() == q.g_buffers())); - } - + q.init(i, V4L2_MEMORY_MMAP); - ret = q.create_bufs(node, 1); - if (!ret && (q.g_capabilities() & V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS)) { - fail_on_test(q.create_bufs(node, q.g_max_buffers() - q.g_buffers())); - ret = q.create_bufs(node, 1); - fail_on_test(ret != ENOBUFS && (q.g_max_buffers() == q.g_buffers())); - } - - q.init(i, V4L2_MEMORY_DMABUF); - ret = q.create_bufs(node, 1); + ret = q.create_bufs(node, 0); if (!ret && (q.g_capabilities() & V4L2_BUF_CAP_SUPPORTS_MAX_NUM_BUFFERS)) { - fail_on_test(q.create_bufs(node, q.g_max_buffers() - q.g_buffers())); + fail_on_test(q.create_bufs(node, q.g_max_num_buffers())); + /* Some drivers may not have allocated all the requested buffers + * because of memory limitation, that is OK but make the next test + * failed so skip it + */ + if (q.g_max_num_buffers() != q.g_buffers()) + continue; ret = q.create_bufs(node, 1); - fail_on_test(ret != ENOBUFS && (q.g_max_buffers() == q.g_buffers())); + fail_on_test(ret != ENOBUFS); } }