From owner-svn-src-all@freebsd.org Sun Feb 19 16:28:48 2017 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 70415CE51CB; Sun, 19 Feb 2017 16:28:48 +0000 (UTC) (envelope-from mjg@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 310F9800; Sun, 19 Feb 2017 16:28:48 +0000 (UTC) (envelope-from mjg@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v1JGSl90076988; Sun, 19 Feb 2017 16:28:47 GMT (envelope-from mjg@FreeBSD.org) Received: (from mjg@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v1JGSlTX076985; Sun, 19 Feb 2017 16:28:47 GMT (envelope-from mjg@FreeBSD.org) Message-Id: <201702191628.v1JGSlTX076985@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mjg set sender to mjg@FreeBSD.org using -f From: Mateusz Guzik Date: Sun, 19 Feb 2017 16:28:47 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r313944 - head/sys/kern X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 19 Feb 2017 16:28:48 -0000 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);