summaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorMichal Hocko <mhocko@suse.com>2016-05-20 19:56:47 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-05-20 20:58:30 -0400
commitc8f7de0bfae36e8532e5e25a39d15407f02aca78 (patch)
tree9653d67af297d7e8f98e7367d2048d287dccbddd /mm
parent1d4746d395975e0ff5103e20ab169d1a95b4ef9e (diff)
mm, compaction: distinguish between full and partial COMPACT_COMPLETE
COMPACT_COMPLETE now means that compaction and free scanner met. This is not very useful information if somebody just wants to use this feedback and make any decisions based on that. The current caller might be a poor guy who just happened to scan tiny portion of the zone and that could be the reason no suitable pages were compacted. Make sure we distinguish the full and partial zone walks. Consumers should treat COMPACT_PARTIAL_SKIPPED as a potential success and be optimistic in retrying. The existing users of COMPACT_COMPLETE are conservatively changed to use COMPACT_PARTIAL_SKIPPED as well but some of them should be probably reconsidered and only defer the compaction only for COMPACT_COMPLETE with the new semantic. This patch shouldn't introduce any functional changes. Signed-off-by: Michal Hocko <mhocko@suse.com> Acked-by: Vlastimil Babka <vbabka@suse.cz> Acked-by: Hillf Danton <hillf.zj@alibaba-inc.com> Cc: David Rientjes <rientjes@google.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: Joonsoo Kim <js1304@gmail.com> Cc: Mel Gorman <mgorman@techsingularity.net> Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Cc: Vladimir Davydov <vdavydov@virtuozzo.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/compaction.c14
-rw-r--r--mm/internal.h1
2 files changed, 12 insertions, 3 deletions
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 */