Re: [PATCH RFC 06/12] dma: direct: Provide accessor to dmem region

Robin Murphy
2025-03-10T14:56:43Z

On 2025-03-10 12:06 pm, Maxime Ripard wrote:
> Consumers of the direct DMA API will have to know which region their
> device allocate from in order for them to charge the memory allocation
> in the right one.

This doesn't seem to make much sense - dma-direct is not an allocator
itself, it just provides the high-level
dma_alloc_attrs/dma_alloc_pages/etc. interfaces wherein the underlying
allocations _could_ come from CMA, but also a per-device
coherent/restricted pool, or a global coherent/atomic pool, or the
regular page allocator, or in one weird corner case the SWIOTLB buffer,
or...

Thanks,
Robin.

> Let's provide an accessor for that region.
>
> Signed-off-by: Maxime Ripard <mripard@kernel.org>
> ---
> include/linux/dma-direct.h | 2 ++
> kernel/dma/direct.c | 8 ++++++++
> 2 files changed, 10 insertions(+)
>
> diff --git a/include/linux/dma-direct.h b/include/linux/dma-direct.h
> index d7e30d4f7503a898a456df8eedf6a2cd284c35ff..2dd7cbccfaeed81c18c67aae877417fe89f2f2f5 100644
> --- a/include/linux/dma-direct.h
> +++ b/include/linux/dma-direct.h
> @@ -145,6 +145,8 @@ void dma_direct_free_pages(struct device *dev, size_t size,
> enum dma_data_direction dir);
> int dma_direct_supported(struct device *dev, u64 mask);
> dma_addr_t dma_direct_map_resource(struct device *dev, phys_addr_t paddr,
> size_t size, enum dma_data_direction dir, unsigned long attrs);
>
> +struct dmem_cgroup_region *dma_direct_get_dmem_cgroup_region(struct device *dev);
> +
> #endif /* _LINUX_DMA_DIRECT_H */
> diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
> index 5b4e6d3bf7bcca8930877ba078aed4ce26828f06..ece1361077b6efeec5b202d838750afd967d473f 100644
> --- a/kernel/dma/direct.c
> +++ b/kernel/dma/direct.c
> @@ -42,10 +42,18 @@ u64 dma_direct_get_required_mask(struct device *dev)
> u64 max_dma = phys_to_dma_direct(dev, phys);
>
> return (1ULL << (fls64(max_dma) - 1)) * 2 - 1;
> }
>
> +#if IS_ENABLED(CONFIG_CGROUP_DMEM)
> +struct dmem_cgroup_region *
> +dma_direct_get_dmem_cgroup_region(struct device *dev)
> +{
> + return dma_contiguous_get_dmem_cgroup_region(dev);
> +}
> +#endif
> +
> static gfp_t dma_direct_optimal_gfp_mask(struct device *dev, u64 *phys_limit)
> {
> u64 dma_limit = min_not_zero(
> dev->coherent_dma_mask,
> dev->bus_dma_limit);
>