summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_sx.c
diff options
context:
space:
mode:
authorattilio <attilio@FreeBSD.org>2009-09-30 13:26:31 +0000
committerattilio <attilio@FreeBSD.org>2009-09-30 13:26:31 +0000
commite9f2530ebfd93a31f9261bfd21bfb5c95dab3720 (patch)
tree14bb844cbbe423beb58afda22e6444bab089a43e /sys/kern/kern_sx.c
parent49524d648a66d9f3860133c520a179e25a5f35aa (diff)
downloadFreeBSD-src-e9f2530ebfd93a31f9261bfd21bfb5c95dab3720.zip
FreeBSD-src-e9f2530ebfd93a31f9261bfd21bfb5c95dab3720.tar.gz
When releasing a read/shared lock we need to use a write memory barrier
in order to avoid, on architectures which doesn't have strong ordered writes, CPU instructions reordering. Diagnosed by: fabio Reviewed by: jhb Tested by: Giovanni Trematerra <giovanni dot trematerra at gmail dot com>
Diffstat (limited to 'sys/kern/kern_sx.c')
-rw-r--r--sys/kern/kern_sx.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/sys/kern/kern_sx.c b/sys/kern/kern_sx.c
index c00b267..2d777a2 100644
--- a/sys/kern/kern_sx.c
+++ b/sys/kern/kern_sx.c
@@ -931,7 +931,7 @@ _sx_sunlock_hard(struct sx *sx, const char *file, int line)
* so, just drop one and return.
*/
if (SX_SHARERS(x) > 1) {
- if (atomic_cmpset_ptr(&sx->sx_lock, x,
+ if (atomic_cmpset_rel_ptr(&sx->sx_lock, x,
x - SX_ONE_SHARER)) {
if (LOCK_LOG_TEST(&sx->lock_object, 0))
CTR4(KTR_LOCK,
@@ -949,8 +949,8 @@ _sx_sunlock_hard(struct sx *sx, const char *file, int line)
*/
if (!(x & SX_LOCK_EXCLUSIVE_WAITERS)) {
MPASS(x == SX_SHARERS_LOCK(1));
- if (atomic_cmpset_ptr(&sx->sx_lock, SX_SHARERS_LOCK(1),
- SX_LOCK_UNLOCKED)) {
+ if (atomic_cmpset_rel_ptr(&sx->sx_lock,
+ SX_SHARERS_LOCK(1), SX_LOCK_UNLOCKED)) {
if (LOCK_LOG_TEST(&sx->lock_object, 0))
CTR2(KTR_LOCK, "%s: %p last succeeded",
__func__, sx);
@@ -973,7 +973,7 @@ _sx_sunlock_hard(struct sx *sx, const char *file, int line)
* Note that the state of the lock could have changed,
* so if it fails loop back and retry.
*/
- if (!atomic_cmpset_ptr(&sx->sx_lock,
+ if (!atomic_cmpset_rel_ptr(&sx->sx_lock,
SX_SHARERS_LOCK(1) | SX_LOCK_EXCLUSIVE_WAITERS,
SX_LOCK_UNLOCKED)) {
sleepq_release(&sx->lock_object);
OpenPOWER on IntegriCloud