summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_mutex.c
diff options
context:
space:
mode:
authorattilio <attilio@FreeBSD.org>2010-01-23 15:54:21 +0000
committerattilio <attilio@FreeBSD.org>2010-01-23 15:54:21 +0000
commit9a7f4738f4b1cfdb4d140e79f2f45b83f0c37aa5 (patch)
tree8948b981ee7ffc54e90f7295617953bd509fcc3f /sys/kern/kern_mutex.c
parent22188bf2d03496348cf79fe3478e52c6b7655095 (diff)
downloadFreeBSD-src-9a7f4738f4b1cfdb4d140e79f2f45b83f0c37aa5.zip
FreeBSD-src-9a7f4738f4b1cfdb4d140e79f2f45b83f0c37aa5.tar.gz
- Fix a race in sched_switch() of sched_4bsd.
In the case of the thread being on a sleepqueue or a turnstile, the sched_lock was acquired (without the aid of the td_lock interface) and the td_lock was dropped. This was going to break locking rules on other threads willing to access to the thread (via the td_lock interface) and modify his flags (allowed as long as the container lock was different by the one used in sched_switch). In order to prevent this situation, while sched_lock is acquired there the td_lock gets blocked. [0] - Merge the ULE's internal function thread_block_switch() into the global thread_lock_block() and make the former semantic as the default for thread_lock_block(). This means that thread_lock_block() will not disable interrupts when called (and consequently thread_unlock_block() will not re-enabled them when called). This should be done manually when necessary. Note, however, that ULE's thread_unblock_switch() is not reaped because it does reflect a difference in semantic due in ULE (the td_lock may not be necessarilly still blocked_lock when calling this). While asymmetric, it does describe a remarkable difference in semantic that is good to keep in mind. [0] Reported by: Kohji Okuno <okuno dot kohji at jp dot panasonic dot com> Tested by: Giovanni Trematerra <giovanni dot trematerra at gmail dot com> MFC: 2 weeks
Diffstat (limited to 'sys/kern/kern_mutex.c')
-rw-r--r--sys/kern/kern_mutex.c2
1 files changed, 0 insertions, 2 deletions
diff --git a/sys/kern/kern_mutex.c b/sys/kern/kern_mutex.c
index 85ca646..f9c3377 100644
--- a/sys/kern/kern_mutex.c
+++ b/sys/kern/kern_mutex.c
@@ -616,7 +616,6 @@ thread_lock_block(struct thread *td)
{
struct mtx *lock;
- spinlock_enter();
THREAD_LOCK_ASSERT(td, MA_OWNED);
lock = td->td_lock;
td->td_lock = &blocked_lock;
@@ -631,7 +630,6 @@ thread_lock_unblock(struct thread *td, struct mtx *new)
mtx_assert(new, MA_OWNED);
MPASS(td->td_lock == &blocked_lock);
atomic_store_rel_ptr((volatile void *)&td->td_lock, (uintptr_t)new);
- spinlock_exit();
}
void
OpenPOWER on IntegriCloud