summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbadger <badger@FreeBSD.org>2016-08-30 13:39:42 +0000
committerbadger <badger@FreeBSD.org>2016-08-30 13:39:42 +0000
commitd8feb13e02c7681586150351a1684bbea3f54e5c (patch)
treed4465a7c4c3874d05951fedfd70e276a55c359c0
parentde43eec3e10416a7e9f3a7565f70e1ba2d265384 (diff)
downloadFreeBSD-src-d8feb13e02c7681586150351a1684bbea3f54e5c.zip
FreeBSD-src-d8feb13e02c7681586150351a1684bbea3f54e5c.tar.gz
MFC r304184:
sem_post(): wake up the sleeper only after adjusting has_waiters If the caller of sem_post() wakes up a thread sleeping via sem_wait() before it clears the has_waiters flag, the caller of sem_wait() has no way of knowing when it is safe to destroy the semaphore and reuse the memory. This is because the caller of sem_post() may be interrupted between the wake step and the clearing of has_waiters. It will then write into the has_waiters flag in userspace after being preempted for some unknown amount of time. Approved by: vangyzen (mentor) Sponsored by: Dell Inc.
-rw-r--r--sys/kern/kern_umtx.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c
index 595e869..dd205d0 100644
--- a/sys/kern/kern_umtx.c
+++ b/sys/kern/kern_umtx.c
@@ -3344,7 +3344,6 @@ do_sem_wake(struct thread *td, struct _usem *sem)
umtxq_busy(&key);
cnt = umtxq_count(&key);
if (cnt > 0) {
- umtxq_signal(&key, 1);
/*
* Check if count is greater than 0, this means the memory is
* still being referenced by user code, so we can safely
@@ -3357,6 +3356,7 @@ do_sem_wake(struct thread *td, struct _usem *sem)
if (error == -1)
error = EFAULT;
}
+ umtxq_signal(&key, 1);
}
umtxq_unbusy(&key);
umtxq_unlock(&key);
OpenPOWER on IntegriCloud