Skip to content

Commit 2b54ac9

Browse files
committed
Merge tag 'dma-mapping-6.19-2026-01-30' of git://git.kernel.org/pub/scm/linux/kernel/git/mszyprowski/linux
Pull dma-mapping fixes from Marek Szyprowski: - important fix for ARM 32-bit based systems using cma= kernel parameter (Oreoluwa Babatunde) - a fix for the corner case of the DMA atomic pool based allocations (Sai Sree Kartheek Adivi) * tag 'dma-mapping-6.19-2026-01-30' of git://git.kernel.org/pub/scm/linux/kernel/git/mszyprowski/linux: dma/pool: distinguish between missing and exhausted atomic pools of: reserved_mem: Allow reserved_mem framework detect "cma=" kernel param
2 parents d941a3f + 56c430c commit 2b54ac9

4 files changed

Lines changed: 42 additions & 9 deletions

File tree

drivers/of/of_reserved_mem.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,13 +157,19 @@ static int __init __reserved_mem_reserve_reg(unsigned long node,
157157
phys_addr_t base, size;
158158
int i, len;
159159
const __be32 *prop;
160-
bool nomap;
160+
bool nomap, default_cma;
161161

162162
prop = of_flat_dt_get_addr_size_prop(node, "reg", &len);
163163
if (!prop)
164164
return -ENOENT;
165165

166166
nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL;
167+
default_cma = of_get_flat_dt_prop(node, "linux,cma-default", NULL);
168+
169+
if (default_cma && cma_skip_dt_default_reserved_mem()) {
170+
pr_err("Skipping dt linux,cma-default for \"cma=\" kernel param.\n");
171+
return -EINVAL;
172+
}
167173

168174
for (i = 0; i < len; i++) {
169175
u64 b, s;
@@ -248,10 +254,13 @@ void __init fdt_scan_reserved_mem_reg_nodes(void)
248254

249255
fdt_for_each_subnode(child, fdt, node) {
250256
const char *uname;
257+
bool default_cma = of_get_flat_dt_prop(child, "linux,cma-default", NULL);
251258
u64 b, s;
252259

253260
if (!of_fdt_device_is_available(fdt, child))
254261
continue;
262+
if (default_cma && cma_skip_dt_default_reserved_mem())
263+
continue;
255264

256265
if (!of_flat_dt_get_addr_size(child, "reg", &b, &s))
257266
continue;
@@ -389,7 +398,7 @@ static int __init __reserved_mem_alloc_size(unsigned long node, const char *unam
389398
phys_addr_t base = 0, align = 0, size;
390399
int i, len;
391400
const __be32 *prop;
392-
bool nomap;
401+
bool nomap, default_cma;
393402
int ret;
394403

395404
prop = of_get_flat_dt_prop(node, "size", &len);
@@ -413,6 +422,12 @@ static int __init __reserved_mem_alloc_size(unsigned long node, const char *unam
413422
}
414423

415424
nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL;
425+
default_cma = of_get_flat_dt_prop(node, "linux,cma-default", NULL);
426+
427+
if (default_cma && cma_skip_dt_default_reserved_mem()) {
428+
pr_err("Skipping dt linux,cma-default for \"cma=\" kernel param.\n");
429+
return -EINVAL;
430+
}
416431

417432
/* Need adjust the alignment to satisfy the CMA requirement */
418433
if (IS_ENABLED(CONFIG_CMA)

include/linux/cma.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,15 @@ extern bool cma_intersects(struct cma *cma, unsigned long start, unsigned long e
5757

5858
extern void cma_reserve_pages_on_error(struct cma *cma);
5959

60+
#ifdef CONFIG_DMA_CMA
61+
extern bool cma_skip_dt_default_reserved_mem(void);
62+
#else
63+
static inline bool cma_skip_dt_default_reserved_mem(void)
64+
{
65+
return false;
66+
}
67+
#endif
68+
6069
#ifdef CONFIG_CMA
6170
struct folio *cma_alloc_folio(struct cma *cma, int order, gfp_t gfp);
6271
bool cma_free_folio(struct cma *cma, const struct folio *folio);

kernel/dma/contiguous.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,16 @@ static int __init early_cma(char *p)
9191
}
9292
early_param("cma", early_cma);
9393

94+
/*
95+
* cma_skip_dt_default_reserved_mem - This is called from the
96+
* reserved_mem framework to detect if the default cma region is being
97+
* set by the "cma=" kernel parameter.
98+
*/
99+
bool __init cma_skip_dt_default_reserved_mem(void)
100+
{
101+
return size_cmdline != -1;
102+
}
103+
94104
#ifdef CONFIG_DMA_NUMA_CMA
95105

96106
static struct cma *dma_contiguous_numa_area[MAX_NUMNODES];
@@ -470,12 +480,6 @@ static int __init rmem_cma_setup(struct reserved_mem *rmem)
470480
struct cma *cma;
471481
int err;
472482

473-
if (size_cmdline != -1 && default_cma) {
474-
pr_info("Reserved memory: bypass %s node, using cmdline CMA params instead\n",
475-
rmem->name);
476-
return -EBUSY;
477-
}
478-
479483
if (!of_get_flat_dt_prop(node, "reusable", NULL) ||
480484
of_get_flat_dt_prop(node, "no-map", NULL))
481485
return -EINVAL;

kernel/dma/pool.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,15 +277,20 @@ struct page *dma_alloc_from_pool(struct device *dev, size_t size,
277277
{
278278
struct gen_pool *pool = NULL;
279279
struct page *page;
280+
bool pool_found = false;
280281

281282
while ((pool = dma_guess_pool(pool, gfp))) {
283+
pool_found = true;
282284
page = __dma_alloc_from_pool(dev, size, pool, cpu_addr,
283285
phys_addr_ok);
284286
if (page)
285287
return page;
286288
}
287289

288-
WARN(1, "Failed to get suitable pool for %s\n", dev_name(dev));
290+
if (pool_found)
291+
WARN(!(gfp & __GFP_NOWARN), "DMA pool exhausted for %s\n", dev_name(dev));
292+
else
293+
WARN(1, "Failed to get suitable pool for %s\n", dev_name(dev));
289294
return NULL;
290295
}
291296

0 commit comments

Comments
 (0)