Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/kern kthread(9): Fix nested kthread_join.
details: https://anonhg.NetBSD.org/src/rev/cb2de9b218f8
branches: trunk
changeset: 377553:cb2de9b218f8
user: riastradh <riastradh%NetBSD.org@localhost>
date: Mon Jul 17 10:55:27 2023 +0000
description:
kthread(9): Fix nested kthread_join.
No reason for one kthread_join to interfere with another, or to cause
non-cyclic dependencies to get stuck.
Uses struct lwp::l_private for this purpose, which for user threads
stores the tls pointer. I don't think anything in kthread(9) uses
l_private -- generally kernel threads will use lwp specificdata. But
maybe this should use a new member instead, or a union member with an
existing pointer for the purpose.
diffstat:
sys/kern/kern_kthread.c | 28 ++++++++++++++--------------
1 files changed, 14 insertions(+), 14 deletions(-)
diffs (81 lines):
diff -r a875c7fd4139 -r cb2de9b218f8 sys/kern/kern_kthread.c
--- a/sys/kern/kern_kthread.c Mon Jul 17 10:12:54 2023 +0000
+++ b/sys/kern/kern_kthread.c Mon Jul 17 10:55:27 2023 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_kthread.c,v 1.47 2022/09/13 09:37:49 riastradh Exp $ */
+/* $NetBSD: kern_kthread.c,v 1.48 2023/07/17 10:55:27 riastradh Exp $ */
/*-
* Copyright (c) 1998, 1999, 2007, 2009, 2019 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_kthread.c,v 1.47 2022/09/13 09:37:49 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_kthread.c,v 1.48 2023/07/17 10:55:27 riastradh Exp $");
#include <sys/param.h>
#include <sys/cpu.h>
@@ -45,7 +45,6 @@
#include <uvm/uvm_extern.h>
-static lwp_t * kthread_jtarget;
static kmutex_t kthread_lock;
static kcondvar_t kthread_cv;
@@ -55,7 +54,6 @@ kthread_sysinit(void)
mutex_init(&kthread_lock, MUTEX_DEFAULT, IPL_NONE);
cv_init(&kthread_cv, "kthrwait");
- kthread_jtarget = NULL;
}
/*
@@ -172,11 +170,14 @@ kthread_exit(int ecode)
/* Barrier for joining. */
if (l->l_pflag & LP_MUSTJOIN) {
+ bool *exitedp;
+
mutex_enter(&kthread_lock);
- while (kthread_jtarget != l) {
+ while ((exitedp = l->l_private) == NULL) {
cv_wait(&kthread_cv, &kthread_lock);
}
- kthread_jtarget = NULL;
+ KASSERT(!*exitedp);
+ *exitedp = true;
cv_broadcast(&kthread_cv);
mutex_exit(&kthread_lock);
}
@@ -197,22 +198,21 @@ kthread_exit(int ecode)
int
kthread_join(lwp_t *l)
{
+ bool exited = false;
KASSERT((l->l_flag & LW_SYSTEM) != 0);
KASSERT((l->l_pflag & LP_MUSTJOIN) != 0);
/*
- * - Wait if some other thread has occupied the target.
- * - Specify our kthread as a target and notify it.
- * - Wait for the target kthread to notify us.
+ * - Ask the kthread to write to `exited'.
+ * - After this, touching l is forbidden -- it may be freed.
+ * - Wait until the kthread has written to `exited'.
*/
mutex_enter(&kthread_lock);
- while (kthread_jtarget) {
- cv_wait(&kthread_cv, &kthread_lock);
- }
- kthread_jtarget = l;
+ KASSERT(l->l_private == NULL);
+ l->l_private = &exited;
cv_broadcast(&kthread_cv);
- while (kthread_jtarget == l) {
+ while (!exited) {
cv_wait(&kthread_cv, &kthread_lock);
}
mutex_exit(&kthread_lock);
Home |
Main Index |
Thread Index |
Old Index