Module Name: src
Committed By: thorpej
Date: Wed Nov 24 16:35:33 UTC 2021
Modified Files:
src/sys/kern: sys_eventfd.c sys_timerfd.c
Log Message:
Fix "restart" semantics -- restart is terminal, so don't clear the
condition when previous waiters have drained. ("restart" is a bad
name for that this function does, fwiw.)
This should address a kernel assertion failure reported by Chavdar Ivanov
on current-users.
To generate a diff of this commit:
cvs rdiff -u -r1.7 -r1.8 src/sys/kern/sys_eventfd.c
cvs rdiff -u -r1.6 -r1.7 src/sys/kern/sys_timerfd.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/kern/sys_eventfd.c
diff -u src/sys/kern/sys_eventfd.c:1.7 src/sys/kern/sys_eventfd.c:1.8
--- src/sys/kern/sys_eventfd.c:1.7 Mon Sep 27 00:40:49 2021
+++ src/sys/kern/sys_eventfd.c Wed Nov 24 16:35:33 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: sys_eventfd.c,v 1.7 2021/09/27 00:40:49 thorpej Exp $ */
+/* $NetBSD: sys_eventfd.c,v 1.8 2021/11/24 16:35:33 thorpej Exp $ */
/*-
* Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_eventfd.c,v 1.7 2021/09/27 00:40:49 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_eventfd.c,v 1.8 2021/11/24 16:35:33 thorpej Exp $");
/*
* eventfd
@@ -64,7 +64,6 @@ struct eventfd {
kmutex_t efd_lock;
kcondvar_t efd_read_wait;
kcondvar_t efd_write_wait;
- kcondvar_t efd_restart_wait;
struct selinfo efd_read_sel;
struct selinfo efd_write_sel;
eventfd_t efd_val;
@@ -97,7 +96,6 @@ eventfd_create(unsigned int const val, i
mutex_init(&efd->efd_lock, MUTEX_DEFAULT, IPL_NONE);
cv_init(&efd->efd_read_wait, "efdread");
cv_init(&efd->efd_write_wait, "efdwrite");
- cv_init(&efd->efd_restart_wait, "efdrstrt");
selinit(&efd->efd_read_sel);
selinit(&efd->efd_write_sel);
efd->efd_val = val;
@@ -119,13 +117,11 @@ eventfd_destroy(struct eventfd * const e
{
KASSERT(efd->efd_nwaiters == 0);
- KASSERT(efd->efd_restarting == false);
KASSERT(efd->efd_has_read_waiters == false);
KASSERT(efd->efd_has_write_waiters == false);
cv_destroy(&efd->efd_read_wait);
cv_destroy(&efd->efd_write_wait);
- cv_destroy(&efd->efd_restart_wait);
seldestroy(&efd->efd_read_sel);
seldestroy(&efd->efd_write_sel);
@@ -152,11 +148,10 @@ eventfd_wait(struct eventfd * const efd,
}
/*
- * We're going to block. If there is a restart in-progress,
- * wait for that to complete first.
+ * We're going to block. Check if we need to return ERESTART.
*/
- while (efd->efd_restarting) {
- cv_wait(&efd->efd_restart_wait, &efd->efd_lock);
+ if (efd->efd_restarting) {
+ return ERESTART;
}
if (is_write) {
@@ -175,18 +170,12 @@ eventfd_wait(struct eventfd * const efd,
/*
* If a restart was triggered while we were asleep, we need
- * to return ERESTART if no other error was returned. If we
- * are the last waiter coming out of the restart drain, clear
- * the condition.
+ * to return ERESTART if no other error was returned.
*/
if (efd->efd_restarting) {
if (error == 0) {
error = ERESTART;
}
- if (efd->efd_nwaiters == 0) {
- efd->efd_restarting = false;
- cv_broadcast(&efd->efd_restart_wait);
- }
}
return error;
Index: src/sys/kern/sys_timerfd.c
diff -u src/sys/kern/sys_timerfd.c:1.6 src/sys/kern/sys_timerfd.c:1.7
--- src/sys/kern/sys_timerfd.c:1.6 Mon Sep 27 00:40:49 2021
+++ src/sys/kern/sys_timerfd.c Wed Nov 24 16:35:33 2021
@@ -1,4 +1,4 @@
-/* $NetBSD: sys_timerfd.c,v 1.6 2021/09/27 00:40:49 thorpej Exp $ */
+/* $NetBSD: sys_timerfd.c,v 1.7 2021/11/24 16:35:33 thorpej Exp $ */
/*-
* Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_timerfd.c,v 1.6 2021/09/27 00:40:49 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_timerfd.c,v 1.7 2021/11/24 16:35:33 thorpej Exp $");
/*
* timerfd
@@ -71,7 +71,6 @@ __KERNEL_RCSID(0, "$NetBSD: sys_timerfd.
struct timerfd {
struct itimer tfd_itimer;
kcondvar_t tfd_read_wait;
- kcondvar_t tfd_restart_wait;
struct selinfo tfd_read_sel;
int64_t tfd_nwaiters;
bool tfd_cancel_on_set;
@@ -162,7 +161,6 @@ timerfd_create(clockid_t const clock_id,
KASSERT(clock_id == CLOCK_REALTIME || clock_id == CLOCK_MONOTONIC);
cv_init(&tfd->tfd_read_wait, "tfdread");
- cv_init(&tfd->tfd_restart_wait, "tfdrstrt");
selinit(&tfd->tfd_read_sel);
getnanotime(&tfd->tfd_btime);
@@ -188,14 +186,12 @@ timerfd_destroy(struct timerfd * const t
{
KASSERT(tfd->tfd_nwaiters == 0);
- KASSERT(tfd->tfd_restarting == false);
itimer_lock();
itimer_poison(&tfd->tfd_itimer);
itimer_fini(&tfd->tfd_itimer); /* drops itimer lock */
cv_destroy(&tfd->tfd_read_wait);
- cv_destroy(&tfd->tfd_restart_wait);
seldestroy(&tfd->tfd_read_sel);
@@ -219,11 +215,10 @@ timerfd_wait(struct timerfd * const tfd,
}
/*
- * We're going to block. If there is a restart in-progress,
- * wait for that to complete first.
+ * We're going to block. Check if we need to return ERESTART.
*/
- while (tfd->tfd_restarting) {
- cv_wait(&tfd->tfd_restart_wait, &itimer_mutex);
+ if (tfd->tfd_restarting) {
+ return ERESTART;
}
tfd->tfd_nwaiters++;
@@ -234,18 +229,12 @@ timerfd_wait(struct timerfd * const tfd,
/*
* If a restart was triggered while we were asleep, we need
- * to return ERESTART if no other error was returned. If we
- * are the last waiter coming out of the restart drain, clear
- * the condition.
+ * to return ERESTART if no other error was returned.
*/
if (tfd->tfd_restarting) {
if (error == 0) {
error = ERESTART;
}
- if (tfd->tfd_nwaiters == 0) {
- tfd->tfd_restarting = false;
- cv_broadcast(&tfd->tfd_restart_wait);
- }
}
return error;