Re: [PATCH 1/1] alpha: enable DMA CMA support (HAVE_DMA_CONTIGUOUS)
From: Matt Turner
Date: Thu Oct 08 2026 - 16:50:26 EST
On Thu, Feb 19, 2026 at 9:53 PM Magnus Lindholm <linmag7@xxxxxxxxx> wrote:
> + if (IS_ENABLED(CONFIG_DMA_CMA)) {
> + cma_page = dma_alloc_from_contiguous(dev, count, order, gfp);
Two problems here.
cma_alloc() can sleep, and alpha_pci_alloc_coherent() is called with
GFP_ATOMIC by some drivers. This needs a gfpflags_allow_blocking(gfp)
check before going to CMA.
The fourth argument of dma_alloc_from_contiguous() is "bool no_warn",
not a gfp mask, so passing gfp makes it always true.
Also, because the buddy allocator is tried first without __GFP_NOWARN,
a large allocation that then succeeds from CMA still produces a page
allocation failure splat.
I think all three go away, and the patch gets a lot smaller, if you
use the helpers dma-direct uses:
page = dma_alloc_contiguous(dev, size, gfp);
if (!page)
page = alloc_pages(gfp | __GFP_ZERO, order);
...
dma_free_contiguous(dev, virt_to_page(cpu_addr), size);
dma_alloc_contiguous() already refuses non-blocking callers, and
dma_free_contiguous() already falls back to __free_pages() when the
page is not in a CMA area. That removes the hand-rolled
release-or-free logic and both gotos.
> + cpu_addr = page_address(cma_page);
> + if (!cpu_addr) {
There is no highmem on alpha, so this cannot fail. Please drop it.
> + /* __GFP_ZERO already did this, but keep the old behavior explicit. */
Either drop the redundant memset in a separate patch or leave the line
alone; the comment does not help.
> + parse_early_param();
This moves the point at which every early_param() handler runs on
alpha, not only "cma=", from start_kernel() to the middle of
setup_arch(). I think that is fine, but it deserves its own patch and
changelog. The comment is also misleading: parse_early_param() works
on its own copy of boot_command_line, so the strsep() damage to
command_line is not the reason it is needed. It is needed because
dma_contiguous_reserve() now runs before start_kernel() gets to it.
> +#ifdef CONFIG_CMA
> + dma_contiguous_reserve(0);
> +#endif
The #ifdef is not needed, there is a stub for !CONFIG_DMA_CMA.
About the limit of 0: setup_arch() has already switched memblock to
bottom-up at this point, so the area ends up low rather than at the
top of RAM. Where does it land on your machines? Two cases I would
like to understand:
- Could a small area (say cma=4M) be placed below 16MB and eat into
ZONE_DMA?
- On machines without an IOMMU (mv_pci_tbi == NULL) the area has to
sit inside the direct-map window to be usable at all. When
pci_map_single_1() fails on a CMA page, the GFP_DMA retry will get
the same CMA memory back.
Passing an explicit limit, and skipping CMA on the GFP_DMA retry,
would make both cases well defined.
The Kconfig hunk no longer applies to for-next, and the select should
go in sorted position.
Side note for the changelog: with CONFIG_DMA_CMA=y the default
CMA_SIZE_MBYTES is 16, so it is worth saying that 16MB is reserved
even without "cma=" on the command line.