summaryrefslogtreecommitdiffstats
path: root/sys/cddl
diff options
context:
space:
mode:
authorkmacy <kmacy@FreeBSD.org>2009-05-07 21:51:13 +0000
committerkmacy <kmacy@FreeBSD.org>2009-05-07 21:51:13 +0000
commit9a7f66b336a4aa07b3719000c96f60ae670caf9a (patch)
treef51156404e3249f558e74aedaf5fd2d937ef081a /sys/cddl
parentfea9d1bdc9af437988646e11fcc8ec875bb13d0c (diff)
downloadFreeBSD-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')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c22
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;
}
/*
OpenPOWER on IntegriCloud