summaryrefslogtreecommitdiffstats
path: root/sys/cddl
diff options
context:
space:
mode:
authoravg <avg@FreeBSD.org>2016-11-03 08:54:04 +0000
committeravg <avg@FreeBSD.org>2016-11-03 08:54:04 +0000
commite229fa41775d369f7dbcf831351c9a42ef66c4de (patch)
tree0e10f427f9dc6d4de18a5005694bccaa5672dd1d /sys/cddl
parentb69b4c10027852f32db19fcda7c1b086c80fcb1e (diff)
downloadFreeBSD-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.c48
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
OpenPOWER on IntegriCloud