[PATCH] dmaengine: sun6i: constrain descriptor addresses through the DMA mask

From: James Hilliard

Date: Wed Oct 21 2026 - 17:11:42 EST


Descriptor allocations pass GFP_DMA32 to dma_pool_alloc(). The DMA API
chooses the memory zone from the device address mask, rather than accepting
zone-selection flags from the driver. These flags can also reach the pool
metadata allocation and trigger a slab allocator warning, as observed on
H616 when preparing the first UART receive-DMA chain.

Set a 32-bit coherent DMA mask before creating the descriptor pool and
remove GFP_DMA32 from its allocations. The driver does not encode the
extra descriptor-address bits supported by some variants, so descriptor
links must remain below 4 GiB. Keep the streaming mask unchanged for
variants with wider source and destination addresses.

Fixes: ec31c5c59492 ("dmaengine: sun6i: Add support for 34-bit physical addresses")
Signed-off-by: James Hilliard <james.hilliard1@xxxxxxxxx>
---
drivers/dma/sun6i-dma.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
index 7704b016aed8..0ef6ed1f936e 100644
--- a/drivers/dma/sun6i-dma.c
+++ b/drivers/dma/sun6i-dma.c
@@ -684,7 +684,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy(
if (!txd)
return NULL;

- v_lli = dma_pool_alloc(sdev->pool, GFP_DMA32 | GFP_NOWAIT, &p_lli);
+ v_lli = dma_pool_alloc(sdev->pool, GFP_NOWAIT, &p_lli);
if (!v_lli) {
dev_err(sdev->slave.dev, "Failed to alloc lli memory\n");
goto err_txd_free;
@@ -743,7 +743,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg(
return NULL;

for_each_sg(sgl, sg, sg_len, i) {
- v_lli = dma_pool_alloc(sdev->pool, GFP_DMA32 | GFP_NOWAIT, &p_lli);
+ v_lli = dma_pool_alloc(sdev->pool, GFP_NOWAIT, &p_lli);
if (!v_lli)
goto err_lli_free;

@@ -826,7 +826,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_cyclic(
return NULL;

for (i = 0; i < periods; i++) {
- v_lli = dma_pool_alloc(sdev->pool, GFP_DMA32 | GFP_NOWAIT, &p_lli);
+ v_lli = dma_pool_alloc(sdev->pool, GFP_NOWAIT, &p_lli);
if (!v_lli) {
dev_err(sdev->slave.dev, "Failed to alloc lli memory\n");
goto err_lli_free;
@@ -1345,6 +1345,11 @@ static int sun6i_dma_probe(struct platform_device *pdev)
return PTR_ERR(sdc->rstc);
}

+ /* This driver uses unextended 32-bit addresses for descriptor links. */
+ ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
+ if (ret)
+ return ret;
+
sdc->pool = dmam_pool_create(dev_name(&pdev->dev), &pdev->dev,
sizeof(struct sun6i_dma_lli), 4, 0);
if (!sdc->pool) {

---
base-commit: 93f51579e7df248780214094418f205253383cc5
change-id: 20261021-submit-sun6i-dma-descriptor-mask-v1-35bb381b932a

Best regards,
--
James Hilliard <james.hilliard1@xxxxxxxxx>