summaryrefslogtreecommitdiffstats
path: root/mm/compaction.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/compaction.c')
-rw-r--r--mm/compaction.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/mm/compaction.c b/mm/compaction.c
index 21bf292b642a..1c7195d42e83 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -1125,27 +1125,26 @@ int sysctl_extfrag_threshold = 500;
1125 * @nodemask: The allowed nodes to allocate from 1125 * @nodemask: The allowed nodes to allocate from
1126 * @mode: The migration mode for async, sync light, or sync migration 1126 * @mode: The migration mode for async, sync light, or sync migration
1127 * @contended: Return value that is true if compaction was aborted due to lock contention 1127 * @contended: Return value that is true if compaction was aborted due to lock contention
1128 * @page: Optionally capture a free page of the requested order during compaction 1128 * @candidate_zone: Return the zone where we think allocation should succeed
1129 * 1129 *
1130 * This is the main entry point for direct page compaction. 1130 * This is the main entry point for direct page compaction.
1131 */ 1131 */
1132unsigned long try_to_compact_pages(struct zonelist *zonelist, 1132unsigned long try_to_compact_pages(struct zonelist *zonelist,
1133 int order, gfp_t gfp_mask, nodemask_t *nodemask, 1133 int order, gfp_t gfp_mask, nodemask_t *nodemask,
1134 enum migrate_mode mode, bool *contended) 1134 enum migrate_mode mode, bool *contended,
1135 struct zone **candidate_zone)
1135{ 1136{
1136 enum zone_type high_zoneidx = gfp_zone(gfp_mask); 1137 enum zone_type high_zoneidx = gfp_zone(gfp_mask);
1137 int may_enter_fs = gfp_mask & __GFP_FS; 1138 int may_enter_fs = gfp_mask & __GFP_FS;
1138 int may_perform_io = gfp_mask & __GFP_IO; 1139 int may_perform_io = gfp_mask & __GFP_IO;
1139 struct zoneref *z; 1140 struct zoneref *z;
1140 struct zone *zone; 1141 struct zone *zone;
1141 int rc = COMPACT_SKIPPED; 1142 int rc = COMPACT_DEFERRED;
1142 int alloc_flags = 0; 1143 int alloc_flags = 0;
1143 1144
1144 /* Check if the GFP flags allow compaction */ 1145 /* Check if the GFP flags allow compaction */
1145 if (!order || !may_enter_fs || !may_perform_io) 1146 if (!order || !may_enter_fs || !may_perform_io)
1146 return rc; 1147 return COMPACT_SKIPPED;
1147
1148 count_compact_event(COMPACTSTALL);
1149 1148
1150#ifdef CONFIG_CMA 1149#ifdef CONFIG_CMA
1151 if (allocflags_to_migratetype(gfp_mask) == MIGRATE_MOVABLE) 1150 if (allocflags_to_migratetype(gfp_mask) == MIGRATE_MOVABLE)
@@ -1156,14 +1155,33 @@ unsigned long try_to_compact_pages(struct zonelist *zonelist,
1156 nodemask) { 1155 nodemask) {
1157 int status; 1156 int status;
1158 1157
1158 if (compaction_deferred(zone, order))
1159 continue;
1160
1159 status = compact_zone_order(zone, order, gfp_mask, mode, 1161 status = compact_zone_order(zone, order, gfp_mask, mode,
1160 contended); 1162 contended);
1161 rc = max(status, rc); 1163 rc = max(status, rc);
1162 1164
1163 /* If a normal allocation would succeed, stop compacting */ 1165 /* If a normal allocation would succeed, stop compacting */
1164 if (zone_watermark_ok(zone, order, low_wmark_pages(zone), 0, 1166 if (zone_watermark_ok(zone, order, low_wmark_pages(zone), 0,
1165 alloc_flags)) 1167 alloc_flags)) {
1168 *candidate_zone = zone;
1169 /*
1170 * We think the allocation will succeed in this zone,
1171 * but it is not certain, hence the false. The caller
1172 * will repeat this with true if allocation indeed
1173 * succeeds in this zone.
1174 */
1175 compaction_defer_reset(zone, order, false);
1166 break; 1176 break;
1177 } else if (mode != MIGRATE_ASYNC) {
1178 /*
1179 * We think that allocation won't succeed in this zone
1180 * so we defer compaction there. If it ends up
1181 * succeeding after all, it will be reset.
1182 */
1183 defer_compaction(zone, order);
1184 }
1167 } 1185 }
1168 1186
1169 return rc; 1187 return rc;