summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorVisa Hankala <visa@cvs.openbsd.org>2019-11-12 04:20:22 +0000
committerVisa Hankala <visa@cvs.openbsd.org>2019-11-12 04:20:22 +0000
commita1c8a678bd969ce29c33da8b9a96a8ed5a5aad08 (patch)
tree827d852335e2cc8ec364755a3cb96e803ef5ab9a /sys/kern
parente52fa1d76ddd7041b5ae31386d0b22b38e9f2514 (diff)
Check sleep timeout state only if the sleep has a timeout. Otherwise,
the timeout cancellation in sleep_finish_timeout() would acquire the kernel lock every time in the no-timeout case, as noticed by mpi@. This also reduces the contention of timeout_mutex. OK mpi@, feedback guenther@
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_synch.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index 1aa80d925e9..6b858a8c727 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_synch.c,v 1.153 2019/10/15 10:05:43 mpi Exp $ */
+/* $OpenBSD: kern_synch.c,v 1.154 2019/11/12 04:20:21 visa Exp $ */
/* $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */
/*
@@ -345,6 +345,7 @@ sleep_setup(struct sleep_state *sls, const volatile void *ident, int prio,
sls->sls_catch = 0;
sls->sls_do_sleep = 1;
sls->sls_sig = 1;
+ sls->sls_timeout = 0;
SCHED_LOCK(sls->sls_s);
@@ -387,8 +388,13 @@ sleep_finish(struct sleep_state *sls, int do_sleep)
void
sleep_setup_timeout(struct sleep_state *sls, int timo)
{
- if (timo)
- timeout_add(&curproc->p_sleep_to, timo);
+ struct proc *p = curproc;
+
+ if (timo) {
+ KASSERT((p->p_flag & P_TIMEOUT) == 0);
+ sls->sls_timeout = 1;
+ timeout_add(&p->p_sleep_to, timo);
+ }
}
int
@@ -396,13 +402,15 @@ sleep_finish_timeout(struct sleep_state *sls)
{
struct proc *p = curproc;
- if (p->p_flag & P_TIMEOUT) {
- atomic_clearbits_int(&p->p_flag, P_TIMEOUT);
- return (EWOULDBLOCK);
- } else {
- /* This must not sleep. */
- timeout_del_barrier(&p->p_sleep_to);
- KASSERT((p->p_flag & P_TIMEOUT) == 0);
+ if (sls->sls_timeout) {
+ if (p->p_flag & P_TIMEOUT) {
+ atomic_clearbits_int(&p->p_flag, P_TIMEOUT);
+ return (EWOULDBLOCK);
+ } else {
+ /* This must not sleep. */
+ timeout_del_barrier(&p->p_sleep_to);
+ KASSERT((p->p_flag & P_TIMEOUT) == 0);
+ }
}
return (0);