diff options
author | badger <badger@FreeBSD.org> | 2016-08-30 13:39:42 +0000 |
---|---|---|
committer | badger <badger@FreeBSD.org> | 2016-08-30 13:39:42 +0000 |
commit | d8feb13e02c7681586150351a1684bbea3f54e5c (patch) | |
tree | d4465a7c4c3874d05951fedfd70e276a55c359c0 | |
parent | de43eec3e10416a7e9f3a7565f70e1ba2d265384 (diff) | |
download | FreeBSD-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.c | 2 |
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); |