diff options
-rw-r--r-- | mm/vmscan.c | 44 |
1 files changed, 39 insertions, 5 deletions
diff --git a/mm/vmscan.c b/mm/vmscan.c index efbcab1c8f54..3b8ede882396 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -2163,6 +2163,42 @@ static void shrink_zone(int priority, struct zone *zone, | |||
2163 | } while (memcg); | 2163 | } while (memcg); |
2164 | } | 2164 | } |
2165 | 2165 | ||
2166 | /* Returns true if compaction should go ahead for a high-order request */ | ||
2167 | static inline bool compaction_ready(struct zone *zone, struct scan_control *sc) | ||
2168 | { | ||
2169 | unsigned long balance_gap, watermark; | ||
2170 | bool watermark_ok; | ||
2171 | |||
2172 | /* Do not consider compaction for orders reclaim is meant to satisfy */ | ||
2173 | if (sc->order <= PAGE_ALLOC_COSTLY_ORDER) | ||
2174 | return false; | ||
2175 | |||
2176 | /* | ||
2177 | * Compaction takes time to run and there are potentially other | ||
2178 | * callers using the pages just freed. Continue reclaiming until | ||
2179 | * there is a buffer of free pages available to give compaction | ||
2180 | * a reasonable chance of completing and allocating the page | ||
2181 | */ | ||
2182 | balance_gap = min(low_wmark_pages(zone), | ||
2183 | (zone->present_pages + KSWAPD_ZONE_BALANCE_GAP_RATIO-1) / | ||
2184 | KSWAPD_ZONE_BALANCE_GAP_RATIO); | ||
2185 | watermark = high_wmark_pages(zone) + balance_gap + (2UL << sc->order); | ||
2186 | watermark_ok = zone_watermark_ok_safe(zone, 0, watermark, 0, 0); | ||
2187 | |||
2188 | /* | ||
2189 | * If compaction is deferred, reclaim up to a point where | ||
2190 | * compaction will have a chance of success when re-enabled | ||
2191 | */ | ||
2192 | if (compaction_deferred(zone)) | ||
2193 | return watermark_ok; | ||
2194 | |||
2195 | /* If compaction is not ready to start, keep reclaiming */ | ||
2196 | if (!compaction_suitable(zone, sc->order)) | ||
2197 | return false; | ||
2198 | |||
2199 | return watermark_ok; | ||
2200 | } | ||
2201 | |||
2166 | /* | 2202 | /* |
2167 | * This is the direct reclaim path, for page-allocating processes. We only | 2203 | * This is the direct reclaim path, for page-allocating processes. We only |
2168 | * try to reclaim pages from zones which will satisfy the caller's allocation | 2204 | * 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, | |||
2180 | * scan then give up on it. | 2216 | * scan then give up on it. |
2181 | * | 2217 | * |
2182 | * This function returns true if a zone is being reclaimed for a costly | 2218 | * This function returns true if a zone is being reclaimed for a costly |
2183 | * high-order allocation and compaction is either ready to begin or deferred. | 2219 | * high-order allocation and compaction is ready to begin. This indicates to |
2184 | * This indicates to the caller that it should retry the allocation or fail. | 2220 | * the caller that it should retry the allocation or fail. |
2185 | */ | 2221 | */ |
2186 | static bool shrink_zones(int priority, struct zonelist *zonelist, | 2222 | static bool shrink_zones(int priority, struct zonelist *zonelist, |
2187 | struct scan_control *sc) | 2223 | struct scan_control *sc) |
@@ -2215,9 +2251,7 @@ static bool shrink_zones(int priority, struct zonelist *zonelist, | |||
2215 | * noticable problem, like transparent huge page | 2251 | * noticable problem, like transparent huge page |
2216 | * allocations. | 2252 | * allocations. |
2217 | */ | 2253 | */ |
2218 | if (sc->order > PAGE_ALLOC_COSTLY_ORDER && | 2254 | if (compaction_ready(zone, sc)) { |
2219 | (compaction_suitable(zone, sc->order) || | ||
2220 | compaction_deferred(zone))) { | ||
2221 | should_abort_reclaim = true; | 2255 | should_abort_reclaim = true; |
2222 | continue; | 2256 | continue; |
2223 | } | 2257 | } |