From: "Thomas Hellström" <thomas.hellstrom@linux.intel.com>
To: Albert Esteve <aesteve@redhat.com>
Cc: "Tejun Heo" <tj@kernel.org>,
"Johannes Weiner" <hannes@cmpxchg.org>,
"Michal Koutný" <mkoutny@suse.com>,
"Jonathan Corbet" <corbet@lwn.net>,
"Shuah Khan" <skhan@linuxfoundation.org>,
"Sumit Semwal" <sumit.semwal@linaro.org>,
"Christian König" <christian.koenig@amd.com>,
"Michal Hocko" <mhocko@kernel.org>,
"Roman Gushchin" <roman.gushchin@linux.dev>,
"Shakeel Butt" <shakeel.butt@linux.dev>,
"Muchun Song" <muchun.song@linux.dev>,
"Andrew Morton" <akpm@linux-foundation.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 Brauner" <brauner@kernel.org>,
"Paul Moore" <paul@paul-moore.com>,
"James Morris" <jmorris@namei.org>,
"Serge E. Hallyn" <serge@hallyn.com>,
"Stephen Smalley" <stephen.smalley.work@gmail.com>,
"Shuah Khan" <shuah@kernel.org>,
"Randy Dunlap" <rdunlap@infradead.org>,
"Ondrej Mosnáček" <omosnacek@gmail.com>,
"Jens Wiklander" <jenswi@kernel.org>,
"Sumit Garg" <sumit.garg@kernel.org>,
cgroups@vger.kernel.org, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-media@vger.kernel.org,
dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org,
linux-mm@kvack.org, linux-security-module@vger.kernel.org,
selinux@vger.kernel.org, linux-kselftest@vger.kernel.org,
op-tee@lists.trustedfirmware.org
Subject: Re: [Linaro-mm-sig] [PATCH v4 2/8] dma-heap: charge dma-buf memory via explicit memcg
Date: Thu, 12 Nov 2026 11:04:54 +0100 [thread overview]
Message-ID: <22b3ca8cd78b61ecf652a34c5b6b23d7d46208d2.camel@linux.intel.com> (raw)
In-Reply-To: <avWNWnXCXm1sUYch@aesteve-thinkpadp1gen8.rmtes.csb>
On Thu, 2026-11-12 at 10:56 +0100, Albert Esteve wrote:
> On Thu, Nov 12, 2026 at 08:42:18AM +0100, Thomas Hellström wrote:
> > On Wed, 2026-11-04 at 12:09 +0100, Albert Esteve wrote:
> > > On embedded platforms a central process often allocates dma-buf
> > > memory on behalf of client applications. Without a way to
> > > attribute the charge to the requesting client's cgroup, the
> > > cost lands on the allocator, making per-cgroup memory limits
> > > ineffective for the actual consumers.
> > >
> > > Add charge_fd to struct dma_heap_allocation_data. When set to
> > > a valid pidfd or cgroupfd, DMA_HEAP_IOCTL_ALLOC resolves the
> > > target
> > > task's or cgroup's memcg and charges the buffer there via
> > > mem_cgroup_reserve_dmabuf() inside dma_heap_ioctl_allocate(). The
> > > resolved memcg is passed through dma_buf_export_info so that
> > > dma_buf_export() stores it and updates the MEMCG_DMABUF stat.
> > > Without charge_fd, and with the mem_accounting module parameter
> > > enabled, the buffer is charged to the allocator's own cgroup.
> > > The __GPF_ACCOUNT flag is removed from system heap allocations
> > > to avoid double counting.
> > >
> > > Usage examples:
> > >
> > > 1. Central allocator charging to a client at allocation time.
> > > The allocator knows the client's PID (e.g., from binder's
> > > sender_pid) and uses pidfd to attribute the charge:
> > >
> > > pid_t client_pid = txn->sender_pid;
> > > int pidfd = pidfd_open(client_pid, 0);
> > >
> > > struct dma_heap_allocation_data alloc = {
> > > .len = buffer_size,
> > > .fd_flags = O_RDWR | O_CLOEXEC,
> > > .charge_fd = pidfd,
> > > };
> > > ioctl(heap_fd, DMA_HEAP_IOCTL_ALLOC, &alloc);
> > > close(pidfd);
> > > /* alloc.fd is now charged to client's cgroup */
> > >
> > > 2. Default allocation (no pidfd, mem_accounting=1).
> > > When charge_fd is not set and the mem_accounting module
> > > parameter is enabled, the buffer is charged to the
> > > allocator's
> > > own cgroup:
> > >
> > > struct dma_heap_allocation_data alloc = {
> > > .len = buffer_size,
> > > .fd_flags = O_RDWR | O_CLOEXEC,
> > > };
> > > ioctl(heap_fd, DMA_HEAP_IOCTL_ALLOC, &alloc);
> > > /* charged to current process's cgroup */
> > >
> > > Current limitations:
> > >
> > > - Single-owner model: a dma-buf carries one memcg charge
> > > regardless
> > > of
> > > how many processes share it. Means only the first owner (and
> > > exporter)
> > > of the shared buffer bears the charge.
> > > - Only memcg accounting supported. While this makes sense for
> > > system
> > > heap buffers, other heaps (e.g., CMA heaps) will require
> > > selectively
> > > charging also for the dmem controller.
> > >
> > > Signed-off-by: Albert Esteve <aesteve@redhat.com>
> > > ---
> > > Documentation/admin-guide/cgroup-v2.rst | 5 ++--
> > > drivers/dma-buf/dma-buf.c | 5 ++++
> > > drivers/dma-buf/dma-heap.c | 28 +++++++++++++++++--
> > > -
> > > drivers/dma-buf/heaps/cma_heap.c | 3 ++-
> > > drivers/dma-buf/heaps/system_heap.c | 21 +++++++++++----
> > > drivers/tee/tee_heap.c | 3 ++-
> > > include/linux/dma-buf.h | 4 +++
> > > include/linux/dma-heap.h | 3 ++-
> > > include/linux/memcontrol.h | 7 +++++
> > > include/uapi/linux/dma-heap.h | 7 +++++
> > > mm/memcontrol.c | 47
> > > +++++++++++++++++++++++++++++++++
> > > 11 files changed, 120 insertions(+), 13 deletions(-)
> > >
> > > diff --git a/Documentation/admin-guide/cgroup-v2.rst
> > > b/Documentation/admin-guide/cgroup-v2.rst
> > > index a3265a4a953e..66ddba678784 100644
> > > --- a/Documentation/admin-guide/cgroup-v2.rst
> > > +++ b/Documentation/admin-guide/cgroup-v2.rst
> > > @@ -1663,8 +1663,9 @@ The following nested keys are defined.
> > > structures.
> > >
> > > dmabuf (npn)
> > > - Amount of memory used for exported DMA buffers
> > > allocated by the cgroup.
> > > - Stays with the allocating cgroup regardless of
> > > how
> > > the buffer is shared.
> > > + Amount of memory used for exported DMA buffers
> > > allocated by or on
> > > + behalf of the cgroup. Stays with the allocating
> > > cgroup regardless
> > > + of how the buffer is shared.
> >
> > This doesn't sound right. Graphics buffers exported as DMA buffers
> > are
> > typically charged elsewhere, like gpu_active, and a transfer of
> > their
> > charge would likely stay in that key? To be consistent, shouldn't
> > this
> > be related to dma-heap memory and called dmaheap or something
> > similar.
>
> Although this work initially targeted dma heaps only, in its current
> form is meant to stay generic (while solving the central allocator
> problem). The memory exported as dma-bufs has no memory.stat of its
> own, and an exporter allocating plain pages (e.g., V4L2) has nowhere
> else to report it.
>
> > We should have a tighter definition of exactly what memory is to be
> > registered here.
>
> Yes, I will be more specific and clearly state that an exporter
> whose memory is already accounted must not opt in. That also
> naturally disallows transfers.
I would suspect (although not sure TBH) a system that uses a
centralized allocator for gpu memory (even if it's accounted as
gpu_active) might want to be able to transfer the charge as well, so I
think the transfer mechanism might want to be generic enough to handle
that. At least the initial design should IMO allow for a future hook to
handle such transfers even for !dma-buf memory?
Thanks,
Thomas
>
> >
> > Also says "Stays with the allocating cgroup regardless of how the
> > buffer is shared", which isn't correct after the series? Perhaps
> > that's
> > changed in a later patch.
>
> I missed updating the text after having added XFER_CHARGE to the
> series. I'll fix the wording in this patch and mention the transfer
> in the next one.
>
> BR,
> Albert
>
> >
> > Thanks,
> > Thomas
> >
> >
> >
> >
> > >
> > > workingset_refault_anon
> > > Number of refaults of previously evicted
> > > anonymous
> > > pages.
> > > diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-
> > > buf.c
> > > index 1c6b9cee7ac2..837666273550 100644
> > > --- a/drivers/dma-buf/dma-buf.c
> > > +++ b/drivers/dma-buf/dma-buf.c
> > > @@ -714,6 +714,7 @@ struct dma_buf *dma_buf_export(const struct
> > > dma_buf_export_info *exp_info)
> > > struct dma_resv *resv = exp_info->resv;
> > > struct file *file;
> > > size_t alloc_size = sizeof(struct dma_buf);
> > > + unsigned int nr_pages = PAGE_ALIGN(exp_info->size) >>
> > > PAGE_SHIFT;
> > > int ret;
> > >
> > > if (WARN_ON(!exp_info->priv || !exp_info->ops
> > > @@ -750,6 +751,7 @@ struct dma_buf *dma_buf_export(const struct
> > > dma_buf_export_info *exp_info)
> > > dmabuf->size = exp_info->size;
> > > dmabuf->exp_name = exp_info->exp_name;
> > > dmabuf->owner = exp_info->owner;
> > > + dmabuf->memcg = exp_info->memcg;
> > > spin_lock_init(&dmabuf->name_lock);
> > > init_waitqueue_head(&dmabuf->poll);
> > > dmabuf->cb_in.poll = dmabuf->cb_out.poll = &dmabuf-
> > > >poll;
> > > @@ -771,6 +773,9 @@ struct dma_buf *dma_buf_export(const struct
> > > dma_buf_export_info *exp_info)
> > >
> > > DMA_BUF_TRACE(trace_dma_buf_export, dmabuf);
> > >
> > > + if (dmabuf->memcg)
> > > + mod_memcg_state(dmabuf->memcg, MEMCG_DMABUF,
> > > nr_pages);
> > > +
> > > return dmabuf;
> > >
> > > err_file:
> > > diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-
> > > heap.c
> > > index 8a6c2b6e0cc6..7bd416ae2c23 100644
> > > --- a/drivers/dma-buf/dma-heap.c
> > > +++ b/drivers/dma-buf/dma-heap.c
> > > @@ -10,6 +10,8 @@
> > > #include <linux/device.h>
> > > #include <linux/dma-buf.h>
> > > #include <linux/dma-heap.h>
> > > +#include <linux/memcontrol.h>
> > > +#include <linux/sched/mm.h>
> > > #include <linux/err.h>
> > > #include <linux/export.h>
> > > #include <linux/list.h>
> > > @@ -78,6 +80,7 @@ static struct dma_buf
> > > *dma_heap_ioctl_allocate(struct file *file, void *data)
> > > struct dma_heap_allocation_data *heap_allocation = data;
> > > struct dma_heap *heap = file->private_data;
> > > struct dma_buf *dmabuf;
> > > + struct mem_cgroup *memcg = NULL;
> > > int fd;
> > > size_t len;
> > >
> > > @@ -90,15 +93,34 @@ static struct dma_buf
> > > *dma_heap_ioctl_allocate(struct file *file, void *data)
> > > if (heap_allocation->heap_flags &
> > > ~DMA_HEAP_VALID_HEAP_FLAGS)
> > > return ERR_PTR(-EINVAL);
> > >
> > > + if (heap_allocation->__padding != 0)
> > > + return ERR_PTR(-EINVAL);
> > > +
> > > + if (heap_allocation->charge_fd) {
> > > + memcg = mem_cgroup_get_from_fd(heap_allocation-
> > > > charge_fd);
> > > + if (IS_ERR(memcg))
> > > + return ERR_CAST(memcg);
> > > + }
> > > +
> > > + if (!memcg && mem_accounting)
> > > + memcg = get_mem_cgroup_from_mm(current->mm);
> > > +
> > > len = PAGE_ALIGN(heap_allocation->len);
> > > - if (!len)
> > > + if (!len) {
> > > + mem_cgroup_put(memcg);
> > > return ERR_PTR(-EINVAL);
> > > + }
> > >
> > > dmabuf = heap->ops->allocate(heap, len, heap_allocation-
> > > > fd_flags,
> > > - heap_allocation-
> > > >heap_flags);
> > > + heap_allocation-
> > > >heap_flags,
> > > memcg);
> > >
> > > - if (IS_ERR(dmabuf))
> > > + if (IS_ERR(dmabuf)) {
> > > + mem_cgroup_put(memcg);
> > > return dmabuf;
> > > + }
> > > +
> > > + if (memcg && !dmabuf->memcg)
> > > + mem_cgroup_put(memcg);
> > >
> > > fd = get_unused_fd_flags(heap_allocation->fd_flags);
> > > if (fd < 0) {
> > > diff --git a/drivers/dma-buf/heaps/cma_heap.c b/drivers/dma-
> > > buf/heaps/cma_heap.c
> > > index 3fb4b946c91a..04de88b468a8 100644
> > > --- a/drivers/dma-buf/heaps/cma_heap.c
> > > +++ b/drivers/dma-buf/heaps/cma_heap.c
> > > @@ -281,7 +281,8 @@ static const struct dma_buf_ops
> > > cma_heap_buf_ops
> > > = {
> > > static struct dma_buf *cma_heap_allocate(struct dma_heap *heap,
> > > unsigned long len,
> > > u32 fd_flags,
> > > - u64 heap_flags)
> > > + u64 heap_flags,
> > > + struct mem_cgroup
> > > *memcg)
> > > {
> > > struct cma_heap *cma_heap = dma_heap_get_drvdata(heap);
> > > struct cma_heap_buffer *buffer;
> > > diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-
> > > buf/heaps/system_heap.c
> > > index c8959eadc71d..2bd245e1eab8 100644
> > > --- a/drivers/dma-buf/heaps/system_heap.c
> > > +++ b/drivers/dma-buf/heaps/system_heap.c
> > > @@ -17,6 +17,7 @@
> > > #include <linux/err.h>
> > > #include <linux/highmem.h>
> > > #include <linux/mem_encrypt.h>
> > > +#include <linux/memcontrol.h>
> > > #include <linux/mm.h>
> > > #include <linux/set_memory.h>
> > > #include <linux/module.h>
> > > @@ -388,8 +389,6 @@ static struct page
> > > *alloc_largest_available(unsigned long size,
> > > if (max_order < orders[i])
> > > continue;
> > > flags = order_flags[i];
> > > - if (mem_accounting)
> > > - flags |= __GFP_ACCOUNT;
> > > page = alloc_pages(flags, orders[i]);
> > > if (!page)
> > > continue;
> > > @@ -401,11 +400,13 @@ static struct page
> > > *alloc_largest_available(unsigned long size,
> > > static struct dma_buf *system_heap_allocate(struct dma_heap
> > > *heap,
> > > unsigned long len,
> > > u32 fd_flags,
> > > - u64 heap_flags)
> > > + u64 heap_flags,
> > > + struct mem_cgroup
> > > *memcg)
> > > {
> > > struct system_heap_buffer *buffer;
> > > DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
> > > unsigned long size_remaining = len;
> > > + unsigned int nr_pages = PAGE_ALIGN(len) >> PAGE_SHIFT;
> > > unsigned int max_order = orders[0];
> > > struct system_heap_priv *priv =
> > > dma_heap_get_drvdata(heap);
> > > bool cc_shared = priv->cc_shared;
> > > @@ -416,10 +417,15 @@ static struct dma_buf
> > > *system_heap_allocate(struct dma_heap *heap,
> > > struct page *page, *tmp_page;
> > > int i, ret = -ENOMEM;
> > >
> > > - buffer = kzalloc_obj(*buffer);
> > > - if (!buffer)
> > > + if (!mem_cgroup_reserve_dmabuf(memcg, GFP_KERNEL,
> > > nr_pages))
> > > return ERR_PTR(-ENOMEM);
> > >
> > > + buffer = kzalloc_obj(*buffer);
> > > + if (!buffer) {
> > > + ret = -ENOMEM;
> > > + goto cancel_charge;
> > > + }
> > > +
> > > INIT_LIST_HEAD(&buffer->attachments);
> > > mutex_init(&buffer->lock);
> > > buffer->heap = heap;
> > > @@ -473,11 +479,14 @@ static struct dma_buf
> > > *system_heap_allocate(struct dma_heap *heap,
> > > exp_info.size = buffer->len;
> > > exp_info.flags = fd_flags;
> > > exp_info.priv = buffer;
> > > + if (memcg)
> > > + exp_info.memcg = memcg;
> > > dmabuf = dma_buf_export(&exp_info);
> > > if (IS_ERR(dmabuf)) {
> > > ret = PTR_ERR(dmabuf);
> > > goto free_pages;
> > > }
> > > +
> > > return dmabuf;
> > >
> > > free_pages:
> > > @@ -498,6 +507,8 @@ static struct dma_buf
> > > *system_heap_allocate(struct dma_heap *heap,
> > > list_for_each_entry_safe(page, tmp_page, &pages, lru)
> > > __free_pages(page, compound_order(page));
> > > kfree(buffer);
> > > +cancel_charge:
> > > + mem_cgroup_cancel_dmabuf(memcg, nr_pages);
> > >
> > > return ERR_PTR(ret);
> > > }
> > > diff --git a/drivers/tee/tee_heap.c b/drivers/tee/tee_heap.c
> > > index 007c00156520..83e2fbd6960b 100644
> > > --- a/drivers/tee/tee_heap.c
> > > +++ b/drivers/tee/tee_heap.c
> > > @@ -167,7 +167,8 @@ static const struct dma_buf_ops
> > > tee_heap_buf_ops
> > > = {
> > >
> > > static struct dma_buf *tee_dma_heap_alloc(struct dma_heap *heap,
> > > unsigned long len, u32
> > > fd_flags,
> > > - u64 heap_flags)
> > > + u64 heap_flags,
> > > + struct mem_cgroup
> > > *memcg)
> > > {
> > > struct tee_dma_heap *h = dma_heap_get_drvdata(heap);
> > > DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
> > > diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
> > > index 23ec0ff23fba..85dd747c9b36 100644
> > > --- a/include/linux/dma-buf.h
> > > +++ b/include/linux/dma-buf.h
> > > @@ -505,6 +505,9 @@ struct dma_buf_attachment {
> > > * @flags: mode flags for the file
> > > * @resv: reservation-object, NULL to allocate default one
> > > * @priv: Attach private data of allocator to this buffer
> > > + * @memcg: memcg to charge for this buffer's memory. Set
> > > only
> > > for
> > > + * buffers backed by system memory where @size
> > > reflects
> > > the
> > > + * actual allocation in bytes.
> > > *
> > > * This structure holds the information required to export the
> > > buffer. Used
> > > * with dma_buf_export() only.
> > > @@ -517,6 +520,7 @@ struct dma_buf_export_info {
> > > int flags;
> > > struct dma_resv *resv;
> > > void *priv;
> > > + struct mem_cgroup *memcg;
> > > };
> > >
> > > /**
> > > diff --git a/include/linux/dma-heap.h b/include/linux/dma-heap.h
> > > index 648328a64b27..2d69f8432bd2 100644
> > > --- a/include/linux/dma-heap.h
> > > +++ b/include/linux/dma-heap.h
> > > @@ -23,7 +23,8 @@ struct dma_heap_ops {
> > > struct dma_buf *(*allocate)(struct dma_heap *heap,
> > > unsigned long len,
> > > u32 fd_flags,
> > > - u64 heap_flags);
> > > + u64 heap_flags,
> > > + struct mem_cgroup *memcg);
> > > };
> > >
> > > /**
> > > diff --git a/include/linux/memcontrol.h
> > > b/include/linux/memcontrol.h
> > > index 4d1e82cf0833..f8ec751b7d7b 100644
> > > --- a/include/linux/memcontrol.h
> > > +++ b/include/linux/memcontrol.h
> > > @@ -671,6 +671,8 @@ int mem_cgroup_charge_hugetlb(struct folio*
> > > folio, gfp_t gfp);
> > > int mem_cgroup_swapin_charge_folio(struct folio *folio, unsigned
> > > short id,
> > > struct mm_struct *mm, gfp_t
> > > gfp);
> > >
> > > +struct mem_cgroup *mem_cgroup_get_from_fd(int fd);
> > > +
> > > bool mem_cgroup_reserve_dmabuf(struct mem_cgroup *memcg, gfp_t
> > > gfp,
> > > unsigned int nr_pages);
> > >
> > > @@ -1178,6 +1180,11 @@ static inline int
> > > mem_cgroup_swapin_charge_folio(struct folio *folio,
> > > return 0;
> > > }
> > >
> > > +static inline struct mem_cgroup *mem_cgroup_get_from_fd(int fd)
> > > +{
> > > + return ERR_PTR(-EOPNOTSUPP);
> > > +}
> > > +
> > > static inline bool mem_cgroup_reserve_dmabuf(struct mem_cgroup
> > > *memcg,
> > > gfp_t gfp,
> > > unsigned int
> > > nr_pages)
> > > diff --git a/include/uapi/linux/dma-heap.h
> > > b/include/uapi/linux/dma-
> > > heap.h
> > > index a4cf716a49fa..bfcd1c25bc7e 100644
> > > --- a/include/uapi/linux/dma-heap.h
> > > +++ b/include/uapi/linux/dma-heap.h
> > > @@ -29,6 +29,11 @@
> > > * handle to the allocated dma-buf
> > > * @fd_flags: file descriptor flags used when
> > > allocating
> > > * @heap_flags: flags passed to heap
> > > + * @charge_fd: optional pidfd or cgroupfd whose cgroup
> > > should be
> > > + * charged for this allocation; 0 means
> > > charge
> > > the calling
> > > + * process's cgroup when the mem_accounting
> > > module parameter
> > > + * is enabled, or skip charging otherwise
> > > + * @__padding: reserved, must be zero
> > > *
> > > * Provided by userspace as an argument to the ioctl
> > > */
> > > @@ -37,6 +42,8 @@ struct dma_heap_allocation_data {
> > > __u32 fd;
> > > __u32 fd_flags;
> > > __u64 heap_flags;
> > > + __u32 charge_fd;
> > > + __u32 __padding;
> > > };
> > >
> > > #define DMA_HEAP_IOC_MAGIC 'H'
> > > diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> > > index e53dd7eebc3b..17fdefc56b97 100644
> > > --- a/mm/memcontrol.c
> > > +++ b/mm/memcontrol.c
> > > @@ -5661,6 +5661,53 @@ void mem_cgroup_flush_workqueue(void)
> > > flush_workqueue(memcg_wq);
> > > }
> > >
> > > +/**
> > > + * mem_cgroup_get_from_fd - resolve a memcg from a cgroupfd or
> > > pidfd
> > > + * @fd: file descriptor (cgroupfd or pidfd)
> > > + *
> > > + * Tries @fd as a cgroupfd first; if that fails, tries it as a
> > > pidfd.
> > > + * On success returns a referenced memcg pointer. On failure
> > > returns
> > > + * an ERR_PTR.
> > > + */
> > > +struct mem_cgroup *mem_cgroup_get_from_fd(int fd)
> > > +{
> > > + struct cgroup_subsys_state *css;
> > > + struct mem_cgroup *memcg;
> > > + struct cgroup *cgrp;
> > > + struct task_struct *task;
> > > + struct mm_struct *mm;
> > > + unsigned int pidfd_flags;
> > > +
> > > + cgrp = cgroup_get_from_fd(fd);
> > > + if (!IS_ERR(cgrp)) {
> > > + rcu_read_lock();
> > > + css = cgroup_css(cgrp, &memory_cgrp_subsys);
> > > + if (!css || !css_tryget_online(css)) {
> > > + rcu_read_unlock();
> > > + cgroup_put(cgrp);
> > > + return ERR_PTR(-ENOENT);
> > > + }
> > > +
> > > + memcg = mem_cgroup_from_css(css);
> > > + rcu_read_unlock();
> > > + cgroup_put(cgrp);
> > > + return memcg;
> > > + }
> > > +
> > > + task = pidfd_get_task(fd, &pidfd_flags);
> > > + if (IS_ERR(task))
> > > + return ERR_CAST(task);
> > > +
> > > + mm = get_task_mm(task);
> > > + put_task_struct(task);
> > > + if (!mm)
> > > + return ERR_PTR(-ESRCH);
> > > +
> > > + memcg = get_mem_cgroup_from_mm(mm);
> > > + mmput(mm);
> > > + return memcg ?: ERR_PTR(-ENOENT);
> > > +}
> > > +
> > > /**
> > > * mem_cgroup_reserve_dmabuf - charge a memcg for a dma-buf
> > > allocation
> > > * @memcg: memcg to charge (may be %NULL)
next prev parent reply other threads:[~2026-11-12 10:05 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-04 11:09 [PATCH v4 0/8] memcg: dma-buf cgroup accounting and charge transfer Albert Esteve
2026-11-04 11:09 ` [PATCH v4 1/8] memcg: Add MEMCG_DMABUF accounting infrastructure Albert Esteve
2026-11-12 7:26 ` [Linaro-mm-sig] " Thomas Hellström
2026-11-12 8:57 ` Albert Esteve
2026-11-04 11:09 ` [PATCH v4 2/8] dma-heap: charge dma-buf memory via explicit memcg Albert Esteve
2026-11-12 7:42 ` [Linaro-mm-sig] " Thomas Hellström
2026-11-12 9:56 ` Albert Esteve
2026-11-12 10:04 ` Thomas Hellström [this message]
2026-11-12 10:35 ` Albert Esteve
2026-11-04 11:09 ` [PATCH v4 3/8] dma-buf: transfer memcg charges via DMA_BUF_IOCTL_XFER_CHARGE Albert Esteve
2026-11-04 13:51 ` Christian König
2026-11-06 15:21 ` Albert Esteve
2026-11-12 7:46 ` [Linaro-mm-sig] " Thomas Hellström
2026-11-12 10:02 ` Albert Esteve
2026-11-04 11:09 ` [PATCH v4 4/8] security: dma-buf: Add dma_buf_charge_task LSM hook Albert Esteve
2026-11-04 11:09 ` [PATCH v4 5/8] security: dma-buf: Add dma_buf_charge_cgroup " Albert Esteve
2026-11-04 11:09 ` [PATCH v4 6/8] selinux: Restrict cross-cgroup dma-buf charging Albert Esteve
2026-11-04 11:09 ` [PATCH v4 7/8] selinux: Restrict dma-buf direct cgroup charging Albert Esteve
2026-11-04 11:09 ` [PATCH v4 8/8] selftests/dmabuf-heaps: Add dma-buf memcg accounting tests Albert Esteve
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=22b3ca8cd78b61ecf652a34c5b6b23d7d46208d2.camel@linux.intel.com \
--to=thomas.hellstrom@linux.intel.com \
--cc=Brian.Starkey@arm.com \
--cc=aesteve@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=benjamin.gaignard@collabora.com \
--cc=brauner@kernel.org \
--cc=cgroups@vger.kernel.org \
--cc=christian.koenig@amd.com \
--cc=corbet@lwn.net \
--cc=dri-devel@lists.freedesktop.org \
--cc=hannes@cmpxchg.org \
--cc=jenswi@kernel.org \
--cc=jmorris@namei.org \
--cc=jstultz@google.com \
--cc=linaro-mm-sig@lists.linaro.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-security-module@vger.kernel.org \
--cc=mhocko@kernel.org \
--cc=mkoutny@suse.com \
--cc=muchun.song@linux.dev \
--cc=omosnacek@gmail.com \
--cc=op-tee@lists.trustedfirmware.org \
--cc=paul@paul-moore.com \
--cc=rdunlap@infradead.org \
--cc=roman.gushchin@linux.dev \
--cc=selinux@vger.kernel.org \
--cc=serge@hallyn.com \
--cc=shakeel.butt@linux.dev \
--cc=shuah@kernel.org \
--cc=skhan@linuxfoundation.org \
--cc=stephen.smalley.work@gmail.com \
--cc=sumit.garg@kernel.org \
--cc=sumit.semwal@linaro.org \
--cc=tj@kernel.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