diff options
author | avg <avg@FreeBSD.org> | 2016-11-03 08:54:04 +0000 |
---|---|---|
committer | avg <avg@FreeBSD.org> | 2016-11-03 08:54:04 +0000 |
commit | e229fa41775d369f7dbcf831351c9a42ef66c4de (patch) | |
tree | 0e10f427f9dc6d4de18a5005694bccaa5672dd1d /sys/cddl | |
parent | b69b4c10027852f32db19fcda7c1b086c80fcb1e (diff) | |
download | FreeBSD-src-e229fa41775d369f7dbcf831351c9a42ef66c4de.zip FreeBSD-src-e229fa41775d369f7dbcf831351c9a42ef66c4de.tar.gz |
MFC r307994: 3746 ZRLs are racy
PR: 204037
Diffstat (limited to 'sys/cddl')
-rw-r--r-- | sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zrlock.c | 48 |
1 files changed, 22 insertions, 26 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zrlock.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zrlock.c index 7f6beee..ec333e5 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zrlock.c +++ b/sys/cddl/contrib/opensolaris/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 |