diff options
author | Arne Jansen <[email protected]> | 2015-07-02 17:58:17 +0200 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2015-07-06 09:31:35 -0700 |
commit | 5e8cd5d17f21200beb5f6fae8e8be64c0491195d (patch) | |
tree | e714db2ad0eeb07ff449c433a4516dacefe41cc6 /module/zfs/rrwlock.c | |
parent | 71e2fe41be982076f14fe5d39bcf5f7051a937f0 (diff) |
Illumos 5981 - Deadlock in dmu_objset_find_dp
5981 Deadlock in dmu_objset_find_dp
Reviewed by: Matthew Ahrens <[email protected]>
Reviewed by: Dan McDonald <[email protected]>
Approved by: Robert Mustacchi <[email protected]>
References:
https://www.illumos.org/issues/5981
https://github.com/illumos/illumos-gate/commit/1d3f896
Ported-by: kernelOfTruth [email protected]
Signed-off-by: Brian Behlendorf <[email protected]>
Closes #3553
Diffstat (limited to 'module/zfs/rrwlock.c')
-rw-r--r-- | module/zfs/rrwlock.c | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/module/zfs/rrwlock.c b/module/zfs/rrwlock.c index 8e80166c7..29a22534e 100644 --- a/module/zfs/rrwlock.c +++ b/module/zfs/rrwlock.c @@ -159,8 +159,8 @@ rrw_destroy(rrwlock_t *rrl) refcount_destroy(&rrl->rr_linked_rcount); } -void -rrw_enter_read(rrwlock_t *rrl, void *tag) +static void +rrw_enter_read_impl(rrwlock_t *rrl, boolean_t prio, void *tag) { mutex_enter(&rrl->rr_lock); #if !defined(DEBUG) && defined(_KERNEL) @@ -176,7 +176,7 @@ rrw_enter_read(rrwlock_t *rrl, void *tag) ASSERT(refcount_count(&rrl->rr_anon_rcount) >= 0); while (rrl->rr_writer != NULL || (rrl->rr_writer_wanted && - refcount_is_zero(&rrl->rr_anon_rcount) && + refcount_is_zero(&rrl->rr_anon_rcount) && !prio && rrn_find(rrl) == NULL)) cv_wait(&rrl->rr_cv, &rrl->rr_lock); @@ -192,6 +192,25 @@ rrw_enter_read(rrwlock_t *rrl, void *tag) } void +rrw_enter_read(rrwlock_t *rrl, void *tag) +{ + rrw_enter_read_impl(rrl, B_FALSE, tag); +} + +/* + * take a read lock even if there are pending write lock requests. if we want + * to take a lock reentrantly, but from different threads (that have a + * relationship to each other), the normal detection mechanism to overrule + * the pending writer does not work, so we have to give an explicit hint here. + */ +void +rrw_enter_read_prio(rrwlock_t *rrl, void *tag) +{ + rrw_enter_read_impl(rrl, B_TRUE, tag); +} + + +void rrw_enter_write(rrwlock_t *rrl) { mutex_enter(&rrl->rr_lock); |