]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
dma-contiguous: simplify numa cma area handling
authorFeng Tang <feng.tang@linux.alibaba.com>
Mon, 25 May 2026 01:51:11 +0000 (09:51 +0800)
committerMarek Szyprowski <m.szyprowski@samsung.com>
Thu, 28 May 2026 08:11:45 +0000 (10:11 +0200)
Currently, there are 2 kernel cmdline ways to setup numa cma area:
"cma_pernuma=" and "numa_cma=", and there are 2 cma arrays as well,
while they have no difference technically. Robin suggested to cleanup
the code and only use one array [1], as "the apparent intent that
users only want one _or_ the other".

Simplify the code by only using one array to save the numa cma area.
And in rare case that a user really setup the 2 cmdline parameters
at the same time,  let the per-node specific size setting 'numa_cma='
take priority over the global numa cma setting.

Link[1]: https://lore.kernel.org/lkml/43c5301c-fe6a-41e4-9482-ccfc7b62f2a7@arm.com/

Suggested-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Feng Tang <feng.tang@linux.alibaba.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Link: https://lore.kernel.org/r/20260525015111.6267-1-feng.tang@linux.alibaba.com
Documentation/admin-guide/kernel-parameters.txt
kernel/dma/Kconfig
kernel/dma/contiguous.c

index 4d0f545fb3ec5a1750d9112a851deb8fd976d32d..8e717a587870fde6f600b6aaf9ffab5f6ef017cf 100644 (file)
@@ -895,6 +895,10 @@ Kernel parameters
                        contiguous memory allocations. It will reserve CMA
                        area for the specified node.
 
+                       If it is setup together with upper 'cmd_pernuma='
+                       (unlikely), its size setting takes priority for the
+                       specified numa nodes.
+
                        With numa CMA enabled, DMA users on node nid will
                        first try to allocate buffer from the numa area
                        which is located in node nid, if the allocation fails,
index c9fa0a922cba94ab43dd2690c7970ff5baca0fd3..0a4ba21a57a7c29de184478612411f57fa8a59bb 100644 (file)
@@ -179,7 +179,9 @@ config DMA_NUMA_CMA
 
          You can set the size of pernuma CMA by specifying "cma_pernuma=size"
          or set the node id and its size of CMA by specifying "numa_cma=
-         <node>:size[,<node>:size]" on the kernel's command line.
+         <node>:size[,<node>:size]" on the kernel's command line. And in
+         rare case that the above 2 are both setup, then the "numa_cma="
+         takes priority for the specified numa nodes.
 
 config CMA_SIZE_PERNUMA
        bool "Default CMA area per NUMA node"
index 799f6e9c88bd6ca784621f16736e42ac95edb04f..f754079a287d615c4a9926bf67dcd2ed2c3cb8f5 100644 (file)
@@ -134,7 +134,6 @@ EXPORT_SYMBOL_GPL(dev_get_cma_area);
 
 static struct cma *dma_contiguous_numa_area[MAX_NUMNODES];
 static phys_addr_t numa_cma_size[MAX_NUMNODES] __initdata;
-static struct cma *dma_contiguous_pernuma_area[MAX_NUMNODES];
 static phys_addr_t pernuma_size_bytes __initdata;
 static bool numa_cma_configured __initdata;
 
@@ -208,7 +207,7 @@ static void __init dma_numa_cma_reserve(void)
                pernuma_size_bytes = cma_get_size(dma_contiguous_default_area);
 
        for_each_node(nid) {
-               int ret;
+               int size, ret;
                char name[CMA_MAX_NAME];
                struct cma **cma;
 
@@ -218,27 +217,17 @@ static void __init dma_numa_cma_reserve(void)
                        continue;
                }
 
-               if (pernuma_size_bytes) {
-
-                       cma = &dma_contiguous_pernuma_area[nid];
-                       snprintf(name, sizeof(name), "pernuma%d", nid);
-                       ret = cma_declare_contiguous_nid(0, pernuma_size_bytes, 0, 0,
-                                                        0, false, name, cma, nid);
-                       if (ret)
-                               pr_warn("%s: reservation failed: err %d, node %d", __func__,
-                                       ret, nid);
-               }
-
-               if (numa_cma_size[nid]) {
+               /* per-node numa setting has the priority */
+               size = numa_cma_size[nid] ?: pernuma_size_bytes;
+               if (!size)
+                       continue;
 
-                       cma = &dma_contiguous_numa_area[nid];
-                       snprintf(name, sizeof(name), "numa%d", nid);
-                       ret = cma_declare_contiguous_nid(0, numa_cma_size[nid], 0, 0, 0, false,
-                                                        name, cma, nid);
-                       if (ret)
-                               pr_warn("%s: reservation failed: err %d, node %d", __func__,
-                                       ret, nid);
-               }
+               cma = &dma_contiguous_numa_area[nid];
+               snprintf(name, sizeof(name), "numa%d", nid);
+               ret = cma_declare_contiguous_nid(0, size, 0, 0, 0, false, name, cma, nid);
+               if (ret)
+                       pr_warn("%s: reservation failed: err %d, node %d", __func__,
+                               ret, nid);
        }
 }
 #else
@@ -437,16 +426,8 @@ struct page *dma_alloc_contiguous(struct device *dev, size_t size, gfp_t gfp)
 
 #ifdef CONFIG_DMA_NUMA_CMA
        if (nid != NUMA_NO_NODE && !(gfp & (GFP_DMA | GFP_DMA32))) {
-               struct cma *cma = dma_contiguous_pernuma_area[nid];
+               struct cma *cma = dma_contiguous_numa_area[nid];
                struct page *page;
-
-               if (cma) {
-                       page = cma_alloc_aligned(cma, size, gfp);
-                       if (page)
-                               return page;
-               }
-
-               cma = dma_contiguous_numa_area[nid];
                if (cma) {
                        page = cma_alloc_aligned(cma, size, gfp);
                        if (page)
@@ -484,9 +465,6 @@ void dma_free_contiguous(struct device *dev, struct page *page, size_t size)
                 * otherwise, page is from either per-numa cma or default cma
                 */
 #ifdef CONFIG_DMA_NUMA_CMA
-               if (cma_release(dma_contiguous_pernuma_area[page_to_nid(page)],
-                                       page, count))
-                       return;
                if (cma_release(dma_contiguous_numa_area[page_to_nid(page)],
                                        page, count))
                        return;