Date: Sun, 19 Feb 2017 16:28:47 +0000 (UTC) From: Mateusz Guzik <mjg@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r313944 - head/sys/kern Message-ID: <201702191628.v1JGSlTX076985@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201702191628.v1JGSlTX076985>