Thread (33 messages) 33 messages, 2 authors, 9h ago

Re: [PATCH v8 01/23] dma-direct: return struct page from dma_direct_alloc_from_pool()

From: Aneesh Kumar K.V <aneesh.kumar@kernel.org>
Date: 2026-07-21 15:10:32
Also in: linux-arm-kernel, linux-coco, linux-iommu, linux-s390, lkml, stable

Leon Romanovsky [off-list ref] writes:
On Tue, Jul 21, 2026 at 07:50:10PM +0530, Aneesh Kumar K.V wrote:
quoted
Leon Romanovsky [off-list ref] writes:
quoted
On Fri, Jul 17, 2026 at 11:34:19PM +0530, Aneesh Kumar K.V (Arm) wrote:
....
quoted
quoted
quoted
 static void *dma_direct_alloc_no_mapping(struct device *dev, size_t size,
@@ -247,8 +246,11 @@ void *dma_direct_alloc(struct device *dev, size_t size,
 	 * the atomic pools instead if we aren't allowed block.
 	 */
 	if ((remap || force_dma_unencrypted(dev)) &&
-	    dma_direct_use_pool(dev, gfp))
-		return dma_direct_alloc_from_pool(dev, size, dma_handle, gfp);
+	    dma_direct_use_pool(dev, gfp)) {
+		page = dma_direct_alloc_from_pool(dev, size, dma_handle,
+						  &ret, gfp);
+		return page ? ret : NULL;
Sorry for joining the discussion late, but the line above caught my
attention.

Why do we need both ret and page? We can derive cpu_addr from page and
vice versa. Do we really need the &ret parameter? Or, more generally, do
we really need "struct page *"?

static struct page *__dma_alloc_from_pool(struct device *dev, size_t size,
		struct gen_pool *pool, void **cpu_addr,
		bool (*phys_addr_ok)(struct device *, phys_addr_t, size_t))
{
...
	*cpu_addr = (void *)addr;
	memset(*cpu_addr, 0, size);
	return pfn_to_page(__phys_to_pfn(phys));
}

Why
With CONFIG_DMA_DIRECT_REMAP the cpu_addr can be different from
page_address.
Can you please point to the code there it can happen?
__dma_alloc_from_pool() has direct connection between physical address
and struct page.
dma_direct_alloc -> 	remap = IS_ENABLED(CONFIG_DMA_DIRECT_REMAP);
	if ((remap && dma_direct_use_pool(dev, gfp)) {
		page = dma_direct_alloc_from_pool(dev, size,

..
__dma_alloc_from_pool -> 
	addr = gen_pool_alloc(pool, size);
	if (!addr)


We expand the pool as below..

atomic_pool_expand ->

#ifdef CONFIG_DMA_DIRECT_REMAP
	addr = dma_common_contiguous_remap(page, pool_size,
			pgprot_decrypted(pgprot_dmacoherent(PAGE_KERNEL)),
			__builtin_return_address(0));
	if (!addr)
		goto free_page;
#else
	addr = page_to_virt(page);
#endif


-aneesh
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help