Module Name:    src
Committed By:   ad
Date:           Fri Oct 13 18:48:56 UTC 2023

Modified Files:
        src/sys/kern: kern_condvar.c kern_sleepq.c
        src/sys/rump/librump/rumpkern: locks.c locks_up.c
        src/sys/sys: condvar.h lwp.h

Log Message:
Add cv_fdrestart() (better name suggestions welcome):

Like cv_broadcast(), but make any LWPs that share the same file descriptor
table as the caller return ERESTART when resuming.  Used to dislodge LWPs
waiting for I/O that prevent a file descriptor from being closed, without
upsetting access to the file (not descriptor) made from another direction.


To generate a diff of this commit:
cvs rdiff -u -r1.59 -r1.60 src/sys/kern/kern_condvar.c
cvs rdiff -u -r1.83 -r1.84 src/sys/kern/kern_sleepq.c
cvs rdiff -u -r1.86 -r1.87 src/sys/rump/librump/rumpkern/locks.c
cvs rdiff -u -r1.12 -r1.13 src/sys/rump/librump/rumpkern/locks_up.c
cvs rdiff -u -r1.17 -r1.18 src/sys/sys/condvar.h
cvs rdiff -u -r1.227 -r1.228 src/sys/sys/lwp.h

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/kern_condvar.c
diff -u src/sys/kern/kern_condvar.c:1.59 src/sys/kern/kern_condvar.c:1.60
--- src/sys/kern/kern_condvar.c:1.59	Thu Oct 12 23:51:05 2023
+++ src/sys/kern/kern_condvar.c	Fri Oct 13 18:48:56 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_condvar.c,v 1.59 2023/10/12 23:51:05 ad Exp $	*/
+/*	$NetBSD: kern_condvar.c,v 1.60 2023/10/13 18:48:56 ad Exp $	*/
 
 /*-
  * Copyright (c) 2006, 2007, 2008, 2019, 2020, 2023
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_condvar.c,v 1.59 2023/10/12 23:51:05 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_condvar.c,v 1.60 2023/10/13 18:48:56 ad Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -543,6 +543,43 @@ cv_wakeup_all(kcondvar_t *cv)
 }
 
 /*
+ * cv_fdrestart:
+ *
+ *	Like cv_broadcast(), but make any LWPs that share the same file
+ *	descriptor table as the caller return ERESTART when resuming.  Used
+ *	to dislodge LWPs waiting for I/O that prevent a file descriptor from
+ *	being closed, without upsetting access to the file (not descriptor)
+ *	made from another direction.  Rarely used thus no fast path
+ *	provided.
+ */
+void
+cv_fdrestart(kcondvar_t *cv)
+{
+	sleepq_t *sq;
+	kmutex_t *mp;
+	lwp_t *l;
+
+	KASSERT(cv_is_valid(cv));
+
+	if (LIST_EMPTY(CV_SLEEPQ(cv)))
+		return;
+
+	mp = sleepq_hashlock(cv);
+	sq = CV_SLEEPQ(cv);
+	while ((l = LIST_FIRST(sq)) != NULL) {
+		KASSERT(l->l_sleepq == sq);
+		KASSERT(l->l_mutex == mp);
+		KASSERT(l->l_wchan == cv);
+		/* l_fd stable at this point so no special locking needed. */
+		if (l->l_fd == curlwp->l_fd) {
+			l->l_flag |= LW_RESTART;
+			sleepq_remove(sq, l, false);
+		}
+	}
+	mutex_spin_exit(mp);
+}
+
+/*
  * cv_has_waiters:
  *
  *	For diagnostic assertions: return non-zero if a condition

Index: src/sys/kern/kern_sleepq.c
diff -u src/sys/kern/kern_sleepq.c:1.83 src/sys/kern/kern_sleepq.c:1.84
--- src/sys/kern/kern_sleepq.c:1.83	Sun Oct  8 13:37:26 2023
+++ src/sys/kern/kern_sleepq.c	Fri Oct 13 18:48:56 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_sleepq.c,v 1.83 2023/10/08 13:37:26 ad Exp $	*/
+/*	$NetBSD: kern_sleepq.c,v 1.84 2023/10/13 18:48:56 ad Exp $	*/
 
 /*-
  * Copyright (c) 2006, 2007, 2008, 2009, 2019, 2020, 2023
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_sleepq.c,v 1.83 2023/10/08 13:37:26 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_sleepq.c,v 1.84 2023/10/13 18:48:56 ad Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -341,7 +341,7 @@ sleepq_uncatch(lwp_t *l)
 int
 sleepq_block(int timo, bool catch_p, syncobj_t *syncobj, int nlocks)
 {
-	const int mask = LW_CANCELLED|LW_WEXIT|LW_WCORE|LW_PENDSIG;
+	const int mask = LW_CANCELLED|LW_WEXIT|LW_WCORE|LW_PENDSIG|LW_RESTART;
 	int error = 0, sig, flag;
 	struct proc *p;
 	lwp_t *l = curlwp;
@@ -358,16 +358,20 @@ sleepq_block(int timo, bool catch_p, syn
 	 * while we are sleeping.  It is independent from LW_SINTR because
 	 * we don't want to leave LW_SINTR set when the LWP is not asleep.
 	 */
