aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Sébastien Pédron <dumbbell@FreeBSD.org>2025-05-26 17:36:49 +0000
committerJean-Sébastien Pédron <dumbbell@FreeBSD.org>2026-01-25 16:04:44 +0000
commit28d6ffe37cf928c5b13e0aa34c39c4414a0f09e4 (patch)
treed0d387abf1c3542d60a874bd04d064e5fd426ec5
parent5931649751847cc3ca54255bb767424dcb8a3e97 (diff)
eventfd: Add eventfd_signal()
The `eventfd_signal()` function is the equivalent to a write to an eventfd file descriptor: it bumps the internal counter and wakes up processes waiting for it. `eventfd_signal()` is meant to be used by kernel drivers. DRM drivers will call it through linuxkpi. Reviewed by: markj Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D50850
-rw-r--r--sys/kern/sys_eventfd.c25
-rw-r--r--sys/sys/eventfd.h1
2 files changed, 23 insertions, 3 deletions
diff --git a/sys/kern/sys_eventfd.c b/sys/kern/sys_eventfd.c
index 433bcb57b2b3..47f1fcc316ec 100644
--- a/sys/kern/sys_eventfd.c
+++ b/sys/kern/sys_eventfd.c
@@ -157,6 +157,27 @@ eventfd_put(struct eventfd *efd)
free(efd, M_EVENTFD);
}
+static void
+eventfd_wakeup(struct eventfd *efd)
+{
+ KNOTE_LOCKED(&efd->efd_sel.si_note, 0);
+ selwakeup(&efd->efd_sel);
+ wakeup(&efd->efd_count);
+}
+
+void
+eventfd_signal(struct eventfd *efd)
+{
+ mtx_lock(&efd->efd_lock);
+
+ if (efd->efd_count < UINT64_MAX)
+ efd->efd_count++;
+
+ eventfd_wakeup(efd);
+
+ mtx_unlock(&efd->efd_lock);
+}
+
static int
eventfd_close(struct file *fp, struct thread *td)
{
@@ -244,9 +265,7 @@ retry:
if (error == 0) {
MPASS(UINT64_MAX - efd->efd_count > count);
efd->efd_count += count;
- KNOTE_LOCKED(&efd->efd_sel.si_note, 0);
- selwakeup(&efd->efd_sel);
- wakeup(&efd->efd_count);
+ eventfd_wakeup(efd);
}
mtx_unlock(&efd->efd_lock);
diff --git a/sys/sys/eventfd.h b/sys/sys/eventfd.h
index 1f36dbecb92d..1b390feed48e 100644
--- a/sys/sys/eventfd.h
+++ b/sys/sys/eventfd.h
@@ -44,6 +44,7 @@ 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);
+void eventfd_signal(struct eventfd *efd);
#else