aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2022-05-03 19:48:50 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2022-06-13 19:30:02 +0000
commitd7a9e6e74067f70eeec74dcd64a9bcc851503a6e (patch)
tree83a154f0010878cea428bf982f38542c19808b98
parent02a2aacbe2c81be455811fa9d4200101f70a86d2 (diff)
downloadsrc-d7a9e6e74067f70eeec74dcd64a9bcc851503a6e.tar.gz
src-d7a9e6e74067f70eeec74dcd64a9bcc851503a6e.zip
thread_single: wait for P_STOPPED_SINGLE to pass
to avoid ALLPROC mode to try to race with any other single-threading mode. In collaboration with: pho Reviewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 2 weeks Differential revision: https://reviews.freebsd.org/D35310
-rw-r--r--sys/kern/kern_thread.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c
index 57d235c002f0..4dd8dbdfb5a7 100644
--- a/sys/kern/kern_thread.c
+++ b/sys/kern/kern_thread.c
@@ -1207,10 +1207,18 @@ thread_single(struct proc *p, int mode)
mtx_assert(&Giant, MA_NOTOWNED);
PROC_LOCK_ASSERT(p, MA_OWNED);
- if ((p->p_flag & P_HADTHREADS) == 0 && mode != SINGLE_ALLPROC)
+ /*
+ * Is someone already single threading?
+ * Or may be singlethreading is not needed at all.
+ */
+ if (mode == SINGLE_ALLPROC) {
+ while ((p->p_flag & P_STOPPED_SINGLE) != 0) {
+ if ((p->p_flag2 & P2_WEXIT) != 0)
+ return (1);
+ msleep(&p->p_flag, &p->p_mtx, PCATCH, "thrsgl", 0);
+ }
+ } else if ((p->p_flag & P_HADTHREADS) == 0)
return (0);
-
- /* Is someone already single threading? */
if (p->p_singlethread != NULL && p->p_singlethread != td)
return (1);
@@ -1669,6 +1677,7 @@ thread_single_end(struct proc *p, int mode)
PROC_SUNLOCK(p);
if (wakeup_swapper)
kick_proc0();
+ wakeup(&p->p_flag);
}
/*