Linux Media Controller development
 help / color / mirror / Atom feed
From: Maxime Ripard <mripard@redhat.com>
To: Eric Chanudet <echanude@redhat.com>
Cc: "Sumit Semwal" <sumit.semwal@linaro.org>,
	"Benjamin Gaignard" <benjamin.gaignard@collabora.com>,
	"Brian Starkey" <Brian.Starkey@arm.com>,
	"John Stultz" <jstultz@google.com>,
	"T.J. Mercier" <tjmercier@google.com>,
	"Christian König" <christian.koenig@amd.com>,
	linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org,
	linaro-mm-sig@lists.linaro.org, linux-kernel@vger.kernel.org,
	"Albert Esteve" <aesteve@redhat.com>
Subject: Re: [PATCH] dma-buf: heaps: cma: register a dmem region for each cma heap
Date: Mon, 2 Feb 2026 11:12:37 +0100	[thread overview]
Message-ID: <20260202-wealthy-quick-cow-8c5421@houat> (raw)
In-Reply-To: <20260130-dmabuf-heap-cma-dmem-v1-1-3647ea993e99@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 5582 bytes --]

Hi,

On Fri, Jan 30, 2026 at 05:55:30PM -0500, Eric Chanudet wrote:
> The cma dma-buf heaps let userspace allocate buffers in CMA regions
> without enforcing limits. Register a dmem region per cma heap and charge
> against it when allocating a buffer in a cma heap.
> 
> For the default cma region, two heaps may be created for the same cma
> range:
> commit 854acbe75ff4 ("dma-buf: heaps: Give default CMA heap a fixed name")
>   Introduced /dev/dma_heap/default_cma_region
> commit 4f5f8baf7341 ("dma-buf: heaps: cma: Create CMA heap for each CMA
>                       reserved region")
>   Created a CMA heap for each CMA region, which might create a duplicate
>   heap to the default one, e.g:
>     /dev/dma_heap/default_cma_region
>     /dev/dma_heap/reserved
> 
> Removing the legacy heap would break user API. So handle the special
> case by using one dmem between the two heaps to account charges
> correctly.
> 
> Signed-off-by: Eric Chanudet <echanude@redhat.com>
> ---
> In continuation with introducing cgroup for the system heap[1], this
> behavior is enabled based on dma_heap.mem_accounting, disabled by
> default.
> 
> dmem is chosen for CMA heaps as it allows limits to be set for each
> region backing each heap. There is one caveat for the default cma range
> that may accessible through two different cma heaps, which is treated as
> a special case.
> 
> [1] https://lore.kernel.org/all/20260116-dmabuf-heap-system-memcg-v3-0-ecc6b62cc446@redhat.com/
> ---
>  drivers/dma-buf/heaps/cma_heap.c | 51 ++++++++++++++++++++++++++++++++++++----
>  1 file changed, 46 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/dma-buf/heaps/cma_heap.c b/drivers/dma-buf/heaps/cma_heap.c
> index 49cc45fb42dd7200c3c14384bcfdbe85323454b1..608af8ad6bce7fe0321da6d8f1b65a69f5d8d950 100644
> --- a/drivers/dma-buf/heaps/cma_heap.c
> +++ b/drivers/dma-buf/heaps/cma_heap.c
> @@ -27,6 +27,7 @@
>  #include <linux/scatterlist.h>
>  #include <linux/slab.h>
>  #include <linux/vmalloc.h>
> +#include <linux/cgroup_dmem.h>
>  
>  #define DEFAULT_CMA_NAME "default_cma_region"
>  
> @@ -46,7 +47,9 @@ int __init dma_heap_cma_register_heap(struct cma *cma)
>  struct cma_heap {
>  	struct dma_heap *heap;
>  	struct cma *cma;
> +	struct dmem_cgroup_region *cg;
>  };
> +static struct dmem_cgroup_region *default_cma_cg;
>  
>  struct cma_heap_buffer {
>  	struct cma_heap *heap;
> @@ -58,6 +61,7 @@ struct cma_heap_buffer {
>  	pgoff_t pagecount;
>  	int vmap_cnt;
>  	void *vaddr;
> +	struct dmem_cgroup_pool_state *pool;
>  };
>  
>  struct dma_heap_attachment {
> @@ -276,6 +280,7 @@ static void cma_heap_dma_buf_release(struct dma_buf *dmabuf)
>  	kfree(buffer->pages);
>  	/* release memory */
>  	cma_release(cma_heap->cma, buffer->cma_pages, buffer->pagecount);
> +	dmem_cgroup_uncharge(buffer->pool, buffer->len);
>  	kfree(buffer);
>  }
>  
> @@ -319,9 +324,16 @@ static struct dma_buf *cma_heap_allocate(struct dma_heap *heap,
>  	if (align > CONFIG_CMA_ALIGNMENT)
>  		align = CONFIG_CMA_ALIGNMENT;
>  
> +	if (mem_accounting) {
> +		ret = dmem_cgroup_try_charge(cma_heap->cg, size,
> +					     &buffer->pool, NULL);
> +		if (ret)
> +			goto free_buffer;
> +	}
>
>  	cma_pages = cma_alloc(cma_heap->cma, pagecount, align, false);
>  	if (!cma_pages)
> -		goto free_buffer;
> +		goto uncharge_cgroup;
>  
>  	/* Clear the cma pages */
>  	if (PageHighMem(cma_pages)) {
> @@ -376,6 +388,8 @@ static struct dma_buf *cma_heap_allocate(struct dma_heap *heap,
>  	kfree(buffer->pages);
>  free_cma:
>  	cma_release(cma_heap->cma, cma_pages, pagecount);
> +uncharge_cgroup:
> +	dmem_cgroup_uncharge(buffer->pool, size);

Should we make that conditional on mem_accounting == true ?

>  free_buffer:
>  	kfree(buffer);
>  
> @@ -390,25 +404,52 @@ static int __init __add_cma_heap(struct cma *cma, const char *name)
>  {
>  	struct dma_heap_export_info exp_info;
>  	struct cma_heap *cma_heap;
> +	struct dmem_cgroup_region *region;
> +	int ret;
>  
>  	cma_heap = kzalloc(sizeof(*cma_heap), GFP_KERNEL);
>  	if (!cma_heap)
>  		return -ENOMEM;
>  	cma_heap->cma = cma;
>  
> +	/*
> +	 * If two heaps are created for the default cma region, use the same
> +	 * dmem for them. They both use the same memory pool.
> +	 */
> +	if (dev_get_cma_area(NULL) == cma && default_cma_cg)
> +		region = default_cma_cg;
> +	else {
> +		region = dmem_cgroup_register_region(cma_get_size(cma), "cma/%s", name);
> +		if (IS_ERR(region)) {
> +			ret = PTR_ERR(region);
> +			goto free_cma_heap;
> +		}
> +	}
> +	cma_heap->cg = region;
> +

I'm not sure it's the best way to go with this. We want to track all
relevant CMA allocations going forward, in the heaps and elsewhere.

If we were to do what you suggest, an allocation in, say, DRM or v4l2
wouldn't be tracked in the same region than one in the heaps, while we
want to have it cumulated.

I think we'd be better off if we created a dmem region for each CMA
region in the system, but we would charge from the heap so we don't
account for every allocation.

I don't think we can register the dmem region when the CMA area is
initialized though, since it will probably be too early in the kernel
boot and SLAB isn't around yet.

But since we would need an accessor to get a dmem region from a cma
region, we could do something like check if a dmem eregion already
exists for that cma region, and allocate one otherwise. Or have a
secondary initcall to allocate all dmem regions.

Maxime

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 273 bytes --]

  reply	other threads:[~2026-02-02 10:12 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-30 22:55 [PATCH] dma-buf: heaps: cma: register a dmem region for each cma heap Eric Chanudet
2026-02-02 10:12 ` Maxime Ripard [this message]
2026-02-02 15:18   ` Eric Chanudet

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260202-wealthy-quick-cow-8c5421@houat \
    --to=mripard@redhat.com \
    --cc=Brian.Starkey@arm.com \
    --cc=aesteve@redhat.com \
    --cc=benjamin.gaignard@collabora.com \
    --cc=christian.koenig@amd.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=echanude@redhat.com \
    --cc=jstultz@google.com \
    --cc=linaro-mm-sig@lists.linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=sumit.semwal@linaro.org \
    --cc=tjmercier@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox