Alpha arch development list
 help / color / mirror / Atom feed
* [PATCH v3 0/2] alpha: enable DMA CMA support
@ 2026-11-15 10:37 Magnus Lindholm
  2026-11-15 10:37 ` [PATCH v3 1/2] alpha: parse early parameters before reserving contiguous memory Magnus Lindholm
  2026-11-15 10:37 ` [PATCH v3 2/2] alpha: enable contiguous memory allocation for coherent DMA Magnus Lindholm
  0 siblings, 2 replies; 3+ messages in thread
From: Magnus Lindholm @ 2026-11-15 10:37 UTC (permalink / raw)
  To: richard.henderson, mattst88, linux-kernel, linux-alpha; +Cc: linmag7

Changes since v2, following Matt Turner's review:

- Initialize jump labels before parsing early parameters, so handlers
  can safely change static keys. Carry Matt's Reviewed-by on patch 1.
- Page-align sizes in both coherent allocation and free. The CMA helper
  assumes a page-aligned size; truncating an unaligned request can cause
  an undersized allocation, an overwrite, and release of unowned pages.
- Change the failure message to "allocation failed".

V2 was boot-tested on a three-CPU AlphaServer ES40 with cma=64M,
including 32 MiB, 24 KiB and 8 KiB allocation tests and GFP_ATOMIC
bypass checks. All of those sizes were page multiples, so they did
not exercise the alignment bug. Those results are not validation
of v3; build and runtime validation of this revision remain pending.

Planned regression cases include 12 KiB and 20 KiB requests, checking
zeroing, mapped size, and allocation/release accounting against the
page-rounded size on each CPU. Repeat the existing static-key tests
on a combined kernel with jump-label v3.

Reservation policy is unchanged: prefer top-down placement below the
direct-map and usable RAM limits, with generic cma= range overrides.
Other reservation-size boots and no-IOMMU testing remain outstanding.

Magnus Lindholm (2):
  alpha: parse early parameters before reserving contiguous memory
  alpha: enable contiguous memory allocation for coherent DMA

 .../io/dma-contiguous/arch-support.txt        |  2 +-
 arch/alpha/Kconfig                            |  1 +
 arch/alpha/kernel/pci_iommu.c                 | 19 ++++++++++++------
 arch/alpha/kernel/setup.c                     | 20 +++++++++++++++++++
 4 files changed, 35 insertions(+), 7 deletions(-)


base-commit: 0b4cadbe7c39d830dec35c4a2655483de0dae568
-- 
2.43.0


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH v3 1/2] alpha: parse early parameters before reserving contiguous memory
  2026-11-15 10:37 [PATCH v3 0/2] alpha: enable DMA CMA support Magnus Lindholm
@ 2026-11-15 10:37 ` Magnus Lindholm
  2026-11-15 10:37 ` [PATCH v3 2/2] alpha: enable contiguous memory allocation for coherent DMA Magnus Lindholm
  1 sibling, 0 replies; 3+ messages in thread
From: Magnus Lindholm @ 2026-11-15 10:37 UTC (permalink / raw)
  To: richard.henderson, mattst88, linux-kernel, linux-alpha; +Cc: linmag7

Run parse_early_param() in setup_arch(), after machine initialization
and before further memory reservations. This lets the subsequent CMA
reservation honor cma= before start_kernel() reaches its normal call.

Initialize jump labels first so early handlers can safely change static
keys. The later jump_label_init() call in start_kernel() is harmless.

The parser uses boot_command_line and guards against repeated calls.
This moves all early parameter handlers, not just the CMA handler.

Signed-off-by: Magnus Lindholm <linmag7@gmail.com>
Reviewed-by: Matt Turner <mattst88@gmail.com>
---
 arch/alpha/kernel/setup.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
index 9fda01b73b18..f21a7c8f5213 100644
--- a/arch/alpha/kernel/setup.c
+++ b/arch/alpha/kernel/setup.c
@@ -25,6 +25,7 @@
 #include <linux/cpu.h>
 #include <linux/errno.h>
 #include <linux/init.h>
+#include <linux/jump_label.h>
 #include <linux/string.h>
 #include <linux/ioport.h>
 #include <linux/panic_notifier.h>
@@ -579,6 +580,10 @@ setup_arch(char **cmdline_p)
 	if (alpha_mv.init_arch)
 		alpha_mv.init_arch();
 
+	/* Early options may change static keys and configure DMA CMA. */
+	jump_label_init();
+	parse_early_param();
+
 	/* Reserve standard resources.  */
 	reserve_std_resources();
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH v3 2/2] alpha: enable contiguous memory allocation for coherent DMA
  2026-11-15 10:37 [PATCH v3 0/2] alpha: enable DMA CMA support Magnus Lindholm
  2026-11-15 10:37 ` [PATCH v3 1/2] alpha: parse early parameters before reserving contiguous memory Magnus Lindholm
@ 2026-11-15 10:37 ` Magnus Lindholm
  1 sibling, 0 replies; 3+ messages in thread
From: Magnus Lindholm @ 2026-11-15 10:37 UTC (permalink / raw)
  To: richard.henderson, mattst88, linux-kernel, linux-alpha; +Cc: linmag7

Select HAVE_DMA_CONTIGUOUS and reserve a default CMA area after the
machine has initialized its DMA windows. Prefer top-down placement
below the direct-map and usable RAM limits. Skip the default reservation
when no direct-map window exists. Explicit cma= ranges retain their
generic override semantics; top-down placement is a preference, not a
hard lower bound excluding the first 16 MiB.

