diff options
| author | Jean-Sébastien Pédron <dumbbell@FreeBSD.org> | 2025-05-26 17:36:49 +0000 |
|---|---|---|
| committer | Jean-Sébastien Pédron <dumbbell@FreeBSD.org> | 2026-01-25 16:04:44 +0000 |
| commit | 28d6ffe37cf928c5b13e0aa34c39c4414a0f09e4 (patch) | |
| tree | d0d387abf1c3542d60a874bd04d064e5fd426ec5 | |
| parent | 5931649751847cc3ca54255bb767424dcb8a3e97 (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.c | 25 | ||||
| -rw-r--r-- | sys/sys/eventfd.h | 1 |
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 |
