svn commit: r313944 - head/sys/kern
Mateusz Guzik
mjg at FreeBSD.org
Sun Feb 19 16:28:48 UTC 2017
Author: mjg
Date: Sun Feb 19 16:28:46 2017
New Revision: 313944
URL: https://svnweb.freebsd.org/changeset/base/313944
Log:
locks: make trylock routines check for 'unowned' value
Since fcmpset can fail without lock contention e.g. on arm, it was possible
to get spurious failures when the caller was expecting the primitive to succeed.
Reported by: mmel
Modified:
head/sys/kern/kern_mutex.c
head/sys/kern/kern_rwlock.c
head/sys/kern/kern_sx.c
Modified: head/sys/kern/kern_mutex.c
==============================================================================
--- head/sys/kern/kern_mutex.c Sun Feb 19 16:08:58 2017 (r313943)
+++ head/sys/kern/kern_mutex.c Sun Feb 19 16:28:46 2017 (r313944)
@@ -402,16 +402,21 @@ _mtx_trylock_flags_(volatile uintptr_t *
rval = 1;
recursed = false;
v = MTX_UNOWNED;
- if (!_mtx_obtain_lock_fetch(m, &v, tid)) {
+ for (;;) {
+ if (_mtx_obtain_lock_fetch(m, &v, tid))
+ break;
+ if (v == MTX_UNOWNED)
+ continue;
if (v == tid &&
((m->lock_object.lo_flags & LO_RECURSABLE) != 0 ||
(opts & MTX_RECURSE) != 0)) {
- m->mtx_recurse++;
- atomic_set_ptr(&m->mtx_lock, MTX_RECURSED);
- recursed = true;
- } else {
- rval = 0;
+ m->mtx_recurse++;
+ atomic_set_ptr(&m->mtx_lock, MTX_RECURSED);
+ recursed = true;
+ break;
}
+ rval = 0;
+ break;
}
opts &= ~MTX_RECURSE;
Modified: head/sys/kern/kern_rwlock.c
==============================================================================
--- head/sys/kern/kern_rwlock.c Sun Feb 19 16:08:58 2017 (r313943)
+++ head/sys/kern/kern_rwlock.c Sun Feb 19 16:28:46 2017 (r313944)
@@ -314,13 +314,18 @@ __rw_try_wlock(volatile uintptr_t *c, co
rval = 1;
recursed = false;
v = RW_UNLOCKED;
- if (!atomic_fcmpset_acq_ptr(&rw->rw_lock, &v, tid)) {
+ for (;;) {
+ if (atomic_fcmpset_acq_ptr(&rw->rw_lock, &v, tid))
+ break;
+ if (v == RW_UNLOCKED)
+ continue;
if (v == tid && (rw->lock_object.lo_flags & LO_RECURSABLE)) {
rw->rw_recurse++;
atomic_set_ptr(&rw->rw_lock, RW_LOCK_WRITER_RECURSED);
- } else {
- rval = 0;
+ break;
}
+ rval = 0;
+ break;
}
LOCK_LOG_TRY("WLOCK", &rw->lock_object, 0, rval, file, line);
Modified: head/sys/kern/kern_sx.c
==============================================================================
--- head/sys/kern/kern_sx.c Sun Feb 19 16:08:58 2017 (r313943)
+++ head/sys/kern/kern_sx.c Sun Feb 19 16:28:46 2017 (r313944)
@@ -341,13 +341,18 @@ sx_try_xlock_(struct sx *sx, const char
rval = 1;
recursed = false;
x = SX_LOCK_UNLOCKED;
- if (!atomic_fcmpset_acq_ptr(&sx->sx_lock, &x, tid)) {
+ for (;;) {
+ if (atomic_fcmpset_acq_ptr(&sx->sx_lock, &x, tid))
+ break;
+ if (x == SX_LOCK_UNLOCKED)
+ continue;
if (x == tid && (sx->lock_object.lo_flags & LO_RECURSABLE)) {
sx->sx_recurse++;
atomic_set_ptr(&sx->sx_lock, SX_LOCK_RECURSED);
- } else {
- rval = 0;
+ break;
}
+ rval = 0;
+ break;
}
LOCK_LOG_TRY("XLOCK", &sx->lock_object, 0, rval, file, line);
More information about the svn-src-head
mailing list