Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c.new =================================================================== --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c.new +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c.new @@ -3447,6 +3447,7 @@ } static long needfree = 0; +static int64_t arc_target_size = 0; typedef enum free_memory_reason_t { FMR_UNKNOWN, @@ -3485,6 +3486,10 @@ free_memory_reason_t r = FMR_UNKNOWN; #ifdef _KERNEL + if (needfree) { + if(arc_size <= arc_target_size) needfree = 0; + else needfree = btoc(arc_size - arc_target_size); + } if (needfree > 0) { n = PAGESIZE * (-needfree); if (n < lowest) { @@ -3737,8 +3737,10 @@ */ free_memory = arc_available_memory(); - int64_t to_free = - (arc_c >> arc_shrink_shift) - free_memory; + int64_t to_free; + if (free_memory >= 0) to_free = (arc_c >> arc_shrink_shift) - free_memory; + else to_free = -free_memory; + if (to_free > 0) { #ifdef _KERNEL to_free = MAX(to_free, ptob(needfree)); @@ -5360,6 +5365,7 @@ mutex_enter(&arc_reclaim_lock); /* XXX: Memory deficit should be passed as argument. */ needfree = btoc(arc_c >> arc_shrink_shift); + arc_target_size = arc_size - needfree * PAGESIZE; DTRACE_PROBE(arc__needfree); cv_signal(&arc_reclaim_thread_cv);