+	flag = l->l_flag;
 	if (catch_p) {
-		if ((l->l_flag & (LW_CANCELLED|LW_WEXIT|LW_WCORE)) != 0) {
-			l->l_flag &= ~LW_CANCELLED;
-			error = EINTR;
-			early = true;
-		} else if ((l->l_flag & LW_PENDSIG) != 0 && sigispending(l, 0))
-			early = true;
-		l->l_flag |= LW_CATCHINTR;
+		if ((flag & mask) != 0) {
+			if ((flag & (LW_CANCELLED|LW_WEXIT|LW_WCORE)) != 0) {
+				l->l_flag = flag & ~LW_CANCELLED;
+				error = EINTR;
+				early = true;
+			} else if ((flag & LW_PENDSIG) != 0 &&
+			    sigispending(l, 0))
+				early = true;
+		}
+		l->l_flag = (flag | LW_CATCHINTR) & ~LW_RESTART;
 	} else
-		l->l_flag &= ~LW_CATCHINTR;
+		l->l_flag = flag & ~(LW_CATCHINTR | LW_RESTART);
 
 	if (early) {
 		/* lwp_unsleep() will release the lock */
@@ -435,7 +439,8 @@ sleepq_block(int timo, bool catch_p, syn
 			    (sig = issignal(l)) != 0)
 				error = sleepq_sigtoerror(l, sig);
 			mutex_exit(p->p_lock);
-		}
+		} else if ((flag & LW_RESTART) != 0)
+			error = ERESTART;
 	}
 
 	ktrcsw(0, 0, syncobj);

