Patch Detail
Show a patch.
GET /api/patches/20730/?format=api
{ "id": 20730, "url": "https://patchwork.libcamera.org/api/patches/20730/?format=api", "web_url": "https://patchwork.libcamera.org/patch/20730/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20240731135936.2105-2-laurent.pinchart@ideasonboard.com>", "date": "2024-07-31T13:59:33", "name": "[v2,1/4] libcamera: base: Add MemFd helper class", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": false, "hash": "a3c770fe5090bfd17287973367edd01d2503d3c1", "submitter": { "id": 2, "url": "https://patchwork.libcamera.org/api/people/2/?format=api", "name": "Laurent Pinchart", "email": "laurent.pinchart@ideasonboard.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/20730/mbox/", "series": [ { "id": 4470, "url": "https://patchwork.libcamera.org/api/series/4470/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=4470", "date": "2024-07-31T13:59:32", "name": "libcamera: Address soft ISP file seal TODO item", "version": 2, "mbox": "https://patchwork.libcamera.org/series/4470/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/20730/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/20730/checks/", "tags": {}, "headers": { "Return-Path": "<libcamera-devel-bounces@lists.libcamera.org>", "X-Original-To": "parsemail@patchwork.libcamera.org", "Delivered-To": "parsemail@patchwork.libcamera.org", "Received": [ "from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id A9FF0C32BB\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 31 Jul 2024 14:00:02 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 3658E63379;\n\tWed, 31 Jul 2024 16:00:02 +0200 (CEST)", "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 713BB6198E\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 31 Jul 2024 15:59:59 +0200 (CEST)", "from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi\n\t[81.175.209.231])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 5B86DF85\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 31 Jul 2024 15:59:11 +0200 (CEST)" ], "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"iZH+jKzO\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1722434351;\n\tbh=eqHwR1evMb7EhKijHWNnlouTO3Bknq5MaVJwRTQNs04=;\n\th=From:To:Subject:Date:In-Reply-To:References:From;\n\tb=iZH+jKzOlUjZNNH3APtdV9DHUI8Z9ZLpC6odr430uih4Z1zXpgc5wjT/daujBJ8E8\n\temv+TQcYaaWe1X0ow1RxcwUh9j1xV+G+4C5ebOweqSFOXddEp0GxxbyVGuU8otlCEZ\n\ttbG49HJVm6ovGSwhurg/9d/3Mk7xMr48/z7LkUto=", "From": "Laurent Pinchart <laurent.pinchart@ideasonboard.com>", "To": "libcamera-devel@lists.libcamera.org", "Subject": "[PATCH v2 1/4] libcamera: base: Add MemFd helper class", "Date": "Wed, 31 Jul 2024 16:59:33 +0300", "Message-ID": "<20240731135936.2105-2-laurent.pinchart@ideasonboard.com>", "X-Mailer": "git-send-email 2.44.2", "In-Reply-To": "<20240731135936.2105-1-laurent.pinchart@ideasonboard.com>", "References": "<20240731135936.2105-1-laurent.pinchart@ideasonboard.com>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "X-BeenThere": "libcamera-devel@lists.libcamera.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "<libcamera-devel.lists.libcamera.org>", "List-Unsubscribe": "<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>", "List-Archive": "<https://lists.libcamera.org/pipermail/libcamera-devel/>", "List-Post": "<mailto:libcamera-devel@lists.libcamera.org>", "List-Help": "<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>", "List-Subscribe": "<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>", "Errors-To": "libcamera-devel-bounces@lists.libcamera.org", "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>" }, "content": "libcamera creates memfds in two locations already, duplicating some\ncode. Move the code to a new MemFd helper class.\n\nSigned-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\nReviewed-by: Milan Zamazal <mzamazal@redhat.com>\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n---\n include/libcamera/base/memfd.h | 34 ++++++++\n include/libcamera/base/meson.build | 1 +\n src/libcamera/base/memfd.cpp | 116 ++++++++++++++++++++++++++++\n src/libcamera/base/meson.build | 1 +\n src/libcamera/dma_buf_allocator.cpp | 46 +----------\n src/libcamera/shared_mem_object.cpp | 21 ++---\n 6 files changed, 161 insertions(+), 58 deletions(-)\n create mode 100644 include/libcamera/base/memfd.h\n create mode 100644 src/libcamera/base/memfd.cpp", "diff": "diff --git a/include/libcamera/base/memfd.h b/include/libcamera/base/memfd.h\nnew file mode 100644\nindex 000000000000..b0edd2de5d83\n--- /dev/null\n+++ b/include/libcamera/base/memfd.h\n@@ -0,0 +1,34 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2024, Ideas on Board Oy\n+ *\n+ * Anonymous file creation\n+ */\n+\n+#pragma once\n+\n+#include <stddef.h>\n+\n+#include <libcamera/base/flags.h>\n+#include <libcamera/base/unique_fd.h>\n+\n+namespace libcamera {\n+\n+class MemFd\n+{\n+public:\n+\tenum class Seal {\n+\t\tNone = 0,\n+\t\tShrink = (1 << 0),\n+\t\tGrow = (1 << 1),\n+\t};\n+\n+\tusing Seals = Flags<Seal>;\n+\n+\tstatic UniqueFD create(const char *name, std::size_t size,\n+\t\t\t Seals seals = Seal::None);\n+};\n+\n+LIBCAMERA_FLAGS_ENABLE_OPERATORS(MemFd::Seal)\n+\n+} /* namespace libcamera */\ndiff --git a/include/libcamera/base/meson.build b/include/libcamera/base/meson.build\nindex bace25d56b13..2a0cee317204 100644\n--- a/include/libcamera/base/meson.build\n+++ b/include/libcamera/base/meson.build\n@@ -21,6 +21,7 @@ libcamera_base_private_headers = files([\n 'event_notifier.h',\n 'file.h',\n 'log.h',\n+ 'memfd.h',\n 'message.h',\n 'mutex.h',\n 'private.h',\ndiff --git a/src/libcamera/base/memfd.cpp b/src/libcamera/base/memfd.cpp\nnew file mode 100644\nindex 000000000000..72474307af09\n--- /dev/null\n+++ b/src/libcamera/base/memfd.cpp\n@@ -0,0 +1,116 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2024, Ideas on Board Oy\n+ *\n+ * Anonymous file creation\n+ */\n+\n+#include <libcamera/base/memfd.h>\n+\n+#include <fcntl.h>\n+#include <string.h>\n+#include <sys/mman.h>\n+#include <sys/syscall.h>\n+#include <unistd.h>\n+\n+#include <libcamera/base/log.h>\n+\n+/**\n+ * \\file base/memfd.h\n+ * \\brief Anonymous file creation\n+ */\n+\n+/* uClibc doesn't provide the file sealing API. */\n+#ifndef __DOXYGEN__\n+#if not HAVE_FILE_SEALS\n+#define F_ADD_SEALS\t\t1033\n+#define F_SEAL_SHRINK\t\t0x0002\n+#define F_SEAL_GROW\t\t0x0004\n+#endif\n+#endif\n+\n+namespace libcamera {\n+\n+LOG_DECLARE_CATEGORY(File)\n+\n+/**\n+ * \\class MemFd\n+ * \\brief Helper class to create anonymous files\n+ *\n+ * Anonymous files behave like regular files, and can be modified, truncated,\n+ * memory-mapped and so on. Unlike regular files, they however live in RAM and\n+ * don't have permanent backing storage.\n+ */\n+\n+/**\n+ * \\enum MemFd::Seal\n+ * \\brief Seals for the MemFd::create() function\n+ * \\var MemFd::Seal::None\n+ * \\brief No seals (used as default value)\n+ * \\var MemFd::Seal::Shrink\n+ * \\brief Prevent the memfd from shrinking\n+ * \\var MemFd::Seal::Grow\n+ * \\brief Prevent the memfd from growing\n+ */\n+\n+/**\n+ * \\typedef MemFd::Seals\n+ * \\brief A bitwise combination of MemFd::Seal values\n+ */\n+\n+/**\n+ * \\brief Create an anonymous file\n+ * \\param[in] name The file name (displayed in symbolic links in /proc/self/fd/)\n+ * \\param[in] size The file size\n+ * \\param[in] seals The file seals\n+ *\n+ * This function is a helper that wraps anonymous file (memfd) creation and\n+ * sets the file size and optional seals.\n+ *\n+ * \\return The descriptor of the anonymous file if creation succeeded, or an\n+ * invalid UniqueFD otherwise\n+ */\n+UniqueFD MemFd::create(const char *name, std::size_t size, Seals seals)\n+{\n+#if HAVE_MEMFD_CREATE\n+\tint ret = memfd_create(name, MFD_ALLOW_SEALING | MFD_CLOEXEC);\n+#else\n+\tint ret = syscall(SYS_memfd_create, name, MFD_ALLOW_SEALING | MFD_CLOEXEC);\n+#endif\n+\tif (ret < 0) {\n+\t\tret = errno;\n+\t\tLOG(File, Error)\n+\t\t\t<< \"Failed to allocate memfd storage for \" << name\n+\t\t\t<< \": \" << strerror(ret);\n+\t\treturn {};\n+\t}\n+\n+\tUniqueFD memfd(ret);\n+\n+\tret = ftruncate(memfd.get(), size);\n+\tif (ret < 0) {\n+\t\tret = errno;\n+\t\tLOG(File, Error)\n+\t\t\t<< \"Failed to set memfd size for \" << name\n+\t\t\t<< \": \" << strerror(ret);\n+\t\treturn {};\n+\t}\n+\n+\tif (seals) {\n+\t\tint fileSeals = (seals & Seal::Shrink ? F_SEAL_SHRINK : 0)\n+\t\t\t | (seals & Seal::Grow ? F_SEAL_GROW : 0);\n+\n+\t\tret = fcntl(memfd.get(), F_ADD_SEALS, fileSeals);\n+\t\tif (ret < 0) {\n+\t\t\tret = errno;\n+\t\t\tLOG(File, Error)\n+\t\t\t\t<< \"Failed to seal the memfd for \" << name\n+\t\t\t\t<< \": \" << strerror(ret);\n+\t\t\treturn {};\n+\t\t}\n+\t}\n+\n+\treturn memfd;\n+}\n+\n+} /* namespace libcamera */\ndiff --git a/src/libcamera/base/meson.build b/src/libcamera/base/meson.build\nindex 7a7fd7e4ca87..4a228d335ba4 100644\n--- a/src/libcamera/base/meson.build\n+++ b/src/libcamera/base/meson.build\n@@ -10,6 +10,7 @@ libcamera_base_sources = files([\n 'file.cpp',\n 'flags.cpp',\n 'log.cpp',\n+ 'memfd.cpp',\n 'message.cpp',\n 'mutex.cpp',\n 'object.cpp',\ndiff --git a/src/libcamera/dma_buf_allocator.cpp b/src/libcamera/dma_buf_allocator.cpp\nindex c06eca7d04ec..be6efb89fbb7 100644\n--- a/src/libcamera/dma_buf_allocator.cpp\n+++ b/src/libcamera/dma_buf_allocator.cpp\n@@ -13,7 +13,6 @@\n #include <sys/ioctl.h>\n #include <sys/mman.h>\n #include <sys/stat.h>\n-#include <sys/syscall.h>\n #include <sys/types.h>\n #include <unistd.h>\n \n@@ -22,6 +21,7 @@\n #include <linux/udmabuf.h>\n \n #include <libcamera/base/log.h>\n+#include <libcamera/base/memfd.h>\n \n /**\n * \\file dma_buf_allocator.cpp\n@@ -126,54 +126,16 @@ DmaBufAllocator::~DmaBufAllocator() = default;\n * \\brief Check if the DmaBufAllocator instance is valid\n * \\return True if the DmaBufAllocator is valid, false otherwise\n */\n-\n-/* uClibc doesn't provide the file sealing API. */\n-#ifndef __DOXYGEN__\n-#if not HAVE_FILE_SEALS\n-#define F_ADD_SEALS\t\t1033\n-#define F_SEAL_SHRINK\t\t0x0002\n-#endif\n-#endif\n-\n UniqueFD DmaBufAllocator::allocFromUDmaBuf(const char *name, std::size_t size)\n {\n \t/* Size must be a multiple of the page size. Round it up. */\n \tstd::size_t pageMask = sysconf(_SC_PAGESIZE) - 1;\n \tsize = (size + pageMask) & ~pageMask;\n \n-#if HAVE_MEMFD_CREATE\n-\tint ret = memfd_create(name, MFD_ALLOW_SEALING | MFD_CLOEXEC);\n-#else\n-\tint ret = syscall(SYS_memfd_create, name, MFD_ALLOW_SEALING | MFD_CLOEXEC);\n-#endif\n-\tif (ret < 0) {\n-\t\tret = errno;\n-\t\tLOG(DmaBufAllocator, Error)\n-\t\t\t<< \"Failed to allocate memfd storage for \" << name\n-\t\t\t<< \": \" << strerror(ret);\n-\t\treturn {};\n-\t}\n-\n-\tUniqueFD memfd(ret);\n-\n-\tret = ftruncate(memfd.get(), size);\n-\tif (ret < 0) {\n-\t\tret = errno;\n-\t\tLOG(DmaBufAllocator, Error)\n-\t\t\t<< \"Failed to set memfd size for \" << name\n-\t\t\t<< \": \" << strerror(ret);\n-\t\treturn {};\n-\t}\n-\n \t/* udmabuf dma-buffers *must* have the F_SEAL_SHRINK seal. */\n-\tret = fcntl(memfd.get(), F_ADD_SEALS, F_SEAL_SHRINK);\n-\tif (ret < 0) {\n-\t\tret = errno;\n-\t\tLOG(DmaBufAllocator, Error)\n-\t\t\t<< \"Failed to seal the memfd for \" << name\n-\t\t\t<< \": \" << strerror(ret);\n+\tUniqueFD memfd = MemFd::create(name, size, MemFd::Seal::Shrink);\n+\tif (!memfd.isValid())\n \t\treturn {};\n-\t}\n \n \tstruct udmabuf_create create;\n \n@@ -182,7 +144,7 @@ UniqueFD DmaBufAllocator::allocFromUDmaBuf(const char *name, std::size_t size)\n \tcreate.offset = 0;\n \tcreate.size = size;\n \n-\tret = ::ioctl(providerHandle_.get(), UDMABUF_CREATE, &create);\n+\tint ret = ::ioctl(providerHandle_.get(), UDMABUF_CREATE, &create);\n \tif (ret < 0) {\n \t\tret = errno;\n \t\tLOG(DmaBufAllocator, Error)\ndiff --git a/src/libcamera/shared_mem_object.cpp b/src/libcamera/shared_mem_object.cpp\nindex 809fbdaf95de..022645e71a35 100644\n--- a/src/libcamera/shared_mem_object.cpp\n+++ b/src/libcamera/shared_mem_object.cpp\n@@ -13,9 +13,9 @@\n #include <stddef.h>\n #include <stdint.h>\n #include <sys/mman.h>\n-#include <sys/syscall.h>\n #include <sys/types.h>\n-#include <unistd.h>\n+\n+#include <libcamera/base/memfd.h>\n \n /**\n * \\file shared_mem_object.cpp\n@@ -58,22 +58,11 @@ SharedMem::SharedMem() = default;\n */\n SharedMem::SharedMem(const std::string &name, std::size_t size)\n {\n-#if HAVE_MEMFD_CREATE\n-\tint fd = memfd_create(name.c_str(), MFD_CLOEXEC);\n-#else\n-\tint fd = syscall(SYS_memfd_create, name.c_str(), MFD_CLOEXEC);\n-#endif\n-\tif (fd < 0)\n+\tUniqueFD memfd = MemFd::create(name.c_str(), size);\n+\tif (!memfd.isValid())\n \t\treturn;\n \n-\tfd_ = SharedFD(std::move(fd));\n-\tif (!fd_.isValid())\n-\t\treturn;\n-\n-\tif (ftruncate(fd_.get(), size) < 0) {\n-\t\tfd_ = SharedFD();\n-\t\treturn;\n-\t}\n+\tfd_ = SharedFD(std::move(memfd));\n \n \tvoid *mem = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED,\n \t\t\t fd_.get(), 0);\n", "prefixes": [ "v2", "1/4" ] }