Re: [PATCH v8 01/23] dma-direct: return struct page from dma_direct_alloc_from_pool()
Aneesh Kumar K.V <[email protected]>
| Newsgroups | dev.linux.lists.linux-coco,dev.linux.lists.iommu,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-kernel,org.kernel.vger.linux-s390,org.kernel.vger.stable,org.ozlabs.lists.linuxppc-dev |
|---|---|
| Message-ID | <[email protected]> |
Leon Romanovsky <[email protected]> writes: > On Tue, Jul 21, 2026 at 07:50:10PM +0530, Aneesh Kumar K.V wrote: >> Leon Romanovsky <[email protected]> writes: >> >> > On Fri, Jul 17, 2026 at 11:34:19PM +0530, Aneesh Kumar K.V (Arm) wrote: .... >> >> 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