diff options
author | Youzhong Yang <yyang@mathworks.com> | 2016-09-28 12:48:00 +0000 |
---|---|---|
committer | Robert Mustacchi <rm@joyent.com> | 2016-10-12 10:14:32 -0700 |
commit | 260af64db74a52d64de8c6c5f67dd0a71d228ca5 (patch) | |
tree | d4f5c1dba1262b6935aa545b206826cfe740bc6c /usr/src | |
parent | ea4c6b78cebe2a3687fa43deeedf6212a124d817 (diff) | |
download | illumos-joyent-260af64db74a52d64de8c6c5f67dd0a71d228ca5.tar.gz |
3746 ZRLs are racy
Authored by: Will Andrews <will@freebsd.org>
Reviewed by: Boris Protopopov <bprotopopov@hotmail.com>
Reviewed by: Pavel Zakharov <pavel.zakha@gmail.com>
Reviewed by: Yuri Pankov <yuri.pankov@gmail.com>
Reviewed by: Justin T. Gibbs <gibbs@scsiguy.com>
Approved by: Matt Ahrens <mahrens@delphix.com>
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/common/fs/zfs/zrlock.c | 48 |
1 files changed, 22 insertions, 26 deletions
diff --git a/usr/src/uts/common/fs/zfs/zrlock.c b/usr/src/uts/common/fs/zfs/zrlock.c index 7f6beeed61..ec333e54d2 100644 --- a/usr/src/uts/common/fs/zfs/zrlock.c +++ b/usr/src/uts/common/fs/zfs/zrlock.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2015 by Delphix. All rights reserved. + * Copyright 2016 The MathWorks, Inc. All rights reserved. */ /* @@ -71,37 +72,32 @@ zrl_destroy(zrlock_t *zrl) void zrl_add_impl(zrlock_t *zrl, const char *zc) { - uint32_t n = (uint32_t)zrl->zr_refcount; - - while (n != ZRL_LOCKED) { - uint32_t cas = atomic_cas_32( - (uint32_t *)&zrl->zr_refcount, n, n + 1); - if (cas == n) { - ASSERT3S((int32_t)n, >=, 0); + for (;;) { + uint32_t n = (uint32_t)zrl->zr_refcount; + while (n != ZRL_LOCKED) { + uint32_t cas = atomic_cas_32( + (uint32_t *)&zrl->zr_refcount, n, n + 1); + if (cas == n) { + ASSERT3S((int32_t)n, >=, 0); #ifdef ZFS_DEBUG - if (zrl->zr_owner == curthread) { - DTRACE_PROBE2(zrlock__reentry, - zrlock_t *, zrl, uint32_t, n); - } - zrl->zr_owner = curthread; - zrl->zr_caller = zc; + if (zrl->zr_owner == curthread) { + DTRACE_PROBE2(zrlock__reentry, + zrlock_t *, zrl, uint32_t, n); + } + zrl->zr_owner = curthread; + zrl->zr_caller = zc; #endif - return; + return; + } + n = cas; } - n = cas; - } - mutex_enter(&zrl->zr_mtx); - while (zrl->zr_refcount == ZRL_LOCKED) { - cv_wait(&zrl->zr_cv, &zrl->zr_mtx); + mutex_enter(&zrl->zr_mtx); + while (zrl->zr_refcount == ZRL_LOCKED) { + cv_wait(&zrl->zr_cv, &zrl->zr_mtx); + } + mutex_exit(&zrl->zr_mtx); } - ASSERT3S(zrl->zr_refcount, >=, 0); - zrl->zr_refcount++; -#ifdef ZFS_DEBUG - zrl->zr_owner = curthread; - zrl->zr_caller = zc; -#endif - mutex_exit(&zrl->zr_mtx); } void |