On Thu, 2026-10-22 at 18:20 +1100, Alistair Popple wrote:
> On 2026-10-22 at 17:59 +1100, Thomas Hellström
> <thomas.hellstrom(a)linux.intel.com> wrote...
> > On Wed, 2026-10-21 at 09:37 -0300, Jason Gunthorpe wrote:
> > > On Wed, Oct 21, 2026 at 08:24:40AM +0200, Thomas Hellström wrote:
> > > > > struct dma_buf_mapping_exp_ops
> > > > > Base type for the per-mapping type exporter provided
> > > > > functions.
> > > > > This
> > > > > would be the map/unmap callbacks. Each mapping type can
> > > > > provide
> > > > > its own
> > > > > functions for map/unmap type operations with optimal type
> > > > > signatures.
> > > >
> > > > Does it make sense to try to land this patch first, plus a
> > > > conversion
> > > > of pcie_p2p so we could agree on what the contract should look
> > > > like?
> > >
> > > I think it would be good to focus on this patch as the main
> > > 'crux' of
> > > the series. The API contract is the main agreement. I'm relucant
> > > to
> > > merge code that has no users, so it woudl be ebtter to go up to
> > > at
> > > least through SGT.
> >
> > I agree about unused code, but wouldn't a pcie_p2p conversion to a
> > mapping type be a valid use-case?
>
> In some ways I think having both sgt and the pcie_p2p conversion is
> helpful as
> it demonstrates how different mapping types are used. I agree the
> important bit
> is settling on the contract though. Adding a pcie_p2p conversion on
> top doesn't
> look too hard though. Thomas would you be ok if I rebased and posted
> some of
> your patches[1] adding pcie_p2p on top of the mapping types + SGT
> conversion
> v2 I'm getting ready to send to demonstrate usage? Or would you
> rather do that
> after I send?
Please go ahead and use them as you wish. That was only a quick mostly
AI-generated POC.
Thanks,
Thomas
>
> [1] -
> https://gitlab.freedesktop.org/thomash/xe-vibe/-/commit/7452df0fc858a7dc5cc…
>
> - Alistair
>
> > >
> > > > s/mapping/interconnect/? My gut feeling is that "interconnect"
> > > > best
> > > > describes what's typically going on, but "mapping" perhaps
> > > > better
> > > > describes all cases.
> > >
> > > My intention was to cover more than just the phyiscal transport.
> > > We
> > > do
> > > really want to get away from scatterlist, so having PCIe map with
> > > scatterlist and PCIe map with <something else> still ends up with
> > > two
> > > mapping types in the system.
> > >
> > > This is why I choose the name over interconnect.
> > >
> > > > Location of common protocols which typically carry cross-
> > > > subsystem
> > > > dependencies?
> > > > drivers/dma-buf/mapping_types? drivers/dma-buf/interconnects?
> > >
> > > I'd encourage people to design more like PCI where the actual
> > > *interconnect* has its own home and there is just some minor call
> > > outs
> > > from dmabuf to help the matching logic.
> > >
> > > > As discussed previously:
> > > > Agree on theoretically possible matches at attach time, Match
> > > > at
> > > > mapping time and guarantee the match is valid until
> > > > invalidate_mappings().
> > >
> > > I was thinking about this some more, and I'm less sure now.
> > >
> > > If I think about mlx5, in a multi-path PCIe configuration, it can
> > > move
> > > the translation around within a single PCIe path, but it cannot
> > > move
> > > it to another path without creating disruption for the
> > > application. This is a HW limitation in how the internal routing
> > > works..
> > >
> > > I strongly suspect this will be the norm for any hardware that
> > > doesn't
> > > rely on decorated page tables to select the IO path..
> > >
> > > So, while I agree we should support hardware that can fully
> > > change
> > > the
> > > path on each and every map, we also need to suport hardware that
> > > must
> > > pin the path during attach.
> > >
> > > Probably this points to needing a 'pin' operation for the mapping
> > > selection after attach.
> > >
> > > > > +/*
> > > > > + * Match items are generated by the importer using the
> > > > > DMA_BUF_IMAPPING_*() and
> > > > > + * the exporter using the DMA_BUF_EMAPPING_*() functions.
> > > > > Each
> > > > > mapping type
> > > > > + * defines its own signature with its own data to make the
> > > > > match
> > > > > and
> > > > > attachment.
> > > > > + */
> > > > > +struct dma_buf_mapping_match {
> > > > > + const struct dma_buf_mapping_type *type;
> > > > > + const struct dma_buf_mapping_exp_ops *exp_ops;
> > > > > + union {
> > > > > + /* Each mapping_type has unique match
> > > > > parameters
> > > > > here */
> > > > > + };
> > > >
> > > > Do we really need to add all global mapping types here? Then
> > > > we'd
> > > > need
> > > > something for driver-private mapping types as well.
> > >
> > > IIRC it is fixed size up front like this because of how the
> > > structure's memory is managed in this design..
> > >
> > > If you want a driver private thing then I'd add a 'u64
> > > driver_private[2]' to the union and the driver can cast over it.
> > >
> > > But this is the kernel, if you want to add an xe_mapping_type,
> > > then
> > > just add it. I don't know we need to do driver private things.
> >
> > I guess it's my wish to separate components. Couldn't this lead to
> > excessive includes and unnecessary dma-buf recompilations when
> > mostly
> > unrelated headers are touched? Except possibly for memory size,
> > core
> > dma-buf shouldn't need to know about this, it's a mapping private
> > thing?
> >
> > /Thomas
> >
> >
> > >
> > > Jason
On Thu, 2026-10-22 at 17:52 +1100, Alistair Popple wrote:
> On 2026-10-21 at 23:37 +1100, Jason Gunthorpe <jgg(a)nvidia.com>
> wrote...
> > On Wed, Oct 21, 2026 at 08:24:40AM +0200, Thomas Hellström wrote:
> > > > struct dma_buf_mapping_exp_ops
> > > > Base type for the per-mapping type exporter provided
> > > > functions.
> > > > This
> > > > would be the map/unmap callbacks. Each mapping type can
> > > > provide
> > > > its own
> > > > functions for map/unmap type operations with optimal type
> > > > signatures.
> > >
> > > Does it make sense to try to land this patch first, plus a
> > > conversion
> > > of pcie_p2p so we could agree on what the contract should look
> > > like?
> >
> > I think it would be good to focus on this patch as the main 'crux'
> > of
> > the series. The API contract is the main agreement. I'm relucant to
> > merge code that has no users, so it woudl be ebtter to go up to at
> > least through SGT.
> >
> > > s/mapping/interconnect/? My gut feeling is that "interconnect"
> > > best
> > > describes what's typically going on, but "mapping" perhaps better
> > > describes all cases.
> >
> > My intention was to cover more than just the phyiscal transport. We
> > do
> > really want to get away from scatterlist, so having PCIe map with
> > scatterlist and PCIe map with <something else> still ends up with
> > two
> > mapping types in the system.
> >
> > This is why I choose the name over interconnect.
> >
> > > Location of common protocols which typically carry cross-
> > > subsystem
> > > dependencies?
> > > drivers/dma-buf/mapping_types? drivers/dma-buf/interconnects?
> >
> > I'd encourage people to design more like PCI where the actual
> > *interconnect* has its own home and there is just some minor call
> > outs
> > from dmabuf to help the matching logic.
> >
> > > As discussed previously:
> > > Agree on theoretically possible matches at attach time, Match at
> > > mapping time and guarantee the match is valid until
> > > invalidate_mappings().
> >
> > I was thinking about this some more, and I'm less sure now.
> >
> > If I think about mlx5, in a multi-path PCIe configuration, it can
> > move
> > the translation around within a single PCIe path, but it cannot
> > move
> > it to another path without creating disruption for the
> > application. This is a HW limitation in how the internal routing
> > works..
> >
> > I strongly suspect this will be the norm for any hardware that
> > doesn't
> > rely on decorated page tables to select the IO path..
> >
> > So, while I agree we should support hardware that can fully change
> > the
> > path on each and every map, we also need to suport hardware that
> > must
> > pin the path during attach.
> >
> > Probably this points to needing a 'pin' operation for the mapping
> > selection after attach.
>
> If I'm understanding things correctly we're expecting a change in
> path between
> attach and map time to be rare in practice. Therefore the need to
> handle this
> case is mostly as a fallback to not break things. So instead of
> pinning could
> new attachments just invalidate all existing incompatible attachments
> on the
> list by setting eg. attach->valid = 0?
I agree, (although I think the "invalidate_attachment" needs to be
discussed). In the end the importer should be given a choice, either
pin and accept that subsequent attachers might see errors or accept
app disruption.
>
> Attachment could also scan existing attachments to preferentially
> pick matching
> mapping_types that are compatible with existing attachments, thus
> avoiding
> invalidation where possible.
Current design appears to be that attach only determines the set of
theoretically possible mapping types, disregarding other attachments.
Taking other attachments into account is also problematic because the
dma-resv lock is not held.
Looking at current GPU drivers, what you describe above is typically
done at pin() time, but if some importers want an early very likely
decision on what mapping_type to use, one could introduce a separate
function that match the mapping_types, but that would be very similar
to the map() function but without returning a sgt/mapping, or a pin()
without actually pinning. One could reuse the invalidate_mappings()
callback to indicate the mapping type is no longer valid?
/Thomas
>
> Map time functions (eg. dma_buf_sgt_map_attachment) would check
> attach->valid
> and return a failure if a subsequent attachment/event had invalidated
> the
> mapping type.
>
> Importers with invalidated attachments would then have to retry
> creating the
> attachment, probably getting a different mapping_type. Would this be
> acceptable?
> Or do some importers absolutely require the mapping_type to never
> change once
> the intial match/attachment has happened?
>
> - Alistair
>
> > > > +/*
> > > > + * Match items are generated by the importer using the
> > > > DMA_BUF_IMAPPING_*() and
> > > > + * the exporter using the DMA_BUF_EMAPPING_*() functions. Each
> > > > mapping type
> > > > + * defines its own signature with its own data to make the
> > > > match and
> > > > attachment.
> > > > + */
> > > > +struct dma_buf_mapping_match {
> > > > + const struct dma_buf_mapping_type *type;
> > > > + const struct dma_buf_mapping_exp_ops *exp_ops;
> > > > + union {
> > > > + /* Each mapping_type has unique match
> > > > parameters
> > > > here */
> > > > + };
> > >
> > > Do we really need to add all global mapping types here? Then we'd
> > > need
> > > something for driver-private mapping types as well.
> >
> > IIRC it is fixed size up front like this because of how the
> > structure's memory is managed in this design..
> >
> > If you want a driver private thing then I'd add a 'u64
> > driver_private[2]' to the union and the driver can cast over it.
> >
> > But this is the kernel, if you want to add an xe_mapping_type, then
> > just add it. I don't know we need to do driver private things.
> >
> > Jason
Since its introduction, DMA-buf has only supported using scatterlist for
the exporter and importer to exchange address information. This is not
sufficient for all use cases as dma_addr_t is a very specific and limited
type that should not be abused for things unrelated to the DMA API.
There are several motivations for addressing this now:
1) VFIO to IOMMUFD and KVM requires a physical address, not a dma_addr_t
scatterlist, it cannot be represented in the scatterlist structure
2) xe vGPU requires the host driver to accept a DMABUF from VFIO of its
own VF and convert it into an internal VRAM address on the PF
3) We are starting to look at replacement datastructures for
scatterlist
4) Ideas around UALink/etc are suggesting not using the DMA API
None of these can sanely be achieved using scatterlist.
Introduce a new mechanism called "mapping types" which allows DMA-buf to
work with more map/unmap options than scatterlist. Each mapping type
encompasses a full set of functions and data unique to itself. The core
code provides a match-making system to select the best type offered by the
exporter and importer to be the active mapping type for the attachment.
Everything related to scatterlist is moved into a DMA-buf SGT mapping
type, and into the "dma_buf_sgt_*" namespace for clarity. Existing
exporters are moved over to explicitly declare SGT mapping types and
importers are adjusted to use the dma_buf_sgt_* named importer helpers.
Mapping types are designed to be extendable, a driver can declare its own
mapping type for its internal private interconnect and use that without
having to adjust the core code.
The new attachment sequence starts with the importing driver declaring
what mapping types it can accept:
struct dma_buf_mapping_match imp_match[] = {
DMA_BUF_IMAPPING_MY_DRIVER(dev, ...),
DMA_BUF_IMAPPING_SGT(dev, false),
};
attach = dma_buf_mapping_attach(dmabuf, imp_match, ...)
Most drivers will do this via a dma_buf_sgt_*attach() helper.
The exporting driver can then declare what mapping types it can supply:
int exporter_match_mapping(struct dma_buf_match_args *args)
{
struct dma_buf_mapping_match exp_match[] = {
DMA_BUF_EMAPPING_MY_DRIVER(my_ops, dev, ...),
DMA_BUF_EMAPPING_SGT(sgt_ops, dev, false),
DMA_BUF_EMAPPING_PAL(PAL_ops),
};
return dma_buf_match_mapping(args, exp_match, ...);
}
Most drivers will do this via a helper:
static const struct dma_buf_ops ops = {
DMA_BUF_SIMPLE_SGT_EXP_MATCH(map_func, unmap_func)
};
During dma_buf_mapping_attach() the core code will select a mutual match
between the importer and exporter and record it as the active match in
the attach->map_type.
Each mapping type has its own types/function calls for
mapping/unmapping, and storage in the attach->map_type for its
information. As such each mapping type can offer function signatures
and data that exactly matches its needs.
This series goes through a sequence of:
1) Introduce the basic mapping type framework and the main components of
the SGT mapping type
2) Automatically make all existing exporters and importers use core
generated SGT mapping types so every attachment has a SGT mapping type
3) Convert all exporter drivers to natively create a SGT mapping type
4) Move all dma_buf_* functions and types that are related to SGT into
dma_buf_sgt_*
5) Remove all the now-unused items that have been moved into SGT specific
structures.
6) Demonstrate adding a new Physical Address List alongside SGT.
Due to the high number of files touched I would expect this to be broken
into phases, but this shows the entire picture.
This is on github: https://github.com/jgunthorpe/linux/commits/dmabuf_map_type
It is a followup to the discussion here:
https://lore.kernel.org/dri-devel/20251027044712.1676175-1-vivek.kasireddy@…
Jason Gunthorpe (26):
dma-buf: Introduce DMA-buf mapping types
dma-buf: Add the SGT DMA mapping type
dma-buf: Add dma_buf_mapping_attach()
dma-buf: Route SGT related actions through attach->map_type
dma-buf: Allow single exporter drivers to avoid the match_mapping
function
drm: Check the SGT ops for drm_gem_map_dma_buf()
dma-buf: Convert all the simple exporters to use SGT mapping type
drm/vmwgfx: Use match_mapping instead of dummy calls
accel/habanalabs: Use the SGT mapping type
drm/xe/dma-buf: Use the SGT mapping type
drm/amdgpu: Use the SGT mapping type
vfio/pci: Change the DMA-buf exporter to use mapping_type
dma-buf: Update dma_buf_phys_vec_to_sgt() to use the SGT mapping type
iio: buffer: convert to use the SGT mapping type
functionfs: convert to use the SGT mapping type
dma-buf: Remove unused SGT stuff from the common structures
treewide: Rename dma_buf_map_attachment(_unlocked) to dma_buf_sgt_
treewide: Rename dma_buf_unmap_attachment(_unlocked) to dma_buf_sgt_*
treewide: Rename dma_buf_attach() to dma_buf_sgt_attach()
treewide: Rename dma_buf_dynamic_attach() to
dma_buf_sgt_dynamic_attach()
dma-buf: Add the Physical Address List DMA mapping type
vfio/pci: Add physical address list support to DMABUF
iommufd: Use the PAL mapping type instead of a vfio function
iommufd: Support DMA-bufs with multiple physical ranges
iommufd/selftest: Check multi-phys DMA-buf scenarios
dma-buf: Add kunit tests for mapping type
Documentation/gpu/todo.rst | 2 +-
drivers/accel/amdxdna/amdxdna_gem.c | 14 +-
drivers/accel/amdxdna/amdxdna_ubuf.c | 10 +-
drivers/accel/habanalabs/common/memory.c | 54 ++-
drivers/accel/ivpu/ivpu_gem.c | 10 +-
drivers/accel/ivpu/ivpu_gem_userptr.c | 11 +-
drivers/accel/qaic/qaic_data.c | 8 +-
drivers/dma-buf/Makefile | 1 +
drivers/dma-buf/dma-buf-mapping.c | 186 ++++++++-
drivers/dma-buf/dma-buf.c | 180 ++++++---
drivers/dma-buf/heaps/cma_heap.c | 12 +-
drivers/dma-buf/heaps/system_heap.c | 13 +-
drivers/dma-buf/st-dma-mapping.c | 373 ++++++++++++++++++
drivers/dma-buf/udmabuf.c | 8 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 98 +++--
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 6 +-
drivers/gpu/drm/armada/armada_gem.c | 33 +-
drivers/gpu/drm/drm_gem_shmem_helper.c | 2 +-
drivers/gpu/drm/drm_prime.c | 31 +-
drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c | 18 +-
drivers/gpu/drm/i915/gem/i915_gem_object.c | 2 +-
.../drm/i915/gem/selftests/i915_gem_dmabuf.c | 8 +-
.../gpu/drm/i915/gem/selftests/mock_dmabuf.c | 8 +-
drivers/gpu/drm/msm/msm_gem_prime.c | 7 +-
drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c | 11 +-
drivers/gpu/drm/tegra/gem.c | 33 +-
drivers/gpu/drm/virtio/virtgpu_prime.c | 23 +-
drivers/gpu/drm/vmwgfx/vmwgfx_prime.c | 32 +-
drivers/gpu/drm/xe/xe_bo.c | 18 +-
drivers/gpu/drm/xe/xe_dma_buf.c | 61 +--
drivers/iio/industrialio-buffer.c | 15 +-
drivers/infiniband/core/umem_dmabuf.c | 15 +-
drivers/iommu/iommufd/io_pagetable.h | 4 +-
drivers/iommu/iommufd/iommufd_private.h | 8 -
drivers/iommu/iommufd/iommufd_test.h | 7 +
drivers/iommu/iommufd/pages.c | 85 ++--
drivers/iommu/iommufd/selftest.c | 177 ++++++---
.../media/common/videobuf2/videobuf2-core.c | 2 +-
.../common/videobuf2/videobuf2-dma-contig.c | 26 +-
.../media/common/videobuf2/videobuf2-dma-sg.c | 21 +-
.../common/videobuf2/videobuf2-vmalloc.c | 13 +-
.../platform/nvidia/tegra-vde/dmabuf-cache.c | 9 +-
drivers/misc/fastrpc.c | 21 +-
drivers/tee/tee_heap.c | 13 +-
drivers/usb/gadget/function/f_fs.c | 11 +-
drivers/vfio/pci/vfio_pci_dmabuf.c | 79 ++--
drivers/xen/gntdev-dmabuf.c | 29 +-
include/linux/dma-buf-mapping.h | 297 ++++++++++++++
include/linux/dma-buf.h | 168 ++++----
io_uring/zcrx.c | 9 +-
net/core/devmem.c | 14 +-
samples/vfio-mdev/mbochs.c | 10 +-
sound/soc/fsl/fsl_asrc_m2m.c | 12 +-
tools/testing/selftests/iommu/iommufd.c | 43 ++
tools/testing/selftests/iommu/iommufd_utils.h | 17 +
55 files changed, 1764 insertions(+), 614 deletions(-)
create mode 100644 drivers/dma-buf/st-dma-mapping.c
base-commit: c63e5a50e1dd291cd95b04291b028fdcaba4c534
--
2.43.0
Hi Karl,
On Mon, Oct 19, 2026 at 4:14 PM Karl Mehltretter <kmehltretter(a)gmail.com> wrote:
>
> VIDIOC_PREPARE_BUF leaves a buffer DEQUEUED after calling buf_prepare()
> and the prepare() memory operation. VIDIOC_REMOVE_BUFS accepts that state
> but frees the buffer without calling the matching finish operations.
>
> With VIDEO_ADV_DEBUG, vivid reports:
>
> unbalanced counters for queue 000000009fa716f8, buffer 0:
> buf_prepare: 1 buf_finish: 0
> prepare: 1 finish: 0
>
> Finish prepared buffers before freeing them, as queue cancellation does.
>
> Fixes: a3293a85381e ("media: v4l2: Add REMOVE_BUFS ioctl")
> Assisted-by: LLM
> Signed-off-by: Karl Mehltretter <kmehltretter(a)gmail.com>
> ---
> drivers/media/common/videobuf2/videobuf2-core.c | 13 +++++++++++++
> 1 file changed, 13 insertions(+)
Thanks for the patch. Please take a look at my comments inline.
>
> diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c
> index b0a6084f17573..460eaf4e82f78 100644
> --- a/drivers/media/common/videobuf2/videobuf2-core.c
> +++ b/drivers/media/common/videobuf2/videobuf2-core.c
> @@ -1746,6 +1746,19 @@ int vb2_core_remove_bufs(struct vb2_queue *q, unsigned int start, unsigned int c
> goto unlock;
> }
> }
> +
> + /* A buffer can be prepared without being queued. Finish it first. */
> + for (i = start; i < start + count; i++) {
> + struct vb2_buffer *vb = vb2_get_buffer(q, i);
> +
> + if (!vb->prepared)
> + continue;
> +
> + __vb2_buf_mem_finish(vb);
> + call_void_vb_qop(vb, buf_finish, vb);
> + vb->prepared = 0;
> + }
> +
__vb2_queue_cancel() does much more than that, especially all the
media request handling. In addition, this open coded handling just
causes code duplication.
Would it make more sense to refactor the relevant part of the buffer
cancelation loop from __vb2_queue_cancel() into a helper function and
call it here instead?
Best,
Tomasz
> __vb2_queue_free(q, start, count);
> dprintk(q, 2, "%u buffers removed\n", count);
>
> --
> 2.47.3
>
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.co…
Signed-off-by: Albert Esteve <aesteve(a)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-63…
---
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,
--
Albert Esteve <aesteve(a)redhat.com>
On 10/21/26 11:08, Val Packett wrote:
> Introduce a new ioctl that allows userspace to register an eventfd to get
> notified when a dma-buf is released.
>
> The current use case comes from virtio-gpu device backends wishing to add
> support for guest-owned buffers with host handles (CREATE_GUEST_HANDLE):
>
> * guest creates a guest-only blob resource on the virtgpu
> * host creates a udmabuf from the iovecs sent by the guest
> * guest attaches the resource to a cross-domain socket send operation
> * guest immediately releases the resource (no longer needed by the guest)
> * host sends the udmabuf to the compositor, but needs to delay responding
> to the resource release request until the resource is *actually* free
> on the host side, i.e. the compositor no longer uses it
Interesting use case you have here.
It doesn't sound to crazy, e.g. it can't deadlock the kernel or anything like that which we often see with dma-fence.
> Signed-off-by: Val Packett <val(a)invisiblethingslab.com>
> ---
>
> More background on the use case with extra links:
> https://lore.kernel.org/virtio-comment/20260903021442.423274-1-val@invisibl…
>
> Funnily enough, gntdev-dmabuf (which is used on Xen hosts instead of
> udmabuf for this) offers "a way" to "poll" for these release events
> on its dmabufs (IOCTL_GNTDEV_DMABUF_EXP_WAIT_RELEASED), but it's unusable:
>
> * it's a blocking wait!!
> * release does not happen while you still have the fd open, so:
> * you can't just timeout and restart, you'd need the fd to restart;
> * and the only way to even close the fd is from a different thread,
> after some arbitrary timeout when hopefully the wait has started.
Oh that made my day :D
> The buffer lifecycle coordination we need this for applies to KVM as well
> and it generally doesn't make sense to have this as a provider-specific
> thing since it's not related to the provider in any way, it's just
> something we want from dmabufs in general.
I wouldn't put that on the DMA-buf file descriptor where basically anybody can mess with it. That is just an recipe for trouble.
The better approach seems to be putting it into the udmabuf_ioctl(), so that from the very beginning you add the eventfd which signals when the udmabuf is released.
If we need that for more implementations than just udmabuf, we can potentially add it to dma_buf_export_info so that exporters can provide the eventfd file descriptor directly on creation.
Regards,
Christian.
>
> Thanks,
> ~val
>
> ---
> drivers/dma-buf/dma-buf.c | 24 ++++++++++++++++++++++++
> include/linux/dma-buf.h | 3 +++
> include/uapi/linux/dma-buf.h | 1 +
> 3 files changed, 28 insertions(+)
>
> diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
> index 36cdc342627e..1321fee73656 100644
> --- a/drivers/dma-buf/dma-buf.c
> +++ b/drivers/dma-buf/dma-buf.c
> @@ -17,6 +17,7 @@
> #include <linux/dma-fence.h>
> #include <linux/dma-fence-unwrap.h>
> #include <linux/anon_inodes.h>
> +#include <linux/eventfd.h>
> #include <linux/export.h>
> #include <linux/debugfs.h>
> #include <linux/list.h>
> @@ -185,6 +186,11 @@ static void dma_buf_release(struct dentry *dentry)
> if (dmabuf->resv == (struct dma_resv *)&dmabuf[1])
> dma_resv_fini(dmabuf->resv);
>
> + if (dmabuf->release_eventfd) {
> + eventfd_signal(dmabuf->release_eventfd);
> + eventfd_ctx_put(dmabuf->release_eventfd);
> + }
> +
> WARN_ON(!list_empty(&dmabuf->attachments));
> module_put(dmabuf->owner);
> kfree(dmabuf->name);
> @@ -537,6 +543,21 @@ static long dma_buf_import_sync_file(struct dma_buf *dmabuf,
> }
> #endif
>
> +static long dma_buf_set_release_eventfd(struct dma_buf *dmabuf,
> + u32 fd)
> +{
> + struct eventfd_ctx *ev_fd_ctx = eventfd_ctx_fdget(fd);
> +
> + if (IS_ERR(ev_fd_ctx))
> + return PTR_ERR(ev_fd_ctx);
> +
> + if (dmabuf->release_eventfd)
> + eventfd_ctx_put(dmabuf->release_eventfd);
> +
> + dmabuf->release_eventfd = ev_fd_ctx;
> + return 0;
> +}
> +
> static long dma_buf_ioctl(struct file *file,
> unsigned int cmd, unsigned long arg)
> {
> @@ -587,6 +608,9 @@ static long dma_buf_ioctl(struct file *file,
> return dma_buf_import_sync_file(dmabuf, (const void __user *)arg);
> #endif
>
> + case DMA_BUF_IOCTL_SET_RELEASE_EVENTFD:
> + return dma_buf_set_release_eventfd(dmabuf, (u32)arg);
> +
> default:
> return -ENOTTY;
> }
> diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
> index d15b2b31d3c9..07b4a589a793 100644
> --- a/include/linux/dma-buf.h
> +++ b/include/linux/dma-buf.h
> @@ -429,6 +429,9 @@ struct dma_buf {
>
> __poll_t active;
> } cb_in, cb_out;
> +
> + /** @release_eventfd: for userspace release notification */
> + struct eventfd_ctx *release_eventfd;
> };
>
> /**
> diff --git a/include/uapi/linux/dma-buf.h b/include/uapi/linux/dma-buf.h
> index e827c9d20c5d..566dea778ad0 100644
> --- a/include/uapi/linux/dma-buf.h
> +++ b/include/uapi/linux/dma-buf.h
> @@ -179,5 +179,6 @@ struct dma_buf_import_sync_file {
> #define DMA_BUF_SET_NAME_B _IOW(DMA_BUF_BASE, 1, __u64)
> #define DMA_BUF_IOCTL_EXPORT_SYNC_FILE _IOWR(DMA_BUF_BASE, 2, struct dma_buf_export_sync_file)
> #define DMA_BUF_IOCTL_IMPORT_SYNC_FILE _IOW(DMA_BUF_BASE, 3, struct dma_buf_import_sync_file)
> +#define DMA_BUF_IOCTL_SET_RELEASE_EVENTFD _IOW(DMA_BUF_BASE, 4, __u32)
>
> #endif
On 15/10/2026 09:38, Jayant Shekhar wrote:
> The DCP firmware exposes display resources through capabilities rather than
> through host-visible display registers. The MSM DRM backend therefore needs
> to build its KMS objects from the firmware capabilities and device-tree
> display graph.
>
> Complete DCP KMS registration, including power and IOMMU integration,
> capability handling, display-graph parsing, and creation of DRM planes,
> CRTCs, encoders, bridges, and connectors.
>
> Signed-off-by: Jayant Shekhar <jayant.shekhar(a)oss.qualcomm.com>
> Assisted-by: LLM
Your tag is the last one.
Best regards,
Krzysztof
On 15/10/2026 09:38, Jayant Shekhar wrote:
> The DCP firmware exposes display resources through capabilities rather than
> through host-visible display registers. The MSM DRM backend therefore needs
> to build its KMS objects from the firmware capabilities and device-tree
> display graph.
...
> +
> + remote_np = of_graph_get_remote_port_parent(ep_np);
> + of_node_put(ep_np);
> + if (!remote_np)
> + continue;
> +
> + if (!of_device_is_available(remote_np)) {
> + of_node_put(remote_np);
> + continue;
> + }
> +
> + if (of_node_name_prefix(remote_np, "dsi")) {
Where did you document the ABI?
> + if (dsi_idx >= ARRAY_SIZE(dpu_kms->dsi_bridge)) {
> + dev_err(dev->dev, "too many DSI outputs\n");
> + ret = -E2BIG;
> + goto out;
> + }
Best regards,
Krzysztof