diff options
author | kmacy <kmacy@FreeBSD.org> | 2009-05-07 21:51:13 +0000 |
---|---|---|
committer | kmacy <kmacy@FreeBSD.org> | 2009-05-07 21:51:13 +0000 |
commit | 9a7f66b336a4aa07b3719000c96f60ae670caf9a (patch) | |
tree | f51156404e3249f558e74aedaf5fd2d937ef081a /sys/cddl/contrib/opensolaris/uts/common/fs/zfs | |
parent | fea9d1bdc9af437988646e11fcc8ec875bb13d0c (diff) | |
download | FreeBSD-src-9a7f66b336a4aa07b3719000c96f60ae670caf9a.zip FreeBSD-src-9a7f66b336a4aa07b3719000c96f60ae670caf9a.tar.gz |
avoid LOR and gratuitous extra lock acquisitions by moving user_evict list buffers to
a temporary list
Diffstat (limited to 'sys/cddl/contrib/opensolaris/uts/common/fs/zfs')
-rw-r--r-- | sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c index de9a973..a3e2580 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c @@ -1712,14 +1712,23 @@ arc_adjust(void) static void arc_do_user_evicts(void) { + static arc_buf_t *tmp_arc_eviction_list; + + /* + * Move list over to avoid LOR + */ +restart: mutex_enter(&arc_eviction_mtx); - while (arc_eviction_list != NULL) { - arc_buf_t *buf = arc_eviction_list; - arc_eviction_list = buf->b_next; + tmp_arc_eviction_list = arc_eviction_list; + arc_eviction_list = NULL; + mutex_exit(&arc_eviction_mtx); + + while (tmp_arc_eviction_list != NULL) { + arc_buf_t *buf = tmp_arc_eviction_list; + tmp_arc_eviction_list = buf->b_next; rw_enter(&buf->b_lock, RW_WRITER); buf->b_hdr = NULL; rw_exit(&buf->b_lock); - mutex_exit(&arc_eviction_mtx); if (buf->b_efunc != NULL) VERIFY(buf->b_efunc(buf) == 0); @@ -1727,9 +1736,10 @@ arc_do_user_evicts(void) buf->b_efunc = NULL; buf->b_private = NULL; kmem_cache_free(buf_cache, buf); - mutex_enter(&arc_eviction_mtx); } - mutex_exit(&arc_eviction_mtx); + + if (arc_eviction_list != NULL) + goto restart; } /* |