aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
Diffstat (limited to 'mm')
-rw-r--r--mm/compaction.c42
-rw-r--r--mm/page_alloc.c23
2 files changed, 52 insertions, 13 deletions
diff --git a/mm/compaction.c b/mm/compaction.c
index 4af1577adb5c..d8a20fcf8678 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -1318,7 +1318,8 @@ static enum compact_result compact_finished(struct zone *zone,
1318 */ 1318 */
1319static enum compact_result __compaction_suitable(struct zone *zone, int order, 1319static enum compact_result __compaction_suitable(struct zone *zone, int order,
1320 unsigned int alloc_flags, 1320 unsigned int alloc_flags,
1321 int classzone_idx) 1321 int classzone_idx,
1322 unsigned long wmark_target)
1322{ 1323{
1323 int fragindex; 1324 int fragindex;
1324 unsigned long watermark; 1325 unsigned long watermark;
@@ -1341,7 +1342,8 @@ static enum compact_result __compaction_suitable(struct zone *zone, int order,
1341 * allocated and for a short time, the footprint is higher 1342 * allocated and for a short time, the footprint is higher
1342 */ 1343 */
1343 watermark += (2UL << order); 1344 watermark += (2UL << order);
1344 if (!zone_watermark_ok(zone, 0, watermark, classzone_idx, alloc_flags)) 1345 if (!__zone_watermark_ok(zone, 0, watermark, classzone_idx,
1346 alloc_flags, wmark_target))
1345 return COMPACT_SKIPPED; 1347 return COMPACT_SKIPPED;
1346 1348
1347 /* 1349 /*
@@ -1368,7 +1370,8 @@ enum compact_result compaction_suitable(struct zone *zone, int order,
1368{ 1370{
1369 enum compact_result ret; 1371 enum compact_result ret;
1370 1372
1371 ret = __compaction_suitable(zone, order, alloc_flags, classzone_idx); 1373 ret = __compaction_suitable(zone, order, alloc_flags, classzone_idx,
1374 zone_page_state(zone, NR_FREE_PAGES));
1372 trace_mm_compaction_suitable(zone, order, ret); 1375 trace_mm_compaction_suitable(zone, order, ret);
1373 if (ret == COMPACT_NOT_SUITABLE_ZONE) 1376 if (ret == COMPACT_NOT_SUITABLE_ZONE)
1374 ret = COMPACT_SKIPPED; 1377 ret = COMPACT_SKIPPED;
@@ -1376,6 +1379,39 @@ enum compact_result compaction_suitable(struct zone *zone, int order,
1376 return ret; 1379 return ret;
1377} 1380}
1378 1381
1382bool compaction_zonelist_suitable(struct alloc_context *ac, int order,
1383 int alloc_flags)
1384{
1385 struct zone *zone;
1386 struct zoneref *z;
1387
1388 /*
1389 * Make sure at least one zone would pass __compaction_suitable if we continue
1390 * retrying the reclaim.
1391 */
1392 for_each_zone_zonelist_nodemask(zone, z, ac->zonelist, ac->high_zoneidx,
1393 ac->nodemask) {
1394 unsigned long available;
1395 enum compact_result compact_result;
1396
1397 /*
1398 * Do not consider all the reclaimable memory because we do not
1399 * want to trash just for a single high order allocation which
1400 * is even not guaranteed to appear even if __compaction_suitable
1401 * is happy about the watermark check.
1402 */
1403 available = zone_reclaimable_pages(zone) / order;
1404 available += zone_page_state_snapshot(zone, NR_FREE_PAGES);
1405 compact_result = __compaction_suitable(zone, order, alloc_flags,
1406 ac_classzone_idx(ac), available);
1407 if (compact_result != COMPACT_SKIPPED &&
1408 compact_result != COMPACT_NOT_SUITABLE_ZONE)
1409 return true;
1410 }
1411
1412 return false;
1413}
1414
1379static enum compact_result compact_zone(struct zone *zone, struct compact_control *cc) 1415static enum compact_result compact_zone(struct zone *zone, struct compact_control *cc)
1380{ 1416{
1381 enum compact_result ret; 1417 enum compact_result ret;
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index dea406a62e3d..089f760ce64a 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2750,10 +2750,9 @@ static inline bool should_fail_alloc_page(gfp_t gfp_mask, unsigned int order)
2750 * one free page of a suitable size. Checking now avoids taking the zone lock 2750 * one free page of a suitable size. Checking now avoids taking the zone lock
2751 * to check in the allocation paths if no pages are free. 2751 * to check in the allocation paths if no pages are free.
2752 */ 2752 */
2753static bool __zone_watermark_ok(struct zone *z, unsigned int order, 2753bool __zone_watermark_ok(struct zone *z, unsigned int order, unsigned long mark,
2754 unsigned long mark, int classzone_idx, 2754 int classzone_idx, unsigned int alloc_flags,
2755 unsigned int alloc_flags, 2755 long free_pages)
2756 long free_pages)
2757{ 2756{
2758 long min = mark; 2757 long min = mark;
2759 int o; 2758 int o;
@@ -3256,8 +3255,8 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order,
3256} 3255}
3257 3256
3258static inline bool 3257static inline bool
3259should_compact_retry(unsigned int order, enum compact_result compact_result, 3258should_compact_retry(struct alloc_context *ac, int order, int alloc_flags,
3260 enum migrate_mode *migrate_mode, 3259 enum compact_result compact_result, enum migrate_mode *migrate_mode,
3261 int compaction_retries) 3260 int compaction_retries)
3262{ 3261{
3263 int max_retries = MAX_COMPACT_RETRIES; 3262 int max_retries = MAX_COMPACT_RETRIES;
@@ -3281,9 +3280,11 @@ should_compact_retry(unsigned int order, enum compact_result compact_result,
3281 /* 3280 /*
3282 * make sure the compaction wasn't deferred or didn't bail out early 3281 * make sure the compaction wasn't deferred or didn't bail out early
3283 * due to locks contention before we declare that we should give up. 3282 * due to locks contention before we declare that we should give up.
3283 * But do not retry if the given zonelist is not suitable for
3284 * compaction.
3284 */ 3285 */
3285 if (compaction_withdrawn(compact_result)) 3286 if (compaction_withdrawn(compact_result))
3286 return true; 3287 return compaction_zonelist_suitable(ac, order, alloc_flags);
3287 3288
3288 /* 3289 /*
3289 * !costly requests are much more important than __GFP_REPEAT 3290 * !costly requests are much more important than __GFP_REPEAT
@@ -3311,7 +3312,8 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order,
3311} 3312}
3312 3313
3313static inline bool 3314static inline bool
3314should_compact_retry(unsigned int order, enum compact_result compact_result, 3315should_compact_retry(struct alloc_context *ac, unsigned int order, int alloc_flags,
3316 enum compact_result compact_result,
3315 enum migrate_mode *migrate_mode, 3317 enum migrate_mode *migrate_mode,
3316 int compaction_retries) 3318 int compaction_retries)
3317{ 3319{
@@ -3706,8 +3708,9 @@ retry:
3706 * of free memory (see __compaction_suitable) 3708 * of free memory (see __compaction_suitable)
3707 */ 3709 */
3708 if (did_some_progress > 0 && 3710 if (did_some_progress > 0 &&
3709 should_compact_retry(order, compact_result, 3711 should_compact_retry(ac, order, alloc_flags,
3710 &migration_mode, compaction_retries)) 3712 compact_result, &migration_mode,
3713 compaction_retries))
3711 goto retry; 3714 goto retry;
3712 3715
3713 /* Reclaim has failed us, start killing things */ 3716 /* Reclaim has failed us, start killing things */