* [PATCH 0/1] alpha: enable DMA CMA support (HAVE_DMA_CONTIGUOUS)
@ 2026-02-19 20:53 Magnus Lindholm
2026-02-19 20:53 ` [PATCH 1/1] " Magnus Lindholm
0 siblings, 1 reply; 2+ messages in thread
From: Magnus Lindholm @ 2026-02-19 20:53 UTC (permalink / raw)
To: richard.henderson, mattst88, linux-kernel, linux-alpha, corbet,
skhan, linux-doc
Cc: glaubitz, macro, macro, mcree, ink, Magnus Lindholm
This series enables CONFIG_DMA_CMA support on Alpha by selecting
HAVE_DMA_CONTIGUOUS and wiring up the required architecture hooks.
Alpha previously relied solely on high-order page allocator
allocations for coherent DMA buffers. With memory compaction now
functional, CMA can be safely enabled to provide reliable
physically contiguous allocations under fragmentation.
Testing was performed on an Alpha UP2000+ (SMP) and a DS10 (UP)
using a custom kernel module that verified the following:
- Correct CMA reservation via "cma=64M"
- CmaTotal/CmaFree reporting in /proc/meminfo
- Successful 32 MiB dma_alloc_coherent() allocations
- CmaFree reduction and recovery after free
- Successful allocations under heavy memory load
No allocation failures were observed.
Magnus Lindholm (1):
alpha: enable DMA CMA support (HAVE_DMA_CONTIGUOUS)
.../io/dma-contiguous/arch-support.txt | 2 +-
arch/alpha/Kconfig | 1 +
arch/alpha/kernel/pci_iommu.c | 46 +++++++++++++++++++
arch/alpha/kernel/setup.c | 16 +++++++
4 files changed, 64 insertions(+), 1 deletion(-)
--
2.52.0
^ permalink raw reply [flat|nested] 2+ messages in thread
* [PATCH 1/1] alpha: enable DMA CMA support (HAVE_DMA_CONTIGUOUS)
2026-02-19 20:53 [PATCH 0/1] alpha: enable DMA CMA support (HAVE_DMA_CONTIGUOUS) Magnus Lindholm
@ 2026-02-19 20:53 ` Magnus Lindholm
0 siblings, 0 replies; 2+ messages in thread
From: Magnus Lindholm @ 2026-02-19 20:53 UTC (permalink / raw)
To: richard.henderson, mattst88, linux-kernel, linux-alpha, corbet,
skhan, linux-doc
Cc: glaubitz, macro, macro, mcree, ink, Magnus Lindholm
Alpha currently does not support CONFIG_DMA_CMA, even though the
generic CMA infrastructure is available. As a result, coherent DMA
allocations rely solely on the buddy allocator and may fail for large
contiguous buffers.
Add architecture support for HAVE_DMA_CONTIGUOUS by:
- Selecting HAVE_DMA_CONTIGUOUS in arch/alpha/Kconfig.
- Ensuring early command-line parameters are parsed in setup_arch()
after Alpha-specific command line handling, so that the "cma="
early parameter is honored.
- Calling dma_contiguous_reserve() during early memory setup while
memblock is active.
- Extending alpha_pci_alloc_coherent() to fall back to
dma_alloc_from_contiguous() when __get_free_pages() fails.
- Extending alpha_pci_free_coherent() to release CMA-backed
allocations via dma_release_from_contiguous().
With these changes, Alpha systems can successfully reserve and use
CMA-backed physically contiguous memory for DMA allocations.
Tested on a DS10 with cma=64M:
- CMA reservation is correctly sized from the command line.
Signed-off-by: Magnus Lindholm <linmag7@gmail.com>
---
.../io/dma-contiguous/arch-support.txt | 2 +-
arch/alpha/Kconfig | 1 +
arch/alpha/kernel/pci_iommu.c | 46 +++++++++++++++++++
arch/alpha/kernel/setup.c | 16 +++++++
4 files changed, 64 insertions(+), 1 deletion(-)
diff --git a/Documentation/features/io/dma-contiguous/arch-support.txt b/Documentation/features/io/dma-contiguous/arch-support.txt
index 3c6ce35d704f..6cd205a991f6 100644
--- a/Documentation/features/io/dma-contiguous/arch-support.txt
+++ b/Documentation/features/io/dma-contiguous/arch-support.txt
@@ -6,7 +6,7 @@
-----------------------
| arch |status|
-----------------------
- | alpha: | TODO |
+ | alpha: | ok |
| arc: | TODO |
| arm: | ok |
| arm64: | ok |
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 6c7dbf0adad6..e3ff6f7d93ab 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -2,6 +2,7 @@
config ALPHA
bool
default y
+ select HAVE_DMA_CONTIGUOUS
select ARCH_32BIT_USTAT_F_TINODE
select ARCH_HAS_CURRENT_STACK_POINTER
select ARCH_HAS_DMA_OPS if PCI
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index 955b6ca61627..08c18d49ca8e 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -15,6 +15,7 @@
#include <linux/iommu-helper.h>
#include <linux/string_choices.h>
+#include <linux/dma-map-ops.h>
#include <asm/io.h>
#include <asm/hwrpb.h>
@@ -409,12 +410,34 @@ static void *alpha_pci_alloc_coherent(struct device *dev, size_t size,
struct pci_dev *pdev = alpha_gendev_to_pci(dev);
void *cpu_addr;
long order = get_order(size);
+ unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
+ struct page *cma_page = NULL;
+ /* Match existing behavior: prefer normal memory first. */
gfp &= ~GFP_DMA;
try_again:
cpu_addr = (void *)__get_free_pages(gfp | __GFP_ZERO, order);
if (! cpu_addr) {
+ /*
+ * Fallback to CMA if enabled: this can migrate/compact
+ * movable pages out of the CMA area to form a contiguous bloc
+ */
+ if (IS_ENABLED(CONFIG_DMA_CMA)) {
+ cma_page = dma_alloc_from_contiguous(dev, count, order, gfp);
+ if (cma_page) {
+ cpu_addr = page_address(cma_page);
+ if (!cpu_addr) {
+ /* Very unlikely on Alpha, but be safe. */
+ dma_release_from_contiguous(dev, cma_page, count);
+ cma_page = NULL;
+ } else {
+ memset(cpu_addr, 0, size);
+ goto have_mem;
+ }
+ }
+ }
+
printk(KERN_INFO "pci_alloc_consistent: "
"get_free_pages failed from %ps\n",
__builtin_return_address(0));
@@ -422,11 +445,24 @@ static void *alpha_pci_alloc_coherent(struct device *dev, size_t size,
with vmalloc and sg if we can't find contiguous memory. */
return NULL;
}
+ /* __GFP_ZERO already did this, but keep the old behavior explicit. */
memset(cpu_addr, 0, size);
+have_mem:
*dma_addrp = pci_map_single_1(pdev, virt_to_phys(cpu_addr), size, 0);
if (*dma_addrp == DMA_MAPPING_ERROR) {
+ /*
+ * Free the memory using the right backend:
+ * - If it came from CMA, release to CMA
+ * - Otherwise free_pages()
+ */
+ if (IS_ENABLED(CONFIG_DMA_CMA)) {
+ if (dma_release_from_contiguous(dev, virt_to_page(cpu_addr), count))
+ goto map_failed_freed;
+ }
free_pages((unsigned long)cpu_addr, order);
+
+map_failed_freed:
if (alpha_mv.mv_pci_tbi || (gfp & GFP_DMA))
return NULL;
/* The address doesn't fit required mask and we
@@ -452,9 +488,19 @@ static void alpha_pci_free_coherent(struct device *dev, size_t size,
unsigned long attrs)
{
struct pci_dev *pdev = alpha_gendev_to_pci(dev);
+ unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
+
dma_unmap_single(&pdev->dev, dma_addr, size, DMA_BIDIRECTIONAL);
+
+ if (IS_ENABLED(CONFIG_DMA_CMA)) {
+ /* Returns true if cpu_addr belongs to a CMA allocation. */
+ if (dma_release_from_contiguous(dev, virt_to_page(cpu_addr), count))
+ goto out;
+ }
+
free_pages((unsigned long)cpu_addr, get_order(size));
+out:
DBGA2("pci_free_consistent: [%llx,%zx] from %ps\n",
dma_addr, size, __builtin_return_address(0));
}
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
index f0af444a69a4..24893bca39f5 100644
--- a/arch/alpha/kernel/setup.c
+++ b/arch/alpha/kernel/setup.c
@@ -46,6 +46,7 @@
#include <asm/io.h>
#include <linux/log2.h>
#include <linux/export.h>
+#include <linux/dma-map-ops.h>
static int alpha_panic_event(struct notifier_block *, unsigned long, void *);
static struct notifier_block alpha_panic_block = {
@@ -513,6 +514,13 @@ setup_arch(char **cmdline_p)
/* Replace the command line, now that we've killed it with strsep. */
strcpy(command_line, boot_command_line);
+ /*
+ * Alpha mutates command_line with strsep() above, so make sure
+ * early params (including "cma=") are parsed from the restored
+ * command line before any CMA reservation happens.
+ */
+ parse_early_param();
+
/* If we want SRM console printk echoing early, do it now. */
if (alpha_using_srm && srmcons_output) {
register_srm_console();
@@ -648,6 +656,14 @@ setup_arch(char **cmdline_p)
printk("Max ASN from HWRPB is bad (0x%lx)\n", hwrpb->max_asn);
}
+#ifdef CONFIG_CMA
+ /*
+ * Reserve CMA now that memblock knows RAM layout and early params
+ * (including cma=) have been parsed.
+ */
+ dma_contiguous_reserve(0);
+#endif
+
/*
* Identify the flock of penguins.
*/
--
2.52.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-02-19 20:55 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-19 20:53 [PATCH 0/1] alpha: enable DMA CMA support (HAVE_DMA_CONTIGUOUS) Magnus Lindholm
2026-02-19 20:53 ` [PATCH 1/1] " Magnus Lindholm
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox