aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVlastimil Babka <vbabka@suse.cz>2016-10-07 20:00:37 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-10-07 21:46:29 -0400
commit9f7e3387939b036faacf4e7f32de7bb92a6635d6 (patch)
treef45ed33dd41fe1b5cea7b4b966d90ef79e9a8363
parentc2033b00dbe856909fcaccf038e4e0d3dcfb85af (diff)
mm, compaction: make full priority ignore pageblock suitability
Several people have reported premature OOMs for order-2 allocations (stack) due to OOM rework in 4.7. In the scenario (parallel kernel build and dd writing to two drives) many pageblocks get marked as Unmovable and compaction free scanner struggles to isolate free pages. Joonsoo Kim pointed out that the free scanner skips pageblocks that are not movable to prevent filling them and forcing non-movable allocations to fallback to other pageblocks. Such heuristic makes sense to help prevent long-term fragmentation, but premature OOMs are relatively more urgent problem. As a compromise, this patch disables the heuristic only for the ultimate compaction priority. Link: http://lkml.kernel.org/r/20160906135258.18335-5-vbabka@suse.cz Reported-by: Ralf-Peter Rohbeck <Ralf-Peter.Rohbeck@quantum.com> Reported-by: Arkadiusz Miskiewicz <a.miskiewicz@gmail.com> Reported-by: Olaf Hering <olaf@aepfle.de> Suggested-by: Joonsoo Kim <iamjoonsoo.kim@lge.com> Signed-off-by: Vlastimil Babka <vbabka@suse.cz> Acked-by: Michal Hocko <mhocko@suse.com> Cc: Michal Hocko <mhocko@kernel.org> Cc: Mel Gorman <mgorman@techsingularity.net> Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com> Cc: David Rientjes <rientjes@google.com> Cc: Rik van Riel <riel@redhat.com> Cc: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--mm/compaction.c11
-rw-r--r--mm/internal.h1
2 files changed, 9 insertions, 3 deletions
diff --git a/mm/compaction.c b/mm/compaction.c
index 29f6c49dc9c2..86d4d0bbfc7c 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -997,8 +997,12 @@ isolate_migratepages_range(struct compact_control *cc, unsigned long start_pfn,
997#ifdef CONFIG_COMPACTION 997#ifdef CONFIG_COMPACTION
998 998
999/* Returns true if the page is within a block suitable for migration to */ 999/* Returns true if the page is within a block suitable for migration to */
1000static bool suitable_migration_target(struct page *page) 1000static bool suitable_migration_target(struct compact_control *cc,
1001 struct page *page)
1001{ 1002{
1003 if (cc->ignore_block_suitable)
1004 return true;
1005
1002 /* If the page is a large free page, then disallow migration */ 1006 /* If the page is a large free page, then disallow migration */
1003 if (PageBuddy(page)) { 1007 if (PageBuddy(page)) {
1004 /* 1008 /*
@@ -1083,7 +1087,7 @@ static void isolate_freepages(struct compact_control *cc)
1083 continue; 1087 continue;
1084 1088
1085 /* Check the block is suitable for migration */ 1089 /* Check the block is suitable for migration */
1086 if (!suitable_migration_target(page)) 1090 if (!suitable_migration_target(cc, page))
1087 continue; 1091 continue;
1088 1092
1089 /* If isolation recently failed, do not retry */ 1093 /* If isolation recently failed, do not retry */
@@ -1656,7 +1660,8 @@ static enum compact_result compact_zone_order(struct zone *zone, int order,
1656 .classzone_idx = classzone_idx, 1660 .classzone_idx = classzone_idx,
1657 .direct_compaction = true, 1661 .direct_compaction = true,
1658 .whole_zone = (prio == MIN_COMPACT_PRIORITY), 1662 .whole_zone = (prio == MIN_COMPACT_PRIORITY),
1659 .ignore_skip_hint = (prio == MIN_COMPACT_PRIORITY) 1663 .ignore_skip_hint = (prio == MIN_COMPACT_PRIORITY),
1664 .ignore_block_suitable = (prio == MIN_COMPACT_PRIORITY)
1660 }; 1665 };
1661 INIT_LIST_HEAD(&cc.freepages); 1666 INIT_LIST_HEAD(&cc.freepages);
1662 INIT_LIST_HEAD(&cc.migratepages); 1667 INIT_LIST_HEAD(&cc.migratepages);
diff --git a/mm/internal.h b/mm/internal.h
index 5214bf8e3171..537ac9951f5f 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -178,6 +178,7 @@ struct compact_control {
178 unsigned long last_migrated_pfn;/* Not yet flushed page being freed */ 178 unsigned long last_migrated_pfn;/* Not yet flushed page being freed */
179 enum migrate_mode mode; /* Async or sync migration mode */ 179 enum migrate_mode mode; /* Async or sync migration mode */
180 bool ignore_skip_hint; /* Scan blocks even if marked skip */ 180 bool ignore_skip_hint; /* Scan blocks even if marked skip */
181 bool ignore_block_suitable; /* Scan blocks considered unsuitable */
181 bool direct_compaction; /* False from kcompactd or /proc/... */ 182 bool direct_compaction; /* False from kcompactd or /proc/... */
182 bool whole_zone; /* Whole zone should/has been scanned */ 183 bool whole_zone; /* Whole zone should/has been scanned */
183 int order; /* order a direct compactor needs */ 184 int order; /* order a direct compactor needs */