Show a patch.

GET /api/patches/20721/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 20721,
    "url": "https://patchwork.libcamera.org/api/patches/20721/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/20721/",
    "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": "<20240730232708.17399-2-laurent.pinchart@ideasonboard.com>",
    "date": "2024-07-30T23:27:06",
    "name": "[1/3] libcamera: base: Add MemFd helper class",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "5bddc0296fa89ce17f3f87a32509302df5bb3f5d",
    "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/20721/mbox/",
    "series": [
        {
            "id": 4468,
            "url": "https://patchwork.libcamera.org/api/series/4468/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=4468",
            "date": "2024-07-30T23:27:05",
            "name": "libcamera: Address soft ISP file seal TODO item",
            "version": 1,
            "mbox": "https://patchwork.libcamera.org/series/4468/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/20721/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/20721/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 1157DC323E\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 30 Jul 2024 23:27:35 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 73FA463378;\n\tWed, 31 Jul 2024 01:27:33 +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 BFCC96336E\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 31 Jul 2024 01:27:30 +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 344876EF\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 31 Jul 2024 01:26:43 +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=\"n9QO6vou\"; dkim-atps=neutral",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1722382003;\n\tbh=Cosr2DwOfC5eFGZ2Uf2RqFkwfNb7rUrl+LsDLI5vKtc=;\n\th=From:To:Subject:Date:In-Reply-To:References:From;\n\tb=n9QO6vouI5aiKJExSSsYQYGpAQZfSjPZ3nU2ix/HscpNgH3zZ6FSo30giiGBqTYXO\n\tTBwpzHCxN/yLyZ9h1h/sxVu8p4M1t+TWfH7NS+6PBtKW59p+L+B1ufir+lKxHL3QkW\n\t4KphVlQrCE8zuUpEmkfon4blPbOuVhR8PnvLOEn0=",
        "From": "Laurent Pinchart <laurent.pinchart@ideasonboard.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Subject": "[PATCH 1/3] libcamera: base: Add MemFd helper class",
        "Date": "Wed, 31 Jul 2024 02:27:06 +0300",
        "Message-ID": "<20240730232708.17399-2-laurent.pinchart@ideasonboard.com>",
        "X-Mailer": "git-send-email 2.44.2",
        "In-Reply-To": "<20240730232708.17399-1-laurent.pinchart@ideasonboard.com>",
        "References": "<20240730232708.17399-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>\n---\n include/libcamera/base/memfd.h      |  34 +++++++++\n include/libcamera/base/meson.build  |   1 +\n src/libcamera/base/memfd.cpp        | 112 ++++++++++++++++++++++++++++\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, 157 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..0d50e2d64638\n--- /dev/null\n+++ b/src/libcamera/base/memfd.cpp\n@@ -0,0 +1,112 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2020, Google Inc.\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 created anonymous files\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+ * \\return The descriptor of the anonymous file is creation succeeded, or an\n+ *\n+ * This function is a helper that wraps anonymous file (memfd) creation and\n+ * sets the file size and optional seals.\n+ *\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": [
        "1/3"
    ]
}