diff options
author | jhb <jhb@FreeBSD.org> | 2000-11-16 02:16:44 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2000-11-16 02:16:44 +0000 |
commit | c0bba69cbe7c4beee5213a4f1494387ee365db4c (patch) | |
tree | bc01d9302c1c47d1c7ec3254c6bfc60515318af1 /sys/kern/kern_synch.c | |
parent | 4b0f06d83c650d18d7bc905ae27eb7412fcfc038 (diff) | |
download | FreeBSD-src-c0bba69cbe7c4beee5213a4f1494387ee365db4c.zip FreeBSD-src-c0bba69cbe7c4beee5213a4f1494387ee365db4c.tar.gz |
Don't release and acquire Giant in mi_switch(). Instead, release and
acquire Giant as needed in functions that call mi_switch(). The releases
need to be done outside of the sched_lock to avoid potential deadlocks
from trying to acquire Giant while interrupts are disabled.
Submitted by: witness
Diffstat (limited to 'sys/kern/kern_synch.c')
-rw-r--r-- | sys/kern/kern_synch.c | 21 |
1 files changed, 5 insertions, 16 deletions
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index 07e1014..13b5707 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -420,6 +420,7 @@ msleep(ident, mtx, priority, wmesg, timo) if (p && KTRPOINT(p, KTR_CSW)) ktrcsw(p->p_tracep, 1, 0); #endif + DROP_GIANT_NOSWITCH(); WITNESS_SLEEP(0, mtx); mtx_enter(&sched_lock, MTX_SPIN); @@ -533,6 +534,7 @@ out: if (KTRPOINT(p, KTR_CSW)) ktrcsw(p->p_tracep, 0, 0); #endif + PICKUP_GIANT(); if (mtx != NULL) { mtx_enter(mtx, MTX_DEF); WITNESS_RESTORE(mtx, mtx); @@ -610,6 +612,7 @@ mawait(struct mtx *mtx, int priority, int timo) int s; WITNESS_SAVE_DECL(mtx); + DROP_GIANT_NOSWITCH(); WITNESS_SLEEP(0, mtx); mtx_enter(&sched_lock, MTX_SPIN); if (mtx != NULL) { @@ -724,6 +727,7 @@ resume: p->p_asleep.as_priority = 0; out: + PICKUP_GIANT(); if (mtx != NULL) { mtx_enter(mtx, MTX_DEF); WITNESS_RESTORE(mtx, mtx); @@ -881,9 +885,7 @@ mi_switch() struct timeval new_switchtime; register struct proc *p = curproc; /* XXX */ register struct rlimit *rlim; - int giantreleased; int x; - WITNESS_SAVE_DECL(Giant); /* * XXX this spl is almost unnecessary. It is partly to allow for @@ -904,14 +906,7 @@ mi_switch() */ x = splstatclock(); - CTR4(KTR_PROC, "mi_switch: old proc %p (pid %d, %s), schedlock %p", - p, p->p_pid, p->p_comm, (void *) sched_lock.mtx_lock); - mtx_enter(&sched_lock, MTX_SPIN | MTX_RLIKELY); - - if (mtx_owned(&Giant)) - WITNESS_SAVE(&Giant, Giant); - for (giantreleased = 0; mtx_owned(&Giant); giantreleased++) - mtx_exit(&Giant, MTX_DEF | MTX_NOSWITCH); + mtx_assert(&sched_lock, MA_OWNED); #ifdef SIMPLELOCK_DEBUG if (p->p_simple_locks) @@ -965,12 +960,6 @@ mi_switch() if (switchtime.tv_sec == 0) microuptime(&switchtime); switchticks = ticks; - mtx_exit(&sched_lock, MTX_SPIN); - while (giantreleased--) - mtx_enter(&Giant, MTX_DEF); - if (mtx_owned(&Giant)) - WITNESS_RESTORE(&Giant, Giant); - splx(x); } |