|
@@ -41,6 +41,7 @@
|
|
#include <linux/memcontrol.h>
|
|
#include <linux/memcontrol.h>
|
|
#include <linux/delayacct.h>
|
|
#include <linux/delayacct.h>
|
|
#include <linux/sysctl.h>
|
|
#include <linux/sysctl.h>
|
|
|
|
+#include <linux/oom.h>
|
|
|
|
|
|
#include <asm/tlbflush.h>
|
|
#include <asm/tlbflush.h>
|
|
#include <asm/div64.h>
|
|
#include <asm/div64.h>
|
|
@@ -1988,17 +1989,12 @@ static bool zone_reclaimable(struct zone *zone)
|
|
return zone->pages_scanned < zone_reclaimable_pages(zone) * 6;
|
|
return zone->pages_scanned < zone_reclaimable_pages(zone) * 6;
|
|
}
|
|
}
|
|
|
|
|
|
-/*
|
|
|
|
- * As hibernation is going on, kswapd is freezed so that it can't mark
|
|
|
|
- * the zone into all_unreclaimable. It can't handle OOM during hibernation.
|
|
|
|
- * So let's check zone's unreclaimable in direct reclaim as well as kswapd.
|
|
|
|
- */
|
|
|
|
|
|
+/* All zones in zonelist are unreclaimable? */
|
|
static bool all_unreclaimable(struct zonelist *zonelist,
|
|
static bool all_unreclaimable(struct zonelist *zonelist,
|
|
struct scan_control *sc)
|
|
struct scan_control *sc)
|
|
{
|
|
{
|
|
struct zoneref *z;
|
|
struct zoneref *z;
|
|
struct zone *zone;
|
|
struct zone *zone;
|
|
- bool all_unreclaimable = true;
|
|
|
|
|
|
|
|
for_each_zone_zonelist_nodemask(zone, z, zonelist,
|
|
for_each_zone_zonelist_nodemask(zone, z, zonelist,
|
|
gfp_zone(sc->gfp_mask), sc->nodemask) {
|
|
gfp_zone(sc->gfp_mask), sc->nodemask) {
|
|
@@ -2006,13 +2002,11 @@ static bool all_unreclaimable(struct zonelist *zonelist,
|
|
continue;
|
|
continue;
|
|
if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL))
|
|
if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL))
|
|
continue;
|
|
continue;
|
|
- if (zone_reclaimable(zone)) {
|
|
|
|
- all_unreclaimable = false;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
|
|
+ if (!zone->all_unreclaimable)
|
|
|
|
+ return false;
|
|
}
|
|
}
|
|
|
|
|
|
- return all_unreclaimable;
|
|
|
|
|
|
+ return true;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -2108,6 +2102,14 @@ out:
|
|
if (sc->nr_reclaimed)
|
|
if (sc->nr_reclaimed)
|
|
return sc->nr_reclaimed;
|
|
return sc->nr_reclaimed;
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * As hibernation is going on, kswapd is freezed so that it can't mark
|
|
|
|
+ * the zone into all_unreclaimable. Thus bypassing all_unreclaimable
|
|
|
|
+ * check.
|
|
|
|
+ */
|
|
|
|
+ if (oom_killer_disabled)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
/* top priority shrink_zones still had more to do? don't OOM, then */
|
|
/* top priority shrink_zones still had more to do? don't OOM, then */
|
|
if (scanning_global_lru(sc) && !all_unreclaimable(zonelist, sc))
|
|
if (scanning_global_lru(sc) && !all_unreclaimable(zonelist, sc))
|
|
return 1;
|
|
return 1;
|