Mercurial > illumos > illumos-gate
changeset 11712:3b88ce606c90
6615402 recursive mutex enter on the hash lock in arc_evict_ghost
author | William Gorrell <william.gorrell@sun.com> |
---|---|
date | Fri, 19 Feb 2010 10:41:19 -0700 |
parents | d0efae043e26 |
children | 03615b084875 |
files | usr/src/uts/common/fs/zfs/arc.c |
diffstat | 1 files changed, 7 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/fs/zfs/arc.c Fri Feb 19 08:06:02 2010 -0800 +++ b/usr/src/uts/common/fs/zfs/arc.c Fri Feb 19 10:41:19 2010 -0700 @@ -1722,6 +1722,7 @@ kmutex_t *hash_lock; uint64_t bytes_deleted = 0; uint64_t bufs_skipped = 0; + boolean_t have_lock; ASSERT(GHOST_STATE(state)); top: @@ -1731,7 +1732,8 @@ if (spa && ab->b_spa != spa) continue; hash_lock = HDR_LOCK(ab); - if (mutex_tryenter(hash_lock)) { + have_lock = MUTEX_HELD(hash_lock); + if (have_lock || mutex_tryenter(hash_lock)) { ASSERT(!HDR_IO_IN_PROGRESS(ab)); ASSERT(ab->b_buf == NULL); ARCSTAT_BUMP(arcstat_deleted); @@ -1743,10 +1745,12 @@ * don't destroy the header. */ arc_change_state(arc_l2c_only, ab, hash_lock); - mutex_exit(hash_lock); + if (!have_lock) + mutex_exit(hash_lock); } else { arc_change_state(arc_anon, ab, hash_lock); - mutex_exit(hash_lock); + if (!have_lock) + mutex_exit(hash_lock); arc_hdr_destroy(ab); }