git: 593164975184 - main - eventfd: Add refcounting
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 25 Jan 2026 16:16:42 UTC
The branch main has been updated by dumbbell:
URL: https://cgit.FreeBSD.org/src/commit/?id=5931649751847cc3ca54255bb767424dcb8a3e97
commit 5931649751847cc3ca54255bb767424dcb8a3e97
Author: Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
AuthorDate: 2025-05-26 17:18:24 +0000
Commit: Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
CommitDate: 2026-01-25 16:04:40 +0000
eventfd: Add refcounting
An eventfd file descriptor can be used by drivers such as DRM drivers
through linuxkpi. A driver can hold a reference to such a file
regardless of the fact it is used by userland or not.
This patch introduces a refcount in `struct eventfd`, plus the
`eventfd_get()` and `eventfd_put()` functions to acquire and release
references. These functions will be used by DRM drivers for instance.
This structure is internal to `sys/kern/sys_eventfd.c` and not used
anywhere else. Thus it is safe to add a field without breaking anything.
Reviewed by: markj
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D50849
---
sys/kern/sys_eventfd.c | 30 ++++++++++++++++++++++++++++--
sys/sys/eventfd.h | 4 ++++
2 files changed, 32 insertions(+), 2 deletions(-)
diff --git a/sys/kern/sys_eventfd.c b/sys/kern/sys_eventfd.c
index 04ed107c933d..433bcb57b2b3 100644
--- a/sys/kern/sys_eventfd.c
+++ b/sys/kern/sys_eventfd.c
@@ -40,6 +40,7 @@
#include <sys/mutex.h>
#include <sys/poll.h>
#include <sys/proc.h>
+#include <sys/refcount.h>
#include <sys/selinfo.h>
#include <sys/stat.h>
#include <sys/uio.h>
@@ -102,6 +103,7 @@ struct eventfd {
uint32_t efd_flags;
struct selinfo efd_sel;
struct mtx efd_lock;
+ unsigned int efd_refcount;
};
int
@@ -119,6 +121,7 @@ eventfd_create_file(struct thread *td, struct file *fp, uint32_t initval,
efd->efd_count = initval;
mtx_init(&efd->efd_lock, "eventfd", NULL, MTX_DEF);
knlist_init_mtx(&efd->efd_sel.si_note, &efd->efd_lock);
+ refcount_init(&efd->efd_refcount, 1);
fflags = FREAD | FWRITE;
if ((flags & EFD_NONBLOCK) != 0)
@@ -128,16 +131,39 @@ eventfd_create_file(struct thread *td, struct file *fp, uint32_t initval,
return (0);
}
-static int
-eventfd_close(struct file *fp, struct thread *td)
+struct eventfd *
+eventfd_get(struct file *fp)
{
struct eventfd *efd;
+ if (fp->f_data == NULL || fp->f_ops != &eventfdops)
+ return (NULL);
+
efd = fp->f_data;
+ refcount_acquire(&efd->efd_refcount);
+
+ return (efd);
+}
+
+void
+eventfd_put(struct eventfd *efd)
+{
+ if (!refcount_release(&efd->efd_refcount))
+ return;
+
seldrain(&efd->efd_sel);
knlist_destroy(&efd->efd_sel.si_note);
mtx_destroy(&efd->efd_lock);
free(efd, M_EVENTFD);
+}
+
+static int
+eventfd_close(struct file *fp, struct thread *td)
+{
+ struct eventfd *efd;
+
+ efd = fp->f_data;
+ eventfd_put(efd);
return (0);
}
diff --git a/sys/sys/eventfd.h b/sys/sys/eventfd.h
index 0f64483753e5..1f36dbecb92d 100644
--- a/sys/sys/eventfd.h
+++ b/sys/sys/eventfd.h
@@ -38,8 +38,12 @@ typedef uint64_t eventfd_t;
#ifdef _KERNEL
+struct eventfd;
+
int eventfd_create_file(struct thread *td, struct file *fp, uint32_t initval,
int flags);
+struct eventfd *eventfd_get(struct file *fp);
+void eventfd_put(struct eventfd *efd);
#else