|
@@ -2163,6 +2163,42 @@ static void shrink_zone(int priority, struct zone *zone,
|
|
|
} while (memcg);
|
|
|
}
|
|
|
|
|
|
+/* Returns true if compaction should go ahead for a high-order request */
|
|
|
+static inline bool compaction_ready(struct zone *zone, struct scan_control *sc)
|
|
|
+{
|
|
|
+ unsigned long balance_gap, watermark;
|
|
|
+ bool watermark_ok;
|
|
|
+
|
|
|
+ /* Do not consider compaction for orders reclaim is meant to satisfy */
|
|
|
+ if (sc->order <= PAGE_ALLOC_COSTLY_ORDER)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Compaction takes time to run and there are potentially other
|
|
|
+ * callers using the pages just freed. Continue reclaiming until
|
|
|
+ * there is a buffer of free pages available to give compaction
|
|
|
+ * a reasonable chance of completing and allocating the page
|
|
|
+ */
|
|
|
+ balance_gap = min(low_wmark_pages(zone),
|
|
|
+ (zone->present_pages + KSWAPD_ZONE_BALANCE_GAP_RATIO-1) /
|
|
|
+ KSWAPD_ZONE_BALANCE_GAP_RATIO);
|
|
|
+ watermark = high_wmark_pages(zone) + balance_gap + (2UL << sc->order);
|
|
|
+ watermark_ok = zone_watermark_ok_safe(zone, 0, watermark, 0, 0);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If compaction is deferred, reclaim up to a point where
|
|
|
+ * compaction will have a chance of success when re-enabled
|
|
|
+ */
|
|
|
+ if (compaction_deferred(zone))
|
|
|
+ return watermark_ok;
|
|
|
+
|
|
|
+ /* If compaction is not ready to start, keep reclaiming */
|
|
|
+ if (!compaction_suitable(zone, sc->order))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ return watermark_ok;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* This is the direct reclaim path, for page-allocating processes. We only
|
|
|
* try to reclaim pages from zones which will satisfy the caller's allocation
|
|
@@ -2180,8 +2216,8 @@ static void shrink_zone(int priority, struct zone *zone,
|
|
|
* scan then give up on it.
|
|
|
*
|
|
|
* This function returns true if a zone is being reclaimed for a costly
|
|
|
- * high-order allocation and compaction is either ready to begin or deferred.
|
|
|
- * This indicates to the caller that it should retry the allocation or fail.
|
|
|
+ * high-order allocation and compaction is ready to begin. This indicates to
|
|
|
+ * the caller that it should retry the allocation or fail.
|
|
|
*/
|
|
|
static bool shrink_zones(int priority, struct zonelist *zonelist,
|
|
|
struct scan_control *sc)
|
|
@@ -2215,9 +2251,7 @@ static bool shrink_zones(int priority, struct zonelist *zonelist,
|
|
|
* noticable problem, like transparent huge page
|
|
|
* allocations.
|
|
|
*/
|
|
|
- if (sc->order > PAGE_ALLOC_COSTLY_ORDER &&
|
|
|
- (compaction_suitable(zone, sc->order) ||
|
|
|
- compaction_deferred(zone))) {
|
|
|
+ if (compaction_ready(zone, sc)) {
|
|
|
should_abort_reclaim = true;
|
|
|
continue;
|
|
|
}
|