* [PATCH] dma-buf: Add DMA_BUF_IOCTL_SET_RELEASE_EVENTFD
@ 2026-10-21 9:08 Val Packett
0 siblings, 0 replies; only message in thread
From: Val Packett @ 2026-10-21 9:08 UTC (permalink / raw)
To: Sumit Semwal, Christian König, Philipp Stanner
Cc: Val Packett, linux-media, dri-devel, linaro-mm-sig, linux-kernel
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
Signed-off-by: Val Packett <val@invisiblethingslab.com>
---
More background on the use case with extra links:
https://lore.kernel.org/virtio-comment/20260903021442.423274-1-val@invisiblethingslab.com/
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.
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.
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
--
2.55.0
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-10-21 9:36 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-21 9:08 [PATCH] dma-buf: Add DMA_BUF_IOCTL_SET_RELEASE_EVENTFD Val Packett
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®