mm, compaction: add the ultimate direct compaction priority
authorVlastimil Babka <vbabka@suse.cz>
Sat, 10 Sep 2016 10:34:05 +0000 (20:34 +1000)
committerStephen Rothwell <sfr@canb.auug.org.au>
Sat, 10 Sep 2016 10:34:05 +0000 (20:34 +1000)
During reclaim/compaction loop, it's desirable to get a final answer from
unsuccessful compaction so we can either fail the allocation or invoke the
OOM killer.  However, heuristics such as deferred compaction or pageblock
skip bits can cause compaction to skip parts or whole zones and lead to
premature OOM's, failures or excessive reclaim/compaction retries.

To remedy this, we introduce a new direct compaction priority called
COMPACT_PRIO_SYNC_FULL, which instructs direct compaction to:

- ignore deferred compaction status for a zone
- ignore pageblock skip hints
- ignore cached scanner positions and scan the whole zone

The new priority should get eventually picked up by should_compact_retry()
and this should improve success rates for costly allocations using
__GFP_REPEAT, such as hugetlbfs allocations, and reduce some corner-case
OOM's for non-costly allocations.

Link: http://lkml.kernel.org/r/20160810091226.6709-6-vbabka@suse.cz
Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
Acked-by: Michal Hocko <mhocko@suse.com>
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>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
include/linux/compaction.h
mm/compaction.c

index e88c037afe47bad99854880bbf6e406817907c08..a1fba999472812d0240d5cef58bbed9e0e1d475e 100644 (file)
@@ -6,8 +6,9 @@
  * Lower value means higher priority, analogically to reclaim priority.
  */
 enum compact_priority {
+       COMPACT_PRIO_SYNC_FULL,
+       MIN_COMPACT_PRIORITY = COMPACT_PRIO_SYNC_FULL,
        COMPACT_PRIO_SYNC_LIGHT,
-       MIN_COMPACT_PRIORITY = COMPACT_PRIO_SYNC_LIGHT,
        DEF_COMPACT_PRIORITY = COMPACT_PRIO_SYNC_LIGHT,
        COMPACT_PRIO_ASYNC,
        INIT_COMPACT_PRIORITY = COMPACT_PRIO_ASYNC
index 2e1113ff7a0384a52903a3574985fa794a114683..342fa9e3127a4ee1733e73bcf3c1062e71643610 100644 (file)
@@ -1644,6 +1644,8 @@ static enum compact_result compact_zone_order(struct zone *zone, int order,
                .alloc_flags = alloc_flags,
                .classzone_idx = classzone_idx,
                .direct_compaction = true,
+               .whole_zone = (prio == COMPACT_PRIO_SYNC_FULL),
+               .ignore_skip_hint = (prio == COMPACT_PRIO_SYNC_FULL)
        };
        INIT_LIST_HEAD(&cc.freepages);
        INIT_LIST_HEAD(&cc.migratepages);
@@ -1689,7 +1691,8 @@ enum compact_result try_to_compact_pages(gfp_t gfp_mask, unsigned int order,
                                                                ac->nodemask) {
                enum compact_result status;
 
-               if (compaction_deferred(zone, order)) {
+               if (prio > COMPACT_PRIO_SYNC_FULL
+                                       && compaction_deferred(zone, order)) {
                        rc = max_t(enum compact_result, COMPACT_DEFERRED, rc);
                        continue;
                }
This page took 0.029322 seconds and 5 git commands to generate.