Index: mm/vmscan.c |
diff --git a/mm/vmscan.c b/mm/vmscan.c |
index 4649929401f888e87814ae35d87a106a9db410ae..045e8299b4ace3e3694e09c9fea32c8b09b40fb1 100644 |
--- a/mm/vmscan.c |
+++ b/mm/vmscan.c |
@@ -130,6 +130,11 @@ struct scan_control { |
int vm_swappiness = 60; |
long vm_total_pages; /* The total number of pages which the VM controls */ |
+/* |
+ * Low watermark used to prevent fscache thrashing during low memory. |
+ */ |
+int min_filelist_kbytes = 0; |
+ |
static LIST_HEAD(shrinker_list); |
static DECLARE_RWSEM(shrinker_rwsem); |
@@ -1510,11 +1515,31 @@ static int inactive_list_is_low(struct zone *zone, struct scan_control *sc, |
return inactive_anon_is_low(zone, sc); |
} |
+/* |
+ * Check low watermark used to prevent fscache thrashing during low memory. |
+ */ |
+static int file_is_low(struct zone *zone, struct scan_control *sc) |
+{ |
+ unsigned long pages_min, active, inactive; |
+ |
+ if (!scanning_global_lru(sc)) |
+ return false; |
+ |
+ pages_min = min_filelist_kbytes >> (PAGE_SHIFT - 10); |
+ active = zone_page_state(zone, NR_ACTIVE_FILE); |
+ inactive = zone_page_state(zone, NR_INACTIVE_FILE); |
+ |
+ return ((active + inactive) < pages_min); |
+} |
+ |
static unsigned long shrink_list(enum lru_list lru, unsigned long nr_to_scan, |
struct zone *zone, struct scan_control *sc, int priority) |
{ |
int file = is_file_lru(lru); |
+ if (file && file_is_low(zone, sc)) |
+ return 0; |
+ |
if (is_active_lru(lru)) { |
if (inactive_list_is_low(zone, sc, file)) |
shrink_active_list(nr_to_scan, zone, sc, priority, file); |