diff options
author | Vlastimil Babka <vbabka@suse.cz> | 2016-09-28 09:24:06 +1000 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2016-09-28 09:24:06 +1000 |
commit | 3196fc51e5a84df81bc074788c8ebb2f858bb1b5 (patch) | |
tree | f58dad7cbf44635d7c8a32e56202cb79a529f34a /mm | |
parent | dd007a654f144abe87b05ed1f55c5f9f4b6eb2ce (diff) |
mm, compaction: more reliably increase direct compaction priority-fix
When increasing the compaction priority, also reset retries. Otherwise we
can consume all retries on the lower priorities. Also pull the retries
increment into should_compact_retry() so it counts only the rounds where
we actually rely on it.
Suggested-by: Michal Hocko <mhocko@suse.com>
Link: http://lkml.kernel.org/r/20160926162025.21555-2-vbabka@suse.cz
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
Acked-by: Michal Hocko <mhocko@suse.com>
Acked-by: Hillf Danton <hillf.zj@alibaba-inc.com>
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>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/page_alloc.c | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 0c00350f8687..a8703b592c39 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -3160,13 +3160,16 @@ static inline bool should_compact_retry(struct alloc_context *ac, int order, int alloc_flags, enum compact_result compact_result, enum compact_priority *compact_priority, - int compaction_retries) + int *compaction_retries) { int max_retries = MAX_COMPACT_RETRIES; if (!order) return false; + if (compaction_made_progress(compact_result)) + (*compaction_retries)++; + /* * compaction considers all the zone as desperately out of memory * so it doesn't really make much sense to retry except when the @@ -3194,16 +3197,17 @@ should_compact_retry(struct alloc_context *ac, int order, int alloc_flags, */ if (order > PAGE_ALLOC_COSTLY_ORDER) max_retries /= 4; - if (compaction_retries <= max_retries) + if (*compaction_retries <= max_retries) return true; /* - * Make sure there is at least one attempt at the highest priority - * if we exhausted all retries at the lower priorities + * Make sure there are attempts at the highest priority if we exhausted + * all retries or failed at the lower priorities. */ check_priority: if (*compact_priority > MIN_COMPACT_PRIORITY) { (*compact_priority)--; + *compaction_retries = 0; return true; } return false; @@ -3222,7 +3226,7 @@ static inline bool should_compact_retry(struct alloc_context *ac, unsigned int order, int alloc_flags, enum compact_result compact_result, enum compact_priority *compact_priority, - int compaction_retries) + int *compaction_retries) { struct zone *zone; struct zoneref *z; @@ -3624,9 +3628,6 @@ retry: if (page) goto got_pg; - if (order && compaction_made_progress(compact_result)) - compaction_retries++; - /* Do not loop if specifically requested */ if (gfp_mask & __GFP_NORETRY) goto nopage; @@ -3661,7 +3662,7 @@ retry: if (did_some_progress > 0 && should_compact_retry(ac, order, alloc_flags, compact_result, &compact_priority, - compaction_retries)) + &compaction_retries)) goto retry; /* Reclaim has failed us, start killing things */ |