aboutsummaryrefslogtreecommitdiffstats
path: root/mm/compaction.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/compaction.c')
-rw-r--r--mm/compaction.c42
1 files changed, 39 insertions, 3 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;