Use dma_alloc_contiguous(), which rejects non-blocking callers, before
falling back to alloc_pages_exact(). Pair both paths with
dma_free_contiguous(), whose buddy fallback uses free_pages_exact().
Skip CMA on the GFP_DMA retry after a mapping failure so it cannot
return the same unsuitable CMA pages. Retain zeroing for CMA memory.

Round the size up to a page boundary in both allocation and free. CMA
allocates size >> PAGE_SHIFT pages, so an unaligned size could otherwise
allocate too few pages and overrun the allocation during zeroing. Keep
the mapping and unmapping lengths consistent with the aligned size.

With CONFIG_DMA_CMA=y, the default CMA_SIZE_MBYTES setting reserves
16 MiB without a cma= argument. cma=0 disables the default area.

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                 | 19 +++++++++++++------
 arch/alpha/kernel/setup.c                     | 15 +++++++++++++++
 4 files changed, 30 insertions(+), 7 deletions(-)

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 6ccb2d230326..cddc1f3af209 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -30,6 +30,7 @@ config ALPHA
 	select HAVE_ARCH_COMPILER_H
 	select HAVE_ASM_MODVERSIONS
 	select HAVE_DEBUG_KMEMLEAK
+	select HAVE_DMA_CONTIGUOUS
 	select HAVE_GUP_FAST
 	select HAVE_KERNEL_BZIP2
 	select HAVE_KERNEL_GZIP
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index 955b6ca61627..19aa5c05de2b 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -408,15 +408,20 @@ 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);
+	struct page *page;
 
+	size = PAGE_ALIGN(size);
 	gfp &= ~GFP_DMA;
 
 try_again:
-	cpu_addr = (void *)__get_free_pages(gfp | __GFP_ZERO, order);
+	/* A low-memory retry must not return the same unsuitable CMA pages. */
+	page = (gfp & GFP_DMA) ? NULL : dma_alloc_contiguous(dev, size, gfp);
+	if (page)
+		cpu_addr = page_address(page);
+	else
+		cpu_addr = alloc_pages_exact(size, gfp | __GFP_ZERO);
 	if (! cpu_addr) {
-		printk(KERN_INFO "pci_alloc_consistent: "
-		       "get_free_pages failed from %ps\n",
+		pr_info("pci_alloc_consistent: allocation failed from %ps\n",
 			__builtin_return_address(0));
 		/* ??? Really atomic allocation?  Otherwise we could play
 		   with vmalloc and sg if we can't find contiguous memory.  */
@@ -426,7 +431,7 @@ static void *alpha_pci_alloc_coherent(struct device *dev, size_t size,
 
 	*dma_addrp = pci_map_single_1(pdev, virt_to_phys(cpu_addr), size, 0);
 	if (*dma_addrp == DMA_MAPPING_ERROR) {
-		free_pages((unsigned long)cpu_addr, order);
+		dma_free_contiguous(dev, virt_to_page(cpu_addr), size);
 		if (alpha_mv.mv_pci_tbi || (gfp & GFP_DMA))
 			return NULL;
 		/* The address doesn't fit required mask and we
@@ -452,8 +457,10 @@ static void alpha_pci_free_coherent(struct device *dev, size_t size,
 				    unsigned long attrs)
 {
 	struct pci_dev *pdev = alpha_gendev_to_pci(dev);
+
+	size = PAGE_ALIGN(size);
 	dma_unmap_single(&pdev->dev, dma_addr, size, DMA_BIDIRECTIONAL);
-	free_pages((unsigned long)cpu_addr, get_order(size));
+	dma_free_contiguous(dev, virt_to_page(cpu_addr), size);
 
 	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 f21a7c8f5213..f40a87b30a7c 100644
--- a/arch/alpha/kernel/setup.c
+++ b/arch/alpha/kernel/setup.c
@@ -31,6 +31,7 @@
 #include <linux/panic_notifier.h>
 #include <linux/platform_device.h>
 #include <linux/memblock.h>
+#include <linux/dma-map-ops.h>
 #include <linux/pci.h>
 #include <linux/seq_file.h>
 #include <linux/root_dev.h>
@@ -584,6 +585,20 @@ setup_arch(char **cmdline_p)
 	jump_label_init();
 	parse_early_param();
 
+	/*
+	 * Prefer higher memory within the direct-map window, rather than
+	 * consuming scarce low memory with a bottom-up CMA reservation.
+	 * Explicit cma= ranges retain the generic command-line semantics.
+	 */
+	if (__direct_map_size) {
+		bool bottom_up = memblock_bottom_up();
+
+		memblock_set_bottom_up(false);
+		dma_contiguous_reserve(min_t(phys_addr_t, __direct_map_size,
+					     PFN_PHYS(max_low_pfn)));
+		memblock_set_bottom_up(bottom_up);
+	}
+
 	/* Reserve standard resources.  */
 	reserve_std_resources();
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-11-15 10:38 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-15 10:37 [PATCH v3 0/2] alpha: enable DMA CMA support Magnus Lindholm
2026-11-15 10:37 ` [PATCH v3 1/2] alpha: parse early parameters before reserving contiguous memory Magnus Lindholm
2026-11-15 10:37 ` [PATCH v3 2/2] alpha: enable contiguous memory allocation for coherent DMA Magnus Lindholm

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox