]> granicus.if.org Git - zfs/commitdiff
Allow scaling of arc in proportion to pagecache
authorDebabrata Banerjee <dbanerje@akamai.com>
Thu, 16 Mar 2017 01:34:56 +0000 (21:34 -0400)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 2 May 2017 19:50:49 +0000 (15:50 -0400)
When multiple filesystems are in use, memory pressure causes arc_cache
to collapse to a minimum. Allow arc_cache to maintain proportional size
even when hit rates are disproportionate. We do this only via evictable
size from the kernel shrinker, thus it's only in effect under memory
pressure.

AKAMAI: zfs: CR 3695072
Reviewed-by: Tim Chase <tim@chase2k.com>
Reviewed-by: Richard Yao <ryao@gentoo.org>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Debabrata Banerjee <dbanerje@akamai.com>
Closes #6035

man/man5/zfs-module-parameters.5
module/zfs/arc.c

index 77f1af6d58870576d86b180e84bee1834ea8667d..2fbab1d010de326469c5f22196b061c1778419d9 100644 (file)
@@ -699,6 +699,24 @@ log2(fraction of arc to reclaim)
 Default value: \fB5\fR.
 .RE
 
+.sp
+.ne 2
+.na
+\fBzfs_arc_pc_percent\fR (uint)
+.ad
+.RS 12n
+Percent of pagecache to reclaim arc to
+
+This tunable allows ZFS arc to play more nicely with the kernel's LRU
+pagecache. It can guarantee that the arc size won't collapse under scanning
+pressure on the pagecache, yet still allows arc to be reclaimed down to
+zfs_arc_min if necessary. This value is specified as percent of pagecache
+size (as measured by NR_FILE_PAGES) where that percent may exceed 100. This
+only operates during memory pressure/reclaim.
+.sp
+Default value: \fB0\fR (disabled).
+.RE
+
 .sp
 .ne 2
 .na
index ce9246061639e07496ad638e3fc006503311a553..acf98dd2dd8c349a729c3f65442aeabb7e963636 100644 (file)
@@ -319,6 +319,11 @@ static int         arc_p_min_shift = 4;
 /* log2(fraction of arc to reclaim) */
 static int             arc_shrink_shift = 7;
 
+/* percent of pagecache to reclaim arc to */
+#ifdef _KERNEL
+static uint_t          zfs_arc_pc_percent = 0;
+#endif
+
 /*
  * log2(fraction of ARC which must be free to allow growing).
  * I.e. If there is less than arc_c >> arc_no_grow_shift free memory,
@@ -4377,10 +4382,18 @@ arc_evictable_memory(void)
            refcount_count(&arc_mfu->arcs_esize[ARC_BUFC_METADATA]);
        uint64_t arc_dirty = MAX((int64_t)arc_size - (int64_t)arc_clean, 0);
 
-       if (arc_dirty >= arc_c_min)
+       /*
+        * Scale reported evictable memory in proportion to page cache, cap
+        * at specified min/max.
+        */
+       uint64_t min = (ptob(global_page_state(NR_FILE_PAGES)) / 100) *
+           zfs_arc_pc_percent;
+       min = MAX(arc_c_min, MIN(arc_c_max, min));
+
+       if (arc_dirty >= min)
                return (arc_clean);
 
-       return (MAX((int64_t)arc_size - (int64_t)arc_c_min, 0));
+       return (MAX((int64_t)arc_size - (int64_t)min, 0));
 }
 
 /*
@@ -7754,6 +7767,10 @@ MODULE_PARM_DESC(zfs_arc_p_dampener_disable, "disable arc_p adapt dampener");
 module_param(zfs_arc_shrink_shift, int, 0644);
 MODULE_PARM_DESC(zfs_arc_shrink_shift, "log2(fraction of arc to reclaim)");
 
+module_param(zfs_arc_pc_percent, uint, 0644);
+MODULE_PARM_DESC(zfs_arc_pc_percent,
+       "Percent of pagecache to reclaim arc to");
+
 module_param(zfs_arc_p_min_shift, int, 0644);
 MODULE_PARM_DESC(zfs_arc_p_min_shift, "arc_c shift to calc min/max arc_p");