diff options
-rw-r--r-- | include/linux/compaction.h | 10 | ||||
-rw-r--r-- | include/trace/events/compaction.h | 1 | ||||
-rw-r--r-- | mm/compaction.c | 14 | ||||
-rw-r--r-- | mm/internal.h | 1 |
4 files changed, 22 insertions, 4 deletions
diff --git a/include/linux/compaction.h b/include/linux/compaction.h index 11f228712ed5..9b37f9d3f7a8 100644 --- a/include/linux/compaction.h +++ b/include/linux/compaction.h | |||
@@ -21,7 +21,15 @@ enum compact_result { | |||
21 | * pages | 21 | * pages |
22 | */ | 22 | */ |
23 | COMPACT_PARTIAL, | 23 | COMPACT_PARTIAL, |
24 | /* The full zone was compacted */ | 24 | /* |
25 | * direct compaction has scanned part of the zone but wasn't successfull | ||
26 | * to compact suitable pages. | ||
27 | */ | ||
28 | COMPACT_PARTIAL_SKIPPED, | ||
29 | /* | ||
30 | * The full zone was compacted scanned but wasn't successfull to compact | ||
31 | * suitable pages. | ||
32 | */ | ||
25 | COMPACT_COMPLETE, | 33 | COMPACT_COMPLETE, |
26 | /* For more detailed tracepoint output */ | 34 | /* For more detailed tracepoint output */ |
27 | COMPACT_NO_SUITABLE_PAGE, | 35 | COMPACT_NO_SUITABLE_PAGE, |
diff --git a/include/trace/events/compaction.h b/include/trace/events/compaction.h index 6ba16c86d7db..36e2d6fb1360 100644 --- a/include/trace/events/compaction.h +++ b/include/trace/events/compaction.h | |||
@@ -14,6 +14,7 @@ | |||
14 | EM( COMPACT_DEFERRED, "deferred") \ | 14 | EM( COMPACT_DEFERRED, "deferred") \ |
15 | EM( COMPACT_CONTINUE, "continue") \ | 15 | EM( COMPACT_CONTINUE, "continue") \ |
16 | EM( COMPACT_PARTIAL, "partial") \ | 16 | EM( COMPACT_PARTIAL, "partial") \ |
17 | EM( COMPACT_PARTIAL_SKIPPED, "partial_skipped") \ | ||
17 | EM( COMPACT_COMPLETE, "complete") \ | 18 | EM( COMPACT_COMPLETE, "complete") \ |
18 | EM( COMPACT_NO_SUITABLE_PAGE, "no_suitable_page") \ | 19 | EM( COMPACT_NO_SUITABLE_PAGE, "no_suitable_page") \ |
19 | EM( COMPACT_NOT_SUITABLE_ZONE, "not_suitable_zone") \ | 20 | EM( COMPACT_NOT_SUITABLE_ZONE, "not_suitable_zone") \ |
diff --git a/mm/compaction.c b/mm/compaction.c index b2b94474dd28..4af1577adb5c 100644 --- a/mm/compaction.c +++ b/mm/compaction.c | |||
@@ -1252,7 +1252,10 @@ static enum compact_result __compact_finished(struct zone *zone, struct compact_ | |||
1252 | if (cc->direct_compaction) | 1252 | if (cc->direct_compaction) |
1253 | zone->compact_blockskip_flush = true; | 1253 | zone->compact_blockskip_flush = true; |
1254 | 1254 | ||
1255 | return COMPACT_COMPLETE; | 1255 | if (cc->whole_zone) |
1256 | return COMPACT_COMPLETE; | ||
1257 | else | ||
1258 | return COMPACT_PARTIAL_SKIPPED; | ||
1256 | } | 1259 | } |
1257 | 1260 | ||
1258 | if (is_via_compact_memory(cc->order)) | 1261 | if (is_via_compact_memory(cc->order)) |
@@ -1413,6 +1416,10 @@ static enum compact_result compact_zone(struct zone *zone, struct compact_contro | |||
1413 | zone->compact_cached_migrate_pfn[0] = cc->migrate_pfn; | 1416 | zone->compact_cached_migrate_pfn[0] = cc->migrate_pfn; |
1414 | zone->compact_cached_migrate_pfn[1] = cc->migrate_pfn; | 1417 | zone->compact_cached_migrate_pfn[1] = cc->migrate_pfn; |
1415 | } | 1418 | } |
1419 | |||
1420 | if (cc->migrate_pfn == start_pfn) | ||
1421 | cc->whole_zone = true; | ||
1422 | |||
1416 | cc->last_migrated_pfn = 0; | 1423 | cc->last_migrated_pfn = 0; |
1417 | 1424 | ||
1418 | trace_mm_compaction_begin(start_pfn, cc->migrate_pfn, | 1425 | trace_mm_compaction_begin(start_pfn, cc->migrate_pfn, |
@@ -1634,7 +1641,8 @@ enum compact_result try_to_compact_pages(gfp_t gfp_mask, unsigned int order, | |||
1634 | goto break_loop; | 1641 | goto break_loop; |
1635 | } | 1642 | } |
1636 | 1643 | ||
1637 | if (mode != MIGRATE_ASYNC && status == COMPACT_COMPLETE) { | 1644 | if (mode != MIGRATE_ASYNC && (status == COMPACT_COMPLETE || |
1645 | status == COMPACT_PARTIAL_SKIPPED)) { | ||
1638 | /* | 1646 | /* |
1639 | * We think that allocation won't succeed in this zone | 1647 | * We think that allocation won't succeed in this zone |
1640 | * so we defer compaction there. If it ends up | 1648 | * so we defer compaction there. If it ends up |
@@ -1881,7 +1889,7 @@ static void kcompactd_do_work(pg_data_t *pgdat) | |||
1881 | cc.classzone_idx, 0)) { | 1889 | cc.classzone_idx, 0)) { |
1882 | success = true; | 1890 | success = true; |
1883 | compaction_defer_reset(zone, cc.order, false); | 1891 | compaction_defer_reset(zone, cc.order, false); |
1884 | } else if (status == COMPACT_COMPLETE) { | 1892 | } else if (status == COMPACT_PARTIAL_SKIPPED || status == COMPACT_COMPLETE) { |
1885 | /* | 1893 | /* |
1886 | * We use sync migration mode here, so we defer like | 1894 | * We use sync migration mode here, so we defer like |
1887 | * sync direct compaction does. | 1895 | * sync direct compaction does. |
diff --git a/mm/internal.h b/mm/internal.h index 3ac544f1963f..f6f3353b0868 100644 --- a/mm/internal.h +++ b/mm/internal.h | |||
@@ -174,6 +174,7 @@ struct compact_control { | |||
174 | enum migrate_mode mode; /* Async or sync migration mode */ | 174 | enum migrate_mode mode; /* Async or sync migration mode */ |
175 | bool ignore_skip_hint; /* Scan blocks even if marked skip */ | 175 | bool ignore_skip_hint; /* Scan blocks even if marked skip */ |
176 | bool direct_compaction; /* False from kcompactd or /proc/... */ | 176 | bool direct_compaction; /* False from kcompactd or /proc/... */ |
177 | bool whole_zone; /* Whole zone has been scanned */ | ||
177 | int order; /* order a direct compactor needs */ | 178 | int order; /* order a direct compactor needs */ |
178 | const gfp_t gfp_mask; /* gfp mask of a direct compactor */ | 179 | const gfp_t gfp_mask; /* gfp mask of a direct compactor */ |
179 | const unsigned int alloc_flags; /* alloc flags of a direct compactor */ | 180 | const unsigned int alloc_flags; /* alloc flags of a direct compactor */ |