mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] dma-buf: Add DMA_BUF_IOCTL_SET_RELEASE_EVENTFD
@ 2026-10-21  9:08 Val Packett
  2026-10-21 13:43 ` Christian König
  0 siblings, 1 reply; 3+ messages 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] 3+ messages in thread

* Re: [PATCH] dma-buf: Add DMA_BUF_IOCTL_SET_RELEASE_EVENTFD
  2026-10-21  9:08 [PATCH] dma-buf: Add DMA_BUF_IOCTL_SET_RELEASE_EVENTFD Val Packett
@ 2026-10-21 13:43 ` Christian König
  2026-10-21 20:16   ` Val Packett
  0 siblings, 1 reply; 3+ messages in thread
From: Christian König @ 2026-10-21 13:43 UTC (permalink / raw)
  To: Val Packett, Sumit Semwal, Philipp Stanner
  Cc: linux-media, dri-devel, linaro-mm-sig, linux-kernel

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@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.

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


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] dma-buf: Add DMA_BUF_IOCTL_SET_RELEASE_EVENTFD
  2026-10-21 13:43 ` Christian König
@ 2026-10-21 20:16   ` Val Packett
  0 siblings, 0 replies; 3+ messages in thread
From: Val Packett @ 2026-10-21 20:16 UTC (permalink / raw)
  To: Christian König, Sumit Semwal, Philipp Stanner
  Cc: linux-media, dri-devel, linaro-mm-sig, linux-kernel


On 10/21/26 10:43 AM, Christian König wrote:
> [..]
>> 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.

Well, we already need it with both udmabuf and gntdev-dmabuf..

Involving the exporter sounds really annoying when it's not something 
exporter dependent really.. What if the policy is just "only one eventfd 
ever" i.e. the first call of the ioctl succeeds but later calls on the 
same dmabuf return an error? That should remove the concern about one 
user messing with another's events (and avoid the concurrent replacement 
issue sashiko-bot warned about)..

Thanks,
~val


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-10-21 20:17 UTC | newest]

Thread overview: 3+ messages (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
2026-10-21 13:43 ` Christian König
2026-10-21 20:16   ` 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®