summaryrefslogtreecommitdiffstats
path: root/mm/page_alloc.c
diff options
context:
space:
mode:
authorVlastimil Babka <vbabka@suse.cz>2016-10-07 20:00:31 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-10-07 21:46:28 -0400
commitd943649831aba0fcdda37a0e9e25b332a634cf5e (patch)
treedb3c779c262e057badc1dbff2004f45666e79a32 /mm/page_alloc.c
parent3250845d0526407330592dd43b9f1354b6fe7a14 (diff)
mm, compaction: more reliably increase direct compaction priority
During reclaim/compaction loop, compaction priority can be increased by the should_compact_retry() function, but the current code is not optimal. Priority is only increased when compaction_failed() is true, which means that compaction has scanned the whole zone. This may not happen even after multiple attempts with a lower priority due to parallel activity, so we might needlessly struggle on the lower priorities and possibly run out of compaction retry attempts in the process. After this patch we are guaranteed at least one attempt at the highest compaction priority even if we exhaust all retries at the lower priorities. Link: http://lkml.kernel.org/r/20160906135258.18335-3-vbabka@suse.cz Signed-off-by: Vlastimil Babka <vbabka@suse.cz> Cc: Michal Hocko <mhocko@kernel.org> Cc: Mel Gorman <mgorman@techsingularity.net> Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com> Cc: David Rientjes <rientjes@google.com> Cc: Rik van Riel <riel@redhat.com> Cc: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r--mm/page_alloc.c33
1 files changed, 19 insertions, 14 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 634806f55120..a8703b592c39 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -3160,25 +3160,23 @@ static inline bool
3160should_compact_retry(struct alloc_context *ac, int order, int alloc_flags, 3160should_compact_retry(struct alloc_context *ac, int order, int alloc_flags,
3161 enum compact_result compact_result, 3161 enum compact_result compact_result,
3162 enum compact_priority *compact_priority, 3162 enum compact_priority *compact_priority,
3163 int compaction_retries) 3163 int *compaction_retries)
3164{ 3164{
3165 int max_retries = MAX_COMPACT_RETRIES; 3165 int max_retries = MAX_COMPACT_RETRIES;
3166 3166
3167 if (!order) 3167 if (!order)
3168 return false; 3168 return false;
3169 3169
3170 if (compaction_made_progress(compact_result))
3171 (*compaction_retries)++;
3172
3170 /* 3173 /*
3171 * compaction considers all the zone as desperately out of memory 3174 * compaction considers all the zone as desperately out of memory
3172 * so it doesn't really make much sense to retry except when the 3175 * so it doesn't really make much sense to retry except when the
3173 * failure could be caused by insufficient priority 3176 * failure could be caused by insufficient priority
3174 */ 3177 */
3175 if (compaction_failed(compact_result)) { 3178 if (compaction_failed(compact_result))
3176 if (*compact_priority > MIN_COMPACT_PRIORITY) { 3179 goto check_priority;
3177 (*compact_priority)--;
3178 return true;
3179 }
3180 return false;
3181 }
3182 3180
3183 /* 3181 /*
3184 * make sure the compaction wasn't deferred or didn't bail out early 3182 * make sure the compaction wasn't deferred or didn't bail out early
@@ -3199,9 +3197,19 @@ should_compact_retry(struct alloc_context *ac, int order, int alloc_flags,
3199 */ 3197 */
3200 if (order > PAGE_ALLOC_COSTLY_ORDER) 3198 if (order > PAGE_ALLOC_COSTLY_ORDER)
3201 max_retries /= 4; 3199 max_retries /= 4;
3202 if (compaction_retries <= max_retries) 3200 if (*compaction_retries <= max_retries)
3203 return true; 3201 return true;
3204 3202
3203 /*
3204 * Make sure there are attempts at the highest priority if we exhausted
3205 * all retries or failed at the lower priorities.
3206 */
3207check_priority:
3208 if (*compact_priority > MIN_COMPACT_PRIORITY) {
3209 (*compact_priority)--;
3210 *compaction_retries = 0;
3211 return true;
3212 }
3205 return false; 3213 return false;
3206} 3214}
3207#else 3215#else
@@ -3218,7 +3226,7 @@ static inline bool
3218should_compact_retry(struct alloc_context *ac, unsigned int order, int alloc_flags, 3226should_compact_retry(struct alloc_context *ac, unsigned int order, int alloc_flags,
3219 enum compact_result compact_result, 3227 enum compact_result compact_result,
3220 enum compact_priority *compact_priority, 3228 enum compact_priority *compact_priority,
3221 int compaction_retries) 3229 int *compaction_retries)
3222{ 3230{
3223 struct zone *zone; 3231 struct zone *zone;
3224 struct zoneref *z; 3232 struct zoneref *z;
@@ -3620,9 +3628,6 @@ retry:
3620 if (page) 3628 if (page)
3621 goto got_pg; 3629 goto got_pg;
3622 3630
3623 if (order && compaction_made_progress(compact_result))
3624 compaction_retries++;
3625
3626 /* Do not loop if specifically requested */ 3631 /* Do not loop if specifically requested */
3627 if (gfp_mask & __GFP_NORETRY) 3632 if (gfp_mask & __GFP_NORETRY)
3628 goto nopage; 3633 goto nopage;
@@ -3657,7 +3662,7 @@ retry:
3657 if (did_some_progress > 0 && 3662 if (did_some_progress > 0 &&
3658 should_compact_retry(ac, order, alloc_flags, 3663 should_compact_retry(ac, order, alloc_flags,
3659 compact_result, &compact_priority, 3664 compact_result, &compact_priority,
3660 compaction_retries)) 3665 &compaction_retries))
3661 goto retry; 3666 goto retry;
3662 3667
3663 /* Reclaim has failed us, start killing things */ 3668 /* Reclaim has failed us, start killing things */