This series adds memory cgroup accounting for dma-buf allocations, building on T.J. Mercier's earlier series [1] and incorporating feedback from the v1 and LPC discussions.
Patch 1 introduces the MEMCG_DMABUF stat and charge/uncharge helpers. Rather than charging at the page level via __GFP_ACCOUNT (which would require every dma-buf exporter to implement charging, and makes cross-cgroup transfer impractical without access to backing pages), we track charges externally on struct dma_buf via a MEMCG_DMABUF stat counter and route all accounting through a single path, removing the __GFP_ACCOUNT flag from system-heap allocations to avoid double counting.
Patch 2 adds a charge_fd field to DMA_HEAP_IOCTL_ALLOC, accepting either a pidfd or a cgroupfd to identify the target cgroup at allocation time. If the target cgroup cannot accommodate the charge, the allocation returns -ENOMEM.
Patches 3-4 add LSM hooks for the two charge_fd flavours: security_dma_buf_charge_task() gates the pidfd path (target identified by task credentials) and security_dma_buf_charge_cgroup() gates the cgroupfd path (target identified by cgroup directory label).
Patches 5-6 implement the SELinux side under a dma_buf object class with charge_task and charge_cgroup permissions. For charge_cgroup, the target SID is derived from the cgroup directory's SELinux label.
Patch 7 adds DMA_BUF_IOCTL_XFER_CHARGE, a general ioctl on any dma-buf fd to transfer charges (or charge) post-allocation. This covers the double-hop allocator case (SurfaceFlinger -> gralloc) and works for buffers from any exporter (DRM, V4L2, etc.). If the receiving cgroup lacks capacity for the charge, the ioctl returns -ENOMEM and the original charge is preserved.
Patch 8 adds selftests.
Known limitations:
- Single-owner model: a dma-buf carries one memcg charge regardless of how many processes share it. - Only memcg accounting. CMA heaps would additionally need dmem controller integration. - Charging CMA-backed heaps to memcg charges unreclaimable memory: when a cgroup hits its limit, try_charge_memcg() may trigger a reclaim pass that cannot free CMA pages. A future version could move charging into per-heap callbacks. - If a transfer of an uncharged buffer fails, the buffer remains uncharged. The allocator (userspace) is expected to handle this (e.g., retry, free, ...). - The LSM hook is intentionally narrow. Broader cgroup access controls could be a separate effort.
[1] https://lore.kernel.org/cgroups/20230109213809.418135-1-tjmercier@google.com...
Signed-off-by: Albert Esteve aesteve@redhat.com --- Changes in v2: - Move charge_pid_fd to charge_fd, accepting cgroupfd in addition to pidfd per Christian König. - New DMA_BUF_IOCTL_XFER_CHARGE ioctl for post-allocation charge transfer on any dma-buf, not just dma-heap buffers per Christian König and T.J. Mercier. - Moved __GFP_ACCOUNT removal to patch 1 per Barry Song. - dma-buf charge/uncharge helpers take struct dma_buf * directly to avoid the need for caller to manage size calculations. - Added test_xfer_charge_cgroupfd_self to dmabuf-heap selftests. - Added LSM and SELinux hooks for cgroupfd-based charging. - Rebased to v7.3-rc7. - Link to v1: https://lore.kernel.org/r/20260512-v2_20230123_tjmercier_google_com-v1-0-632...
--- Albert Esteve (7): dma-heap: charge dma-buf memory via explicit memcg security: dma-buf: Add dma_buf_charge_task LSM hook security: dma-buf: Add dma_buf_charge_cgroup LSM hook selinux: Restrict cross-cgroup dma-buf charging selinux: Restrict dma-buf direct cgroup charging dma-buf: transfer memcg charges via DMA_BUF_IOCTL_XFER_CHARGE selftests/dmabuf-heaps: Add dma-buf memcg accounting tests
T.J. Mercier (1): memcg: Add MEMCG_DMABUF accounting infrastructure
Documentation/admin-guide/cgroup-v2.rst | 5 + drivers/dma-buf/dma-buf.c | 80 ++++++++ drivers/dma-buf/dma-heap.c | 72 ++++++- drivers/dma-buf/heaps/system_heap.c | 2 - include/linux/dma-buf.h | 4 + include/linux/lsm_hook_defs.h | 2 + include/linux/memcontrol.h | 29 +++ include/linux/security.h | 14 ++ include/uapi/linux/dma-buf.h | 26 +++ include/uapi/linux/dma-heap.h | 7 + mm/memcontrol.c | 94 +++++++++ security/security.c | 32 +++ security/selinux/hooks.c | 40 ++++ security/selinux/include/classmap.h | 1 + tools/testing/selftests/cgroup/Makefile | 2 +- tools/testing/selftests/cgroup/test_memcontrol.c | 145 +++++++++++++- tools/testing/selftests/dmabuf-heaps/config | 1 + tools/testing/selftests/dmabuf-heaps/dmabuf-heap.c | 222 ++++++++++++++++++++- tools/testing/selftests/dmabuf-heaps/vmtest.sh | 205 +++++++++++++++++++ 19 files changed, 974 insertions(+), 9 deletions(-) --- base-commit: 24a19b953e2a3d0ea5a8c4951a0ab8f32720c907 change-id: 20260508-v2_20230123_tjmercier_google_com-f44fcfb16530
Best regards,