In order to create a CMA heap instance for each CMA region found in the system, we need to register each of these instances.
While it would appear trivial, the CMA regions are created super early in the kernel boot process, before most of the subsystems are initialized. Thus, we can't just create an exported function to create a heap from the CMA region being initialized.
What we can do however is create a two-step process, where we collect all the CMA regions into an array early on, and then when we initialize the heaps we iterate over that array and create the heaps from the CMA regions we collected.
Reviewed-by: T.J. Mercier tjmercier@google.com Signed-off-by: Maxime Ripard mripard@kernel.org --- MAINTAINERS | 1 + drivers/dma-buf/heaps/cma_heap.c | 14 ++++++++++++++ include/linux/dma-buf/heaps/cma.h | 16 ++++++++++++++++ 3 files changed, 31 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS index 46126ce2f968e4f9260263f1574ee29f5ff0de1c..c4edcc29368eec722432a85ac5c420a08c2680ea 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7306,10 +7306,11 @@ T: git https://gitlab.freedesktop.org/drm/misc/kernel.git F: Documentation/driver-api/dma-buf.rst F: Documentation/userspace-api/dma-buf-alloc-exchange.rst F: drivers/dma-buf/ F: include/linux/*fence.h F: include/linux/dma-buf.h +F: include/linux/dma-buf/ F: include/linux/dma-resv.h K: \bdma_(?:buf|fence|resv)\b
DMA GENERIC OFFLOAD ENGINE SUBSYSTEM M: Vinod Koul vkoul@kernel.org diff --git a/drivers/dma-buf/heaps/cma_heap.c b/drivers/dma-buf/heaps/cma_heap.c index 0df007111975447d555714d61ead9699287fd65a..2a901af635ed76cdb085915c03258c235e302792 100644 --- a/drivers/dma-buf/heaps/cma_heap.c +++ b/drivers/dma-buf/heaps/cma_heap.c @@ -12,10 +12,11 @@
#define pr_fmt(fmt) "cma_heap: " fmt
#include <linux/cma.h> #include <linux/dma-buf.h> +#include <linux/dma-buf/heaps/cma.h> #include <linux/dma-heap.h> #include <linux/dma-map-ops.h> #include <linux/err.h> #include <linux/highmem.h> #include <linux/io.h> @@ -25,10 +26,23 @@ #include <linux/slab.h> #include <linux/vmalloc.h>
#define DEFAULT_CMA_NAME "default_cma_region"
+static struct cma *dma_areas[MAX_CMA_AREAS] __initdata; +static unsigned int dma_areas_num __initdata; + +int __init dma_heap_cma_register_heap(struct cma *cma) +{ + if (dma_areas_num >= ARRAY_SIZE(dma_areas)) + return -EINVAL; + + dma_areas[dma_areas_num++] = cma; + + return 0; +} + struct cma_heap { struct dma_heap *heap; struct cma *cma; };
diff --git a/include/linux/dma-buf/heaps/cma.h b/include/linux/dma-buf/heaps/cma.h new file mode 100644 index 0000000000000000000000000000000000000000..e751479e21e703e24a5f799b4a7fc8bd0df3c1c4 --- /dev/null +++ b/include/linux/dma-buf/heaps/cma.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef DMA_BUF_HEAP_CMA_H_ +#define DMA_BUF_HEAP_CMA_H_ + +struct cma; + +#ifdef CONFIG_DMABUF_HEAPS_CMA +int dma_heap_cma_register_heap(struct cma *cma); +#else +static inline int dma_heap_cma_register_heap(struct cma *cma) +{ + return 0; +} +#endif // CONFIG_DMABUF_HEAPS_CMA + +#endif // DMA_BUF_HEAP_CMA_H_