From patchwork Thu Apr 4 08:46:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Zamazal X-Patchwork-Id: 19821 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 02954C0DA4 for ; Thu, 4 Apr 2024 08:47:36 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B336163373; Thu, 4 Apr 2024 10:47:36 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="G8hEjjq3"; dkim-atps=neutral Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5DC1D6336D for ; Thu, 4 Apr 2024 10:47:34 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1712220453; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=QK+1+oSKmj1gR1qnBux1j02v7JZt/vfWqNtE5KT9bms=; b=G8hEjjq3af/DlAX8eYqujcGAa7CjuFoTEmAfJZr/a1ZB3d9urq0KXqJ1EunO8mz/dG7czL tp2eeiZJJerwSPM+feAkLqKYoTpAg3z45eWvupUdR+u04kULC99fl/13Z9RvqkycFfioNX XKN5HQgn3jXHJdnWRxsil5lNHeL2rDs= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-689-vtjVh1L8NPSpIl7bGVaT3g-1; Thu, 04 Apr 2024 04:47:31 -0400 X-MC-Unique: vtjVh1L8NPSpIl7bGVaT3g-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id A2AF4863017; Thu, 4 Apr 2024 08:47:30 +0000 (UTC) Received: from nuthatch.brq.redhat.com (unknown [10.43.17.39]) by smtp.corp.redhat.com (Postfix) with ESMTP id 49C718173; Thu, 4 Apr 2024 08:47:29 +0000 (UTC) From: Milan Zamazal To: libcamera-devel@lists.libcamera.org Cc: Andrey Konovalov , Andrei Konovalov , Bryan O'Donoghue , Maxime Ripard , Milan Zamazal , Pavel Machek , Hans de Goede , Kieran Bingham , Laurent Pinchart Subject: [PATCH v7 03/18] libcamera: dma_heaps: extend DmaHeap class to support system heap Date: Thu, 4 Apr 2024 10:46:40 +0200 Message-ID: <20240404084657.353464-4-mzamazal@redhat.com> In-Reply-To: <20240404084657.353464-1-mzamazal@redhat.com> References: <20240404084657.353464-1-mzamazal@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.5 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" From: Andrey Konovalov Add an argument to the constructor to specify dma heaps type(s) to use. Can be DmaHeapFlag::Cma and/or DmaHeapFlag::System. By default DmaHeapFlag::Cma is used. If both DmaHeapFlag::Cma and DmaHeapFlag::System are set, CMA heap is tried first. Tested-by: Bryan O'Donoghue # sc8280xp Lenovo x13s Tested-by: Pavel Machek Reviewed-by: Milan Zamazal Reviewed-by: Pavel Machek Signed-off-by: Andrey Konovalov Signed-off-by: Hans de Goede Reviewed-by: Laurent Pinchart --- include/libcamera/internal/dma_heaps.h | 12 +++- src/libcamera/dma_heaps.cpp | 76 +++++++++++++++++++++----- 2 files changed, 73 insertions(+), 15 deletions(-) diff --git a/include/libcamera/internal/dma_heaps.h b/include/libcamera/internal/dma_heaps.h index cff8f140..80bf29e7 100644 --- a/include/libcamera/internal/dma_heaps.h +++ b/include/libcamera/internal/dma_heaps.h @@ -9,6 +9,7 @@ #include +#include #include namespace libcamera { @@ -16,7 +17,14 @@ namespace libcamera { class DmaHeap { public: - DmaHeap(); + enum class DmaHeapFlag { + Cma = 1 << 0, + System = 1 << 1, + }; + + using DmaHeapFlags = Flags; + + DmaHeap(DmaHeapFlags flags = DmaHeapFlag::Cma); ~DmaHeap(); bool isValid() const { return dmaHeapHandle_.isValid(); } UniqueFD alloc(const char *name, std::size_t size); @@ -25,4 +33,6 @@ private: UniqueFD dmaHeapHandle_; }; +LIBCAMERA_FLAGS_ENABLE_OPERATORS(DmaHeap::DmaHeapFlag) + } /* namespace libcamera */ diff --git a/src/libcamera/dma_heaps.cpp b/src/libcamera/dma_heaps.cpp index 70da6f3a..2503e4c5 100644 --- a/src/libcamera/dma_heaps.cpp +++ b/src/libcamera/dma_heaps.cpp @@ -19,9 +19,11 @@ /** * \file dma_heaps.cpp - * \brief CMA dma-heap allocator + * \brief dma-heap allocator */ +namespace libcamera { + /* * /dev/dma_heap/linux,cma is the dma-heap allocator, which allows dmaheap-cma * to only have to worry about importing. @@ -29,40 +31,86 @@ * Annoyingly, should the cma heap size be specified on the kernel command line * instead of DT, the heap gets named "reserved" instead. */ -static constexpr std::array heapNames = { - "/dev/dma_heap/linux,cma", - "/dev/dma_heap/reserved" + +/** + * \brief Specification of a heap info entry + */ +struct DmaHeapInfo { + /** + * \brief Flag to match for considering the entry + */ + DmaHeap::DmaHeapFlag type; + /** + * \brief Path to a heap device + */ + const char *deviceNodeName; }; -namespace libcamera { +static constexpr std::array heapInfos = { { + { DmaHeap::DmaHeapFlag::Cma, "/dev/dma_heap/linux,cma" }, + { DmaHeap::DmaHeapFlag::Cma, "/dev/dma_heap/reserved" }, + { DmaHeap::DmaHeapFlag::System, "/dev/dma_heap/system" }, +} }; LOG_DEFINE_CATEGORY(DmaHeap) /** * \class DmaHeap - * \brief Helper class for CMA dma-heap allocations + * \brief Helper class for dma-heap allocations + * + * DMA heaps are kernel devices that provide an API to allocate memory from + * different pools called "heaps", wrap each allocated piece of memory in a + * dmabuf object, and return the dmabuf file descriptor to userspace. Multiple + * heaps can be provided by the system, with different properties for the + * underlying memory. + * + * This class wraps a DMA heap selected at construction time, and exposes + * functions to manage memory allocation. */ /** - * \brief Construct a DmaHeap that owns a CMA dma-heap file descriptor + * \enum DmaHeap::DmaHeapFlag + * \brief Type of the dma-heap + * \var DmaHeap::Cma + * \brief Allocate from a CMA dma-heap, providing physically-contiguous memory + * \var DmaHeap::System + * \brief Allocate from the system dma-heap, using the page allocator + */ + +/** + * \typedef DmaHeap::DmaHeapFlags + * \brief A bitwise combination of DmaHeap::DmaHeapFlag values + */ + +/** + * \brief Construct a DmaHeap of a given type + * \param [in] type The type(s) of the dma-heap(s) to allocate from * - * Looks for a CMA dma-heap device to use. If it fails to open any dma-heap - * device, an invalid DmaHeap object is constructed. + * The DMA heap type is selected with the \a type parameter, which defaults to + * the CMA heap. If no heap of the given type can be accessed, the constructed + * DmaHeap instance is invalid as indicated by the isValid() function. * - * Check the new DmaHeap object with DmaHeap::isValid before using it. + * Multiple types can be selected by combining type flags, in which case the + * constructed DmaHeap will match one of the types. If the system provides + * multiple heaps that match the requested types, which heap is used is + * undefined. */ -DmaHeap::DmaHeap() +DmaHeap::DmaHeap(DmaHeapFlags type) { - for (const char *name : heapNames) { - int ret = ::open(name, O_RDWR | O_CLOEXEC, 0); + for (const auto &info : heapInfos) { + if (!(type & info.type)) + continue; + + int ret = ::open(info.deviceNodeName, O_RDWR | O_CLOEXEC, 0); if (ret < 0) { ret = errno; LOG(DmaHeap, Debug) - << "Failed to open " << name << ": " + << "Failed to open " << info.deviceNodeName << ": " << strerror(ret); continue; } + LOG(DmaHeap, Debug) << "Using " << info.deviceNodeName; dmaHeapHandle_ = UniqueFD(ret); break; }