Index: src/sys/rump/librump/rumpkern/locks.c
diff -u src/sys/rump/librump/rumpkern/locks.c:1.86 src/sys/rump/librump/rumpkern/locks.c:1.87
--- src/sys/rump/librump/rumpkern/locks.c:1.86	Sun Jul 16 23:12:17 2023
+++ src/sys/rump/librump/rumpkern/locks.c	Fri Oct 13 18:48:56 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: locks.c,v 1.86 2023/07/16 23:12:17 riastradh Exp $	*/
+/*	$NetBSD: locks.c,v 1.87 2023/10/13 18:48:56 ad Exp $	*/
 
 /*
  * Copyright (c) 2007-2011 Antti Kantee.  All Rights Reserved.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: locks.c,v 1.86 2023/07/16 23:12:17 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: locks.c,v 1.87 2023/10/13 18:48:56 ad Exp $");
 
 #include <sys/param.h>
 #include <sys/kmem.h>
@@ -486,6 +486,13 @@ cv_broadcast(kcondvar_t *cv)
 	rumpuser_cv_broadcast(RUMPCV(cv));
 }
 
+void
+cv_fdrestart(kcondvar_t *cv)
+{
+
+	rumpuser_cv_broadcast(RUMPCV(cv));
+}
+
 bool
 cv_has_waiters(kcondvar_t *cv)
 {

Index: src/sys/rump/librump/rumpkern/locks_up.c
diff -u src/sys/rump/librump/rumpkern/locks_up.c:1.12 src/sys/rump/librump/rumpkern/locks_up.c:1.13
--- src/sys/rump/librump/rumpkern/locks_up.c:1.12	Wed Apr 12 06:35:40 2023
+++ src/sys/rump/librump/rumpkern/locks_up.c	Fri Oct 13 18:48:56 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: locks_up.c,v 1.12 2023/04/12 06:35:40 riastradh Exp $	*/
+/*	$NetBSD: locks_up.c,v 1.13 2023/10/13 18:48:56 ad Exp $	*/
 
 /*
  * Copyright (c) 2010 Antti Kantee.  All Rights Reserved.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: locks_up.c,v 1.12 2023/04/12 06:35:40 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: locks_up.c,v 1.13 2023/10/13 18:48:56 ad Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -421,6 +421,14 @@ cv_broadcast(kcondvar_t *cv)
 	rumpuser_cv_broadcast(RUMPCV(cv));
 }
 
+void
+cv_fdrestart(kcondvar_t *cv)
+{
+
+	/* CPU == interlock */
+	rumpuser_cv_broadcast(RUMPCV(cv));
+}
+
 bool
 cv_has_waiters(kcondvar_t *cv)
 {

Index: src/sys/sys/condvar.h
diff -u src/sys/sys/condvar.h:1.17 src/sys/sys/condvar.h:1.18
--- src/sys/sys/condvar.h:1.17	Mon May 11 03:59:33 2020
+++ src/sys/sys/condvar.h	Fri Oct 13 18:48:56 2023
@@ -1,7 +1,7 @@
-/*	$NetBSD: condvar.h,v 1.17 2020/05/11 03:59:33 riastradh Exp $	*/
+/*	$NetBSD: condvar.h,v 1.18 2023/10/13 18:48:56 ad Exp $	*/
 
 /*-
- * Copyright (c) 2006, 2007, 2008, 2020 The NetBSD Foundation, Inc.
+ * Copyright (c) 2006, 2007, 2008, 2020, 2023 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -56,6 +56,7 @@ int	cv_timedwaitbt_sig(kcondvar_t *, str
 
 void	cv_signal(kcondvar_t *);
 void	cv_broadcast(kcondvar_t *);
+void	cv_fdrestart(kcondvar_t *);
 
 bool	cv_has_waiters(kcondvar_t *);
 bool	cv_is_valid(kcondvar_t *);

Index: src/sys/sys/lwp.h
diff -u src/sys/sys/lwp.h:1.227 src/sys/sys/lwp.h:1.228
--- src/sys/sys/lwp.h:1.227	Thu Oct  5 19:41:07 2023
+++ src/sys/sys/lwp.h	Fri Oct 13 18:48:56 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: lwp.h,v 1.227 2023/10/05 19:41:07 ad Exp $	*/
+/*	$NetBSD: lwp.h,v 1.228 2023/10/13 18:48:56 ad Exp $	*/
 
 /*
  * Copyright (c) 2001, 2006, 2007, 2008, 2009, 2010, 2019, 2020, 2023
@@ -266,6 +266,7 @@ extern int		maxlwp __read_mostly;	/* max
 #define	LW_CACHECRED	0x04000000 /* Cache new process credential */
 #define	LW_WREBOOT	0x08000000 /* System is rebooting, please suspend */
 #define	LW_UNPARKED	0x10000000 /* Unpark op pending */
+#define	LW_RESTART	0x20000000 /* Return ERESTART after waking */
 #define	LW_RUMP_CLEAR	0x40000000 /* Clear curlwp in RUMP scheduler */
 #define	LW_RUMP_QEXIT	0x80000000 /* LWP should exit ASAP */
 

Reply via email to