The patch titled mm: compaction: defer compaction using an exponential backoff has been added to the -mm tree. Its filename is mm-compaction-do-not-display-compaction-related-stats-when-config_co-mpaction-reject-fixpatch-added-to-mm-tree.patch Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/SubmitChecklist when testing your code *** See http://userweb.kernel.org/~akpm/stuff/added-to-mm.txt to find out what to do about this The current -mm tree may be found at http://userweb.kernel.org/~akpm/mmotm/ ------------------------------------------------------ Subject: mm: compaction: defer compaction using an exponential backoff From: Mel Gorman <mel@xxxxxxxxx> The fragmentation index may indicate that a failure is due to external fragmentation but after a compaction run completes, it is still possible for an allocation to fail. There are two obvious reasons as to why o Page migration cannot move all pages so fragmentation remains o A suitable page may exist but watermarks are not met In the event of compaction followed by an allocation failure, this patch defers further compaction in the zone (1 << compact_defer_shift) times. If the next compaction attempt also fails, compact_defer_shift is increased up to a maximum of 6. If compaction succeeds, the defer counters are reset again. The zone that is deferred is the first zone in the zonelist - i.e. the preferred zone. To defer compaction in the other zones, the information would need to be stored in the zonelist or implemented similar to the zonelist_cache. This would impact the fast-paths and is not justified at this time. Signed-off-by: Mel Gorman <mel@xxxxxxxxx> Cc: Andrea Arcangeli <aarcange@xxxxxxxxxx> Cc: Christoph Lameter <cl@xxxxxxxxxxxxxxxxxxxx> Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@xxxxxxxxxxxxxx> Cc: KOSAKI Motohiro <kosaki.motohiro@xxxxxxxxxxxxxx> Cc: Minchan Kim <minchan.kim@xxxxxxxxx> Cc: Rik van Riel <riel@xxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- include/linux/compaction.h | 39 +++++++++++++++++++++++++++++++++++ include/linux/mmzone.h | 9 ++++++++ mm/page_alloc.c | 5 +++- 3 files changed, 52 insertions(+), 1 deletion(-) diff -puN include/linux/compaction.h~mm-compaction-do-not-display-compaction-related-stats-when-config_co-mpaction-reject-fixpatch-added-to-mm-tree include/linux/compaction.h --- a/include/linux/compaction.h~mm-compaction-do-not-display-compaction-related-stats-when-config_co-mpaction-reject-fixpatch-added-to-mm-tree +++ a/include/linux/compaction.h @@ -18,6 +18,36 @@ extern int sysctl_extfrag_handler(struct extern int fragmentation_index(struct zone *zone, unsigned int order); extern unsigned long try_to_compact_pages(struct zonelist *zonelist, int order, gfp_t gfp_mask, nodemask_t *mask); + +/* Do not skip compaction more than 64 times */ +#define COMPACT_MAX_DEFER_SHIFT 6 + +/* + * Compaction is deferred when compaction fails to result in a page + * allocation success. 1 << compact_defer_limit compactions are skipped up + * to a limit of 1 << COMPACT_MAX_DEFER_SHIFT + */ +static inline void defer_compaction(struct zone *zone) +{ + zone->compact_considered = 0; + zone->compact_defer_shift++; + + if (zone->compact_defer_shift > COMPACT_MAX_DEFER_SHIFT) + zone->compact_defer_shift = COMPACT_MAX_DEFER_SHIFT; +} + +/* Returns true if compaction should be skipped this time */ +static inline bool compaction_deferred(struct zone *zone) +{ + unsigned long defer_limit = 1UL << zone->compact_defer_shift; + + /* Avoid possible overflow */ + if (++zone->compact_considered > defer_limit) + zone->compact_considered = defer_limit; + + return zone->compact_considered < (1UL << zone->compact_defer_shift); +} + #else static inline unsigned long try_to_compact_pages(struct zonelist *zonelist, int order, gfp_t gfp_mask, nodemask_t *nodemask) @@ -25,6 +55,15 @@ static inline unsigned long try_to_compa return COMPACT_INCOMPLETE; } +static inline void defer_compaction(struct zone *zone) +{ +} + +static inline bool compaction_deferred(struct zone *zone) +{ + return 1; +} + #endif /* CONFIG_COMPACTION */ #if defined(CONFIG_COMPACTION) && defined(CONFIG_SYSFS) && defined(CONFIG_NUMA) diff -puN include/linux/mmzone.h~mm-compaction-do-not-display-compaction-related-stats-when-config_co-mpaction-reject-fixpatch-added-to-mm-tree include/linux/mmzone.h --- a/include/linux/mmzone.h~mm-compaction-do-not-display-compaction-related-stats-when-config_co-mpaction-reject-fixpatch-added-to-mm-tree +++ a/include/linux/mmzone.h @@ -321,6 +321,15 @@ struct zone { unsigned long *pageblock_flags; #endif /* CONFIG_SPARSEMEM */ +#ifdef CONFIG_COMPACTION + /* + * On compaction failure, 1<<compact_defer_shift compactions + * are skipped before trying again. The number attempted since + * last failure is tracked with compact_considered. + */ + unsigned int compact_considered; + unsigned int compact_defer_shift; +#endif ZONE_PADDING(_pad1_) diff -puN mm/page_alloc.c~mm-compaction-do-not-display-compaction-related-stats-when-config_co-mpaction-reject-fixpatch-added-to-mm-tree mm/page_alloc.c --- a/mm/page_alloc.c~mm-compaction-do-not-display-compaction-related-stats-when-config_co-mpaction-reject-fixpatch-added-to-mm-tree +++ a/mm/page_alloc.c @@ -1766,7 +1766,7 @@ __alloc_pages_direct_compact(gfp_t gfp_m { struct page *page; - if (!order) + if (!order || compaction_deferred(preferred_zone)) return NULL; *did_some_progress = try_to_compact_pages(zonelist, order, gfp_mask, @@ -1782,6 +1782,8 @@ __alloc_pages_direct_compact(gfp_t gfp_m alloc_flags, preferred_zone, migratetype); if (page) { + preferred_zone->compact_considered = 0; + preferred_zone->compact_defer_shift = 0; __count_vm_event(COMPACTSUCCESS); return page; } @@ -1792,6 +1794,7 @@ __alloc_pages_direct_compact(gfp_t gfp_m * but not enough to satisfy watermarks. */ count_vm_event(COMPACTFAIL); + defer_compaction(preferred_zone); cond_resched(); } _ Patches currently in -mm which might be from mel@xxxxxxxxx are linux-next.patch page-allocator-reduce-fragmentation-in-buddy-allocator-by-adding-buddies-that-are-merging-to-the-tail-of-the-free-lists.patch mempolicy-remove-redundant-code.patch mm-default-to-node-zonelist-ordering-when-nodes-have-only-lowmem.patch mm-migration-take-a-reference-to-the-anon_vma-before-migrating.patch mm-migration-do-not-try-to-migrate-unmapped-anonymous-pages.patch mm-share-the-anon_vma-ref-counts-between-ksm-and-page-migration.patch mm-allow-config_migration-to-be-set-without-config_numa-or-memory-hot-remove.patch mm-allow-config_migration-to-be-set-without-config_numa-or-memory-hot-remove-fix.patch mm-export-unusable-free-space-index-via-proc-unusable_index.patch mm-export-unusable-free-space-index-via-proc-unusable_index-fix.patch mm-export-unusable-free-space-index-via-proc-unusable_index-fix-fix-2.patch mm-export-fragmentation-index-via-proc-extfrag_index.patch mm-export-fragmentation-index-via-proc-extfrag_index-fix.patch mm-move-definition-for-lru-isolation-modes-to-a-header.patch mm-compaction-memory-compaction-core.patch mm-compaction-memory-compaction-core-fix.patch mm-compaction-memory-compaction-core-fix-page-buddy-can-go-away-before-reading-page_order-while-isolating-pages-for-migration.patch mm-compaction-add-proc-trigger-for-memory-compaction.patch mm-compaction-add-proc-trigger-for-memory-compaction-fix.patch mm-compaction-add-proc-trigger-for-memory-compaction-fix-fix.patch mm-compaction-add-sys-trigger-for-per-node-memory-compaction.patch mm-compaction-direct-compact-when-a-high-order-allocation-fails.patch mm-compaction-direct-compact-when-a-high-order-allocation-fails-reject-fix.patch mm-compaction-add-a-tunable-that-decides-when-memory-should-be-compacted-and-when-it-should-be-reclaimed.patch mm-migration-allow-the-migration-of-pageswapcache-pages.patch mm-migration-allow-the-migration-of-pageswapcache-pages-fix.patch mm-compaction-do-not-display-compaction-related-stats-when-config_compaction.patch mm-compaction-do-not-display-compaction-related-stats-when-config_compaction-fix.patch mm-compaction-do-not-display-compaction-related-stats-when-config_compaction-fix-fix-2.patch mm-compaction-do-not-display-compaction-related-stats-when-config_compaction-fix-fix-2-do-not-compact-twice.patch mm-compaction-do-not-display-compaction-related-stats-when-config_co-mpaction-reject-fixpatch-added-to-mm-tree.patch mm-remove-nodes-validity-check-in-alloc_pages.patch mm-change-alloc-function-in-vmemmap_alloc_block.patch mm-change-alloc-function-in-__vmalloc_area_node.patch mm-add-comment-in-alloc_pages_exact_node.patch delay-accounting-re-implement-c-for-getdelaysc-to-report-information-on-a-target-command.patch delay-accounting-re-implement-c-for-getdelaysc-to-report-information-on-a-target-command-checkpatch-fixes.patch add-debugging-aid-for-memory-initialisation-problems.patch -- To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html