aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
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
* failure could be caused by insufficient priority
*/
- if (compaction_failed(compact_result)) {
- if (*compact_priority > MIN_COMPACT_PRIORITY) {
- (*compact_priority)--;
- return true;
- }
- return false;
- }
+ if (compaction_failed(compact_result))
+ goto check_priority;
/*
* 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,
*/
if (order > PAGE_ALLOC_COSTLY_ORDER)
max_retries /= 4;
- if (compaction_retries <= max_retries)
+ if (*compaction_retries <= max_retries)
return true;
+ /*
+ * 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;
}
#else
@@ -3218,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;
@@ -3620,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;
@@ -3657,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 */