Print this page
3746 ZRLs are racy
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>

*** 19,28 **** --- 19,30 ---- * CDDL HEADER END */ /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2015 by Delphix. All rights reserved. + * Copyright 2016 Spectra Logic Corporation. All rights reserved. + * Copyright 2016 The MathWorks, Inc. All rights reserved. */ /* * A Zero Reference Lock (ZRL) is a reference count that can lock out new * references only when the count is zero and only without waiting if the count
*** 69,83 **** --- 71,87 ---- } void zrl_add_impl(zrlock_t *zrl, const char *zc) { + 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,
*** 93,109 **** mutex_enter(&zrl->zr_mtx); while (zrl->zr_refcount == ZRL_LOCKED) { cv_wait(&zrl->zr_cv, &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 zrl_remove(zrlock_t *zrl) { --- 97,108 ---- mutex_enter(&zrl->zr_mtx); while (zrl->zr_refcount == ZRL_LOCKED) { cv_wait(&zrl->zr_cv, &zrl->zr_mtx); } mutex_exit(&zrl->zr_mtx); + } } void zrl_remove(zrlock_t *zrl) {