From c6f620c32b046839dbf4f906e50f260a93ddb74a Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Fri, 8 Jul 2011 14:14:36 +1000 Subject: [PATCH] --- yaml --- r: 257362 b: refs/heads/master c: 3567b59aa80ac4417002bf58e35dce5c777d4164 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/mm/vmscan.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index f99f87d1e92e..17cfde3778bd 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: acf92b485cccf028177f46918e045c0c4e80ee10 +refs/heads/master: 3567b59aa80ac4417002bf58e35dce5c777d4164 diff --git a/trunk/mm/vmscan.c b/trunk/mm/vmscan.c index 2f7c6ae8fae0..387422470c95 100644 --- a/trunk/mm/vmscan.c +++ b/trunk/mm/vmscan.c @@ -276,6 +276,21 @@ unsigned long shrink_slab(struct shrink_control *shrink, total_scan = max_pass; } + /* + * We need to avoid excessive windup on filesystem shrinkers + * due to large numbers of GFP_NOFS allocations causing the + * shrinkers to return -1 all the time. This results in a large + * nr being built up so when a shrink that can do some work + * comes along it empties the entire cache due to nr >>> + * max_pass. This is bad for sustaining a working set in + * memory. + * + * Hence only allow the shrinker to scan the entire cache when + * a large delta change is calculated directly. + */ + if (delta < max_pass / 4) + total_scan = min(total_scan, max_pass / 2); + /* * Avoid risking looping forever due to too large nr value: * never try to free more than twice the estimate number of