summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPrakash Surya <[email protected]>2013-12-11 12:25:30 -0800
committerBrian Behlendorf <[email protected]>2014-02-21 14:53:08 -0800
commit39e055c44b3025d9ef87f6c6178ef5ae5e2a55c6 (patch)
treea4b3581ed1870fdc33a6d38446420a9c9e5e3240
parent914158259225d9723bbb288457797936b41d3c9a (diff)
Adjust arc_p based on "bytes" in arc_shrink
In an attempt to prevent arc_c from collapsing "too fast", the arc_shrink() function was updated to take a "bytes" parameter by this change: commit 302f753f1657c05a4287226eeda1f53ae431b8a7 Author: Brian Behlendorf <[email protected]> Date: Tue Mar 13 14:29:16 2012 -0700 Integrate ARC more tightly with Linux Unfortunately, that change failed to make a similar change to the way that arc_p was updated. So, there still exists the possibility for arc_p to collapse to near 0 when the kernel start calling the arc's shrinkers. This change attempts to fix this, by decrementing arc_p by the "bytes" parameter in the same way that arc_c is updated. In addition, a minimum value of arc_p is attempted to be maintained, similar to the way a minimum arc_p value is maintained in arc_adapt(). Signed-off-by: Prakash Surya <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> Issue #2110
-rw-r--r--module/zfs/arc.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/module/zfs/arc.c b/module/zfs/arc.c
index 11839af59..cbc9b9fee 100644
--- a/module/zfs/arc.c
+++ b/module/zfs/arc.c
@@ -2332,6 +2332,7 @@ void
arc_shrink(uint64_t bytes)
{
if (arc_c > arc_c_min) {
+ uint64_t arc_p_min;
uint64_t to_free;
to_free = bytes ? bytes : arc_c >> zfs_arc_shrink_shift;
@@ -2341,7 +2342,14 @@ arc_shrink(uint64_t bytes)
else
arc_c = arc_c_min;
- atomic_add_64(&arc_p, -(arc_p >> zfs_arc_shrink_shift));
+ arc_p_min = (arc_c >> zfs_arc_p_min_shift);
+ to_free = bytes ? bytes : arc_p >> zfs_arc_shrink_shift;
+
+ if (arc_p > arc_p_min + to_free)
+ atomic_add_64(&arc_p, -to_free);
+ else
+ arc_p = arc_p_min;
+
if (arc_c > arc_size)
arc_c = MAX(arc_size, arc_c_min);
if (arc_p > arc_c)