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

Leon Romanovsky <[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 <20260721142921.GN110966@unreal>
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:
> >> Commit 5b138c534fda ("dma-direct: factor out a dma_direct_alloc_from_pool
> >> helper") changed dma_direct_alloc_from_pool() to return the CPU address
> >> from dma_alloc_from_pool(). That fits dma_direct_alloc(), but
> >> dma_direct_alloc_pages() also uses the helper and expects a struct page *.
> >> 
> >> Fix this by making dma_direct_alloc_from_pool() return the struct page *
> >> again, and pass the CPU address back through an out-parameter for the
> >> dma_direct_alloc() caller.
> >> 
> >> Fixes: 5b138c534fda ("dma-direct: factor out a dma_direct_alloc_from_pool helper")
> >> Cc: [email protected]
> >> Tested-by: Michael Kelley <[email protected]>
> >> Tested-by: Mostafa Saleh <[email protected]>
> >> Reviewed-by: Jason Gunthorpe <[email protected]>
> >> Signed-off-by: Aneesh Kumar K.V (Arm) <[email protected]>
> >> ---
> >>  kernel/dma/direct.c | 18 ++++++++++--------
> >>  1 file changed, 10 insertions(+), 8 deletions(-)
> >> 
> >> diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
> >> index d8219efe3273..363d984d90e7 100644
> >> --- a/kernel/dma/direct.c
> >> +++ b/kernel/dma/direct.c
> >> @@ -164,22 +164,21 @@ static bool dma_direct_use_pool(struct device *dev, gfp_t gfp)
> >>  	return !gfpflags_allow_blocking(gfp) && !is_swiotlb_for_alloc(dev);
> >>  }
> >>  
> >> -static void *dma_direct_alloc_from_pool(struct device *dev, size_t size,
> >> -		dma_addr_t *dma_handle, gfp_t gfp)
> >> +static struct page *dma_direct_alloc_from_pool(struct device *dev, size_t size,
> >> +		dma_addr_t *dma_handle, void **cpu_addr, gfp_t gfp)
> >>  {
> >>  	struct page *page;
> >>  	u64 phys_limit;
> >> -	void *ret;
> >>  
> >>  	if (WARN_ON_ONCE(!IS_ENABLED(CONFIG_DMA_COHERENT_POOL)))
> >>  		return NULL;
> >>  
> >>  	gfp |= dma_direct_optimal_gfp_mask(dev, &phys_limit);
> >> -	page = dma_alloc_from_pool(dev, size, &ret, gfp, dma_coherent_ok);
> >> +	page = dma_alloc_from_pool(dev, size, cpu_addr, gfp, dma_coherent_ok);
> >>  	if (!page)
> >>  		return NULL;
> >>  	*dma_handle = phys_to_dma_direct(dev, page_to_phys(page));
> >> -	return ret;
> >> +	return page;
> >>  }
> >>  
> >>  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.

Thanks

> 
> -aneesh
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.