Mercurial > illumos > illumos-gate
changeset 12674:fb4985fff3dd
6954665 system stuck spinning in arc_evict_ghost()
author | Sanjeev Bagewadi <Sanjeev.Bagewadi@Sun.COM> |
---|---|
date | Wed, 23 Jun 2010 03:45:11 +0530 |
parents | e579258c2bb7 |
children | fa714c2912e2 |
files | usr/src/uts/common/fs/zfs/arc.c |
diffstat | 1 files changed, 20 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/fs/zfs/arc.c Tue Jun 22 14:06:24 2010 +0800 +++ b/usr/src/uts/common/fs/zfs/arc.c Wed Jun 23 03:45:11 2010 +0530 @@ -1744,6 +1744,7 @@ arc_evict_ghost(arc_state_t *state, uint64_t spa, int64_t bytes) { arc_buf_hdr_t *ab, *ab_prev; + arc_buf_hdr_t marker = { 0 }; list_t *list = &state->arcs_list[ARC_BUFC_DATA]; kmutex_t *hash_lock; uint64_t bytes_deleted = 0; @@ -1756,6 +1757,11 @@ ab_prev = list_prev(list, ab); if (spa && ab->b_spa != spa) continue; + + /* ignore markers */ + if (ab->b_spa == 0) + continue; + hash_lock = HDR_LOCK(ab); /* caller may be trying to modify this buffer, skip it */ if (MUTEX_HELD(hash_lock)) @@ -1782,15 +1788,21 @@ DTRACE_PROBE1(arc__delete, arc_buf_hdr_t *, ab); if (bytes >= 0 && bytes_deleted >= bytes) break; - } else { - if (bytes < 0) { - mutex_exit(&state->arcs_mtx); - mutex_enter(hash_lock); - mutex_exit(hash_lock); - goto top; - } + } else if (bytes < 0) { + /* + * Insert a list marker and then wait for the + * hash lock to become available. Once its + * available, restart from where we left off. + */ + list_insert_after(list, ab, &marker); + mutex_exit(&state->arcs_mtx); + mutex_enter(hash_lock); + mutex_exit(hash_lock); + mutex_enter(&state->arcs_mtx); + ab_prev = list_prev(list, &marker); + list_remove(list, &marker); + } else bufs_skipped += 1; - } } mutex_exit(&state->arcs_mtx);