summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2000-11-16 01:07:19 +0000
committerjhb <jhb@FreeBSD.org>2000-11-16 01:07:19 +0000
commit8b193931b51791d7266c8d80191705ce96bbfb3e (patch)
tree301358a6131bef5f0b81d9475754b214eb88df93 /sys
parent0ee48b4aca419a4b02c82a50299bcd6e23a3a25b (diff)
downloadFreeBSD-src-8b193931b51791d7266c8d80191705ce96bbfb3e.zip
FreeBSD-src-8b193931b51791d7266c8d80191705ce96bbfb3e.tar.gz
CURSIG() calls functions that acquire sleep mutexes, so it is not a good
idea to be holding the sched_lock while we are calling it. As such, release sched_lock before calling CURSIG() in msleep() and mawait() and reacquire it after CURSIG() returns. Submitted by: witness
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_synch.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index 3f04391..a6eaa18 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -477,12 +477,15 @@ msleep(ident, mtx, priority, wmesg, timo)
"msleep caught: proc %p (pid %d, %s), schedlock %p",
p, p->p_pid, p->p_comm, (void *) sched_lock.mtx_lock);
p->p_flag |= P_SINTR;
+ mtx_exit(&sched_lock, MTX_SPIN);
if ((sig = CURSIG(p))) {
+ mtx_enter(&sched_lock, MTX_SPIN);
if (p->p_wchan)
unsleep(p);
p->p_stat = SRUN;
goto resume;
}
+ mtx_enter(&sched_lock, MTX_SPIN);
if (p->p_wchan == 0) {
catch = 0;
goto resume;
@@ -507,10 +510,13 @@ resume:
ktrcsw(p->p_tracep, 0, 0);
#endif
rval = EWOULDBLOCK;
+ mtx_exit(&sched_lock, MTX_SPIN);
goto out;
}
} else if (timo)
untimeout(endtsleep, (void *)p, thandle);
+ mtx_exit(&sched_lock, MTX_SPIN);
+
if (catch && (sig != 0 || (sig = CURSIG(p)))) {
#ifdef KTRACE
if (KTRPOINT(p, KTR_CSW))
@@ -523,7 +529,6 @@ resume:
goto out;
}
out:
- mtx_exit(&sched_lock, MTX_SPIN);
#ifdef KTRACE
if (KTRPOINT(p, KTR_CSW))
ktrcsw(p->p_tracep, 0, 0);
@@ -643,12 +648,15 @@ mawait(struct mtx *mtx, int priority, int timo)
if (catch) {
p->p_flag |= P_SINTR;
+ mtx_exit(&sched_lock, MTX_SPIN);
if ((sig = CURSIG(p))) {
+ mtx_enter(&sched_lock, MTX_SPIN);
if (p->p_wchan)
unsleep(p);
p->p_stat = SRUN;
goto resume;
}
+ mtx_enter(&sched_lock, MTX_SPIN);
if (p->p_wchan == NULL) {
catch = 0;
goto resume;
@@ -674,6 +682,8 @@ resume:
}
} else if (timo)
untimeout(endtsleep, (void *)p, thandle);
+ mtx_exit(&sched_lock, MTX_SPIN);
+
if (catch && (sig != 0 || (sig = CURSIG(p)))) {
#ifdef KTRACE
if (KTRPOINT(p, KTR_CSW))
@@ -700,6 +710,7 @@ resume:
p->p_stats->p_ru.ru_nvcsw++;
mi_switch();
}
+ mtx_exit(&sched_lock, MTX_SPIN);
splx(s);
}
@@ -712,8 +723,6 @@ resume:
p->p_asleep.as_priority = 0;
out:
- mtx_exit(&sched_lock, MTX_SPIN);
-
if (mtx != NULL) {
mtx_enter(mtx, MTX_DEF);
WITNESS_RESTORE(mtx, mtx);
OpenPOWER on IntegriCloud