aboutsummaryrefslogtreecommitdiffstats
path: root/mm/vmscan.c
diff options
context:
space:
mode:
authorMel Gorman <mgorman@suse.de>2012-01-12 20:19:45 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-01-12 23:13:09 -0500
commitfe4b1b244bdb96136855f2c694071cb09d140766 (patch)
treec1fafe7ef5b5bd7c77ae981b47fa82916e0436eb /mm/vmscan.c
parenta6bc32b899223a877f595ef9ddc1e89ead5072b8 (diff)
mm: vmscan: when reclaiming for compaction, ensure there are sufficient free pages available
In commit e0887c19 ("vmscan: limit direct reclaim for higher order allocations"), Rik noted that reclaim was too aggressive when THP was enabled. In his initial patch he used the number of free pages to decide if reclaim should abort for compaction. My feedback was that reclaim and compaction should be using the same logic when deciding if reclaim should be aborted. Unfortunately, this had the effect of reducing THP success rates when the workload included something like streaming reads that continually allocated pages. The window during which compaction could run and return a THP was too small. This patch combines Rik's two patches together. compaction_suitable() is still used to decide if reclaim should be aborted to allow compaction is used. However, it will also ensure that there is a reasonable buffer of free pages available. This improves upon the THP allocation success rates but bounds the number of pages that are freed for compaction. Signed-off-by: Mel Gorman <mgorman@suse.de> Reviewed-by: Rik van Riel<riel@redhat.com> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: Minchan Kim <minchan.kim@gmail.com> Cc: Dave Jones <davej@redhat.com> Cc: Jan Kara <jack@suse.cz> Cc: Andy Isaacson <adi@hexapodia.org> Cc: Nai Xia <nai.xia@gmail.com> Cc: Johannes Weiner <jweiner@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/vmscan.c')
-rw-r--r--mm/vmscan.c44
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 */
2167static 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 */
2186static bool shrink_zones(int priority, struct zonelist *zonelist, 2222static 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 }