diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/vmscan.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c index bb7df1e2382..d375de3111b 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -277,6 +277,21 @@ unsigned long shrink_slab(struct shrink_control *shrink, } /* + * 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 * freeable entries. |