summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormpi <mpi@openbsd.org>2020-01-16 16:35:03 +0000
committermpi <mpi@openbsd.org>2020-01-16 16:35:03 +0000
commit9566af8920ce0c73af22f6155f3428b247ad2cc0 (patch)
tree1fbe95b2ac7601abd6418ad43a6a57c6a5924bd1
parentturns out there WAS something fishy in signal handling in the "generic" (diff)
downloadwireguard-openbsd-9566af8920ce0c73af22f6155f3428b247ad2cc0.tar.xz
wireguard-openbsd-9566af8920ce0c73af22f6155f3428b247ad2cc0.zip
Introduce wakeup_proc() a function to un-SSTOP/SSLEEP a thread.
This moves most of the SCHED_LOCK() related to protecting the sleepqueue and its states to kern/kern_sync.c Name suggestion from jsg@, ok kettenis@, visa@
-rw-r--r--sys/dev/pci/drm/drm_linux.c16
-rw-r--r--sys/kern/kern_sig.c4
-rw-r--r--sys/kern/kern_synch.c40
-rw-r--r--sys/kern/sys_generic.c12
-rw-r--r--sys/kern/vfs_sync.c10
-rw-r--r--sys/sys/proc.h3
6 files changed, 36 insertions, 49 deletions
diff --git a/sys/dev/pci/drm/drm_linux.c b/sys/dev/pci/drm/drm_linux.c
index ddb8be808e9..851d90d5af6 100644
--- a/sys/dev/pci/drm/drm_linux.c
+++ b/sys/dev/pci/drm/drm_linux.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: drm_linux.c,v 1.55 2020/01/05 13:46:02 visa Exp $ */
+/* $OpenBSD: drm_linux.c,v 1.56 2020/01/16 16:35:03 mpi Exp $ */
/*
* Copyright (c) 2013 Jonathan Gray <jsg@openbsd.org>
* Copyright (c) 2015, 2016 Mark Kettenis <kettenis@openbsd.org>
@@ -115,20 +115,8 @@ schedule_timeout(long timeout)
int
wake_up_process(struct proc *p)
{
- int s, r = 0;
-
- SCHED_LOCK(s);
atomic_cas_ptr(&sch_proc, p, NULL);
- if (p->p_wchan) {
- if (p->p_stat == SSLEEP) {
- setrunnable(p);
- r = 1;
- } else
- unsleep(p);
- }
- SCHED_UNLOCK(s);
-
- return r;
+ return wakeup_proc(p, NULL);
}
void
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index cabca171b50..172848428b7 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_sig.c,v 1.241 2020/01/14 08:52:18 mpi Exp $ */
+/* $OpenBSD: kern_sig.c,v 1.242 2020/01/16 16:35:03 mpi Exp $ */
/* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */
/*
@@ -1109,7 +1109,7 @@ ptsignal(struct proc *p, int signum, enum signal_type type)
* runnable and can look at the signal. But don't make
* the process runnable, leave it stopped.
*/
- if (p->p_wchan && p->p_flag & P_SINTR)
+ if (p->p_flag & P_SINTR)
unsleep(p);
goto out;
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index 7d3c86481f3..da5b4e9b34e 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_synch.c,v 1.157 2020/01/14 08:52:18 mpi Exp $ */
+/* $OpenBSD: kern_synch.c,v 1.158 2020/01/16 16:35:04 mpi Exp $ */
/* $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */
/*
@@ -469,8 +469,7 @@ sleep_setup_signal(struct sleep_state *sls)
*/
atomic_setbits_int(&p->p_flag, P_SINTR);
if (p->p_p->ps_single != NULL || (sls->sls_sig = CURSIG(p)) != 0) {
- if (p->p_wchan)
- unsleep(p);
+ unsleep(p);
p->p_stat = SONPROC;
sls->sls_do_sleep = 0;
} else if (p->p_wchan == 0) {
@@ -505,6 +504,25 @@ sleep_finish_signal(struct sleep_state *sls)
return (error);
}
+int
+wakeup_proc(struct proc *p, const volatile void *chan)
+{
+ int s, awakened = 0;
+
+ SCHED_LOCK(s);
+ if (p->p_wchan != NULL &&
+ ((chan == NULL) || (p->p_wchan == chan))) {
+ awakened = 1;
+ if (p->p_stat == SSLEEP)
+ setrunnable(p);
+ else
+ unsleep(p);
+ }
+ SCHED_UNLOCK(s);
+
+ return awakened;
+}
+
/*
* Implement timeout for tsleep.
* If process hasn't been awakened (wchan non-zero),
@@ -518,13 +536,8 @@ endtsleep(void *arg)
int s;
SCHED_LOCK(s);
- if (p->p_wchan) {
- if (p->p_stat == SSLEEP)
- setrunnable(p);
- else
- unsleep(p);
+ if (wakeup_proc(p, NULL))
atomic_setbits_int(&p->p_flag, P_TIMEOUT);
- }
SCHED_UNLOCK(s);
}
@@ -536,7 +549,7 @@ unsleep(struct proc *p)
{
SCHED_ASSERT_LOCKED();
- if (p->p_wchan) {
+ if (p->p_wchan != NULL) {
TAILQ_REMOVE(&slpque[LOOKUP(p->p_wchan)], p, p_runq);
p->p_wchan = NULL;
}
@@ -570,13 +583,8 @@ wakeup_n(const volatile void *ident, int n)
if (p->p_stat != SSLEEP && p->p_stat != SSTOP)
panic("wakeup: p_stat is %d", (int)p->p_stat);
#endif
- if (p->p_wchan == ident) {
+ if (wakeup_proc(p, ident))
--n;
- p->p_wchan = 0;
- TAILQ_REMOVE(qp, p, p_runq);
- if (p->p_stat == SSLEEP)
- setrunnable(p);
- }
}
SCHED_UNLOCK(s);
}
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
index b2870249c99..dc050095a33 100644
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sys_generic.c,v 1.127 2020/01/08 16:27:41 visa Exp $ */
+/* $OpenBSD: sys_generic.c,v 1.128 2020/01/16 16:35:04 mpi Exp $ */
/* $NetBSD: sys_generic.c,v 1.24 1996/03/29 00:25:32 cgd Exp $ */
/*
@@ -767,7 +767,6 @@ void
selwakeup(struct selinfo *sip)
{
struct proc *p;
- int s;
KNOTE(&sip->si_note, NOTE_SUBMIT);
if (sip->si_seltid == 0)
@@ -780,15 +779,10 @@ selwakeup(struct selinfo *sip)
p = tfind(sip->si_seltid);
sip->si_seltid = 0;
if (p != NULL) {
- SCHED_LOCK(s);
- if (p->p_wchan == (caddr_t)&selwait) {
- if (p->p_stat == SSLEEP)
- setrunnable(p);
- else
- unsleep(p);
+ if (wakeup_proc(p, &selwait)) {
+ /* nothing else to do */
} else if (p->p_flag & P_SELECT)
atomic_clearbits_int(&p->p_flag, P_SELECT);
- SCHED_UNLOCK(s);
}
}
diff --git a/sys/kern/vfs_sync.c b/sys/kern/vfs_sync.c
index 14fc49787dc..d871f111836 100644
--- a/sys/kern/vfs_sync.c
+++ b/sys/kern/vfs_sync.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_sync.c,v 1.61 2019/12/08 12:29:42 mpi Exp $ */
+/* $OpenBSD: vfs_sync.c,v 1.62 2020/01/16 16:35:04 mpi Exp $ */
/*
* Portions of this code are:
@@ -241,12 +241,8 @@ syncer_thread(void *arg)
int
speedup_syncer(void)
{
- int s;
-
- SCHED_LOCK(s);
- if (syncerproc && syncerproc->p_wchan == &lbolt)
- setrunnable(syncerproc);
- SCHED_UNLOCK(s);
+ if (syncerproc)
+ wakeup_proc(syncerproc, &lbolt);
if (rushjob < syncdelay / 2) {
rushjob += 1;
stat_rush_requests += 1;
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index bb39ab71bae..c463e736f8a 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: proc.h,v 1.284 2020/01/06 10:25:10 visa Exp $ */
+/* $OpenBSD: proc.h,v 1.285 2020/01/16 16:35:04 mpi Exp $ */
/* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */
/*-
@@ -564,6 +564,7 @@ void procinit(void);
void setpriority(struct proc *, uint32_t, uint8_t);
void setrunnable(struct proc *);
void endtsleep(void *);
+int wakeup_proc(struct proc *, const volatile void *);
void unsleep(struct proc *);
void reaper(void *);
void exit1(struct proc *, int, int, int);