Re: [RFC PATCH 3/3] mm/compaction: respect compact_unevictable_allowed in alloc_contig path
From: "Vlastimil Babka (SUSE)" <vbabka@kernel.org>
Date: 2026-06-17 18:57:36
Also in:
linux-mm, linux-rt-devel, lkml
On 6/4/26 04:38, Wandun Chen wrote:
From: Wandun Chen <redacted> vm.compact_unevictable_allowed=0 is used to prevent compacting unevictable pages. However, isolate_migratepages_range() passes ISOLATE_UNEVICTABLE regardless of this sysctl, so the setting has no effect in the alloc_contig path. Fix it by: - Keep ISOLATE_UNEVICTABLE for CMA allocation, discussed in [1]. - Honour sysctl_compact_unevictable_allowed for non-CMA allocation. Suggested-by: Vlastimil Babka <redacted> Signed-off-by: Wandun Chen <redacted> Link: https://lore.kernel.org/all/25ba0d77-eb61-4efc-b2fc-73878cbd85c1@suse.cz/ (local) [1]
There was also the "Ideally by not having mlock'd pages in CMA areas at all." part. Is it the case? It was more elaborated here: https://lore.kernel.org/all/CAPTztWZpnX1j8-7yeppVUsxE=O9hbVeqricDjZt8_pnN7a-kBQ@mail.gmail.com/ (local)
quoted hunk ↗ jump to hunk
--- include/linux/compaction.h | 6 ++++++ mm/compaction.c | 9 +++++++-- mm/internal.h | 1 + mm/page_alloc.c | 2 ++ 4 files changed, 16 insertions(+), 2 deletions(-)diff --git a/include/linux/compaction.h b/include/linux/compaction.h index f29ef0653546..04e60f65b976 100644 --- a/include/linux/compaction.h +++ b/include/linux/compaction.h@@ -106,6 +106,7 @@ bool compaction_zonelist_suitable(struct alloc_context *ac, int order, extern void __meminit kcompactd_run(int nid); extern void __meminit kcompactd_stop(int nid); extern void wakeup_kcompactd(pg_data_t *pgdat, int order, int highest_zoneidx); +extern bool compaction_allow_unevictable(void); #else static inline void reset_isolation_suitable(pg_data_t *pgdat)@@ -131,6 +132,11 @@ static inline void wakeup_kcompactd(pg_data_t *pgdat, { } +static inline bool compaction_allow_unevictable(void) +{ + return true; +} + #endif /* CONFIG_COMPACTION */ struct node;diff --git a/mm/compaction.c b/mm/compaction.c index 007d5e00a8ae..a10acb273454 100644 --- a/mm/compaction.c +++ b/mm/compaction.c@@ -1341,6 +1341,7 @@ isolate_migratepages_range(struct compact_control *cc, unsigned long start_pfn, unsigned long end_pfn) { unsigned long pfn, block_start_pfn, block_end_pfn; + isolate_mode_t mode = cc->allow_unevictable ? ISOLATE_UNEVICTABLE : 0; int ret = 0; /* Scan block by block. First and last block may be incomplete */@@ -1360,8 +1361,7 @@ isolate_migratepages_range(struct compact_control *cc, unsigned long start_pfn, block_end_pfn, cc->zone)) continue; - ret = isolate_migratepages_block(cc, pfn, block_end_pfn, - ISOLATE_UNEVICTABLE); + ret = isolate_migratepages_block(cc, pfn, block_end_pfn, mode); if (ret) break;@@ -1902,6 +1902,11 @@ typedef enum { * compactable pages. */ static int sysctl_compact_unevictable_allowed __read_mostly = CONFIG_COMPACT_UNEVICTABLE_DEFAULT; + +bool compaction_allow_unevictable(void) +{ + return sysctl_compact_unevictable_allowed; +} /* * Tunable for proactive compaction. It determines how * aggressively the kernel should compact memory in thediff --git a/mm/internal.h b/mm/internal.h index 181e79f1d6a2..163f9d6b37f3 100644 --- a/mm/internal.h +++ b/mm/internal.h@@ -1052,6 +1052,7 @@ struct compact_control { * ensure forward progress. */ bool alloc_contig; /* alloc_contig_range allocation */ + bool allow_unevictable; /* Allow isolation of unevictable folios */ }; /*diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 81a9d4d1e6c0..1cf9d4a3b14c 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c@@ -7118,6 +7118,8 @@ int alloc_contig_frozen_range_noprof(unsigned long start, unsigned long end, .ignore_skip_hint = true, .no_set_skip_hint = true, .alloc_contig = true, + .allow_unevictable = !!(alloc_flags & ACR_FLAGS_CMA) || + compaction_allow_unevictable(), }; INIT_LIST_HEAD(&cc.migratepages); enum pb_isolate_mode mode = (alloc_flags & ACR_FLAGS_CMA) ?