Index: /usr/src/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c =================================================================== --- /usr/src/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c +++ /usr/src/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c @@ -3489,6 +3489,10 @@ #ifdef _KERNEL if (needfree > 0) { + n = (int64_t)vm_cnt.v_free_target - (int64_t)vm_cnt.v_free_count; + needfree = n > 0 ? n : 0; + } + if (needfree > 0) { n = PAGESIZE * (-needfree); if (n < lowest) { lowest = n; @@ -3500,7 +3504,7 @@ * Cooperate with pagedaemon when it's time for it to scan * and reclaim some pages. */ - n = PAGESIZE * ((int64_t)freemem - zfs_arc_free_target); + n = PAGESIZE * ((int64_t)freemem - (int64_t)zfs_arc_free_target - (int64_t)vm_cnt.v_free_reserved); if (n < lowest) { lowest = n; r = FMR_LOTSFREE; @@ -3710,11 +3714,18 @@ mutex_enter(&arc_reclaim_lock); while (!arc_reclaim_thread_exit) { - int64_t free_memory = arc_available_memory(); uint64_t evicted = 0; mutex_exit(&arc_reclaim_lock); + /* + * We call arc_adjust() before (possibly) calling + * arc_kmem_reap_now(), so that we can wake up + * arc_get_data_buf() sooner. + */ + evicted = arc_adjust(); + + int64_t free_memory = arc_available_memory(); if (free_memory < 0) { arc_no_grow = B_TRUE; @@ -3741,6 +3752,7 @@ to_free = MAX(to_free, ptob(needfree)); #endif arc_shrink(to_free); + arc_kmem_reap_now(); } } else if (free_memory < arc_c >> arc_no_grow_shift) { arc_no_grow = B_TRUE; @@ -3748,8 +3760,6 @@ arc_no_grow = B_FALSE; } - evicted = arc_adjust(); - mutex_enter(&arc_reclaim_lock); /* @@ -5434,17 +5444,10 @@ mutex_enter(&arc_reclaim_lock); /* XXX: Memory deficit should be passed as argument. */ - needfree = btoc(arc_c >> arc_shrink_shift); + needfree = (int64_t)vm_cnt.v_free_target - (int64_t)vm_cnt.v_free_count; + if(needfree <= 0) needfree = vm_cnt.v_free_target >> 8; DTRACE_PROBE(arc__needfree); cv_signal(&arc_reclaim_thread_cv); - - /* - * It is unsafe to block here in arbitrary threads, because we can come - * here from ARC itself and may hold ARC locks and thus risk a deadlock - * with ARC reclaim thread. - */ - if (curproc == pageproc) - (void) cv_wait(&arc_reclaim_waiters_cv, &arc_reclaim_lock); mutex_exit(&arc_reclaim_lock); } #endif