diff options
Diffstat (limited to 'mm/compaction.c')
-rw-r--r-- | mm/compaction.c | 32 |
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 | */ |
1132 | unsigned long try_to_compact_pages(struct zonelist *zonelist, | 1132 | unsigned 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; |