Commit 35cd78156c499ef83f60605e4643d5a98fef14fd

Authored by Rik van Riel
Committed by Linus Torvalds
1 parent a731286de6

vmscan: throttle direct reclaim when too many pages are isolated already

When way too many processes go into direct reclaim, it is possible for all
of the pages to be taken off the LRU.  One result of this is that the next
process in the page reclaim code thinks there are no reclaimable pages
left and triggers an out of memory kill.

One solution to this problem is to never let so many processes into the
page reclaim path that the entire LRU is emptied.  Limiting the system to
only having half of each inactive list isolated for reclaim should be
safe.

Signed-off-by: Rik van Riel <riel@redhat.com>
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 1 changed file with 33 additions and 0 deletions Side-by-side Diff

... ... @@ -1034,6 +1034,31 @@
1034 1034 }
1035 1035  
1036 1036 /*
  1037 + * Are there way too many processes in the direct reclaim path already?
  1038 + */
  1039 +static int too_many_isolated(struct zone *zone, int file,
  1040 + struct scan_control *sc)
  1041 +{
  1042 + unsigned long inactive, isolated;
  1043 +
  1044 + if (current_is_kswapd())
  1045 + return 0;
  1046 +
  1047 + if (!scanning_global_lru(sc))
  1048 + return 0;
  1049 +
  1050 + if (file) {
  1051 + inactive = zone_page_state(zone, NR_INACTIVE_FILE);
  1052 + isolated = zone_page_state(zone, NR_ISOLATED_FILE);
  1053 + } else {
  1054 + inactive = zone_page_state(zone, NR_INACTIVE_ANON);
  1055 + isolated = zone_page_state(zone, NR_ISOLATED_ANON);
  1056 + }
  1057 +
  1058 + return isolated > inactive;
  1059 +}
  1060 +
  1061 +/*
1037 1062 * shrink_inactive_list() is a helper for shrink_zone(). It returns the number
1038 1063 * of reclaimed pages
1039 1064 */
... ... @@ -1047,6 +1072,14 @@
1047 1072 unsigned long nr_reclaimed = 0;
1048 1073 struct zone_reclaim_stat *reclaim_stat = get_reclaim_stat(zone, sc);
1049 1074 int lumpy_reclaim = 0;
  1075 +
  1076 + while (unlikely(too_many_isolated(zone, file, sc))) {
  1077 + congestion_wait(WRITE, HZ/10);
  1078 +
  1079 + /* We are about to die and free our memory. Return now. */
  1080 + if (fatal_signal_pending(current))
  1081 + return SWAP_CLUSTER_MAX;
  1082 + }
1050 1083  
1051 1084 /*
1052 1085 * If we need a large contiguous chunk of memory, or have