diff --git a/mm/huge_memory.c b/mm/huge_memory.c --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -4476,6 +4476,17 @@ static unsigned long deferred_split_count(struct shrinker *shrink, { unsigned long count; + /* + * Splitting a partially mapped folio during an opportunistic + * high-order pass frees its unmapped tail pages but shatters the + * folio, so the pass works against the contiguous block it is + * reclaiming for. Report nothing rather than SHRINK_EMPTY: for a + * memcg aware shrinker SHRINK_EMPTY clears the memcg shrinker bit, + * which would also skip the next normal pass. + */ + if (sc->opportunistic_compaction) + return 0; + count = list_lru_shrink_count(&deferred_split_lru, sc); return count ?: SHRINK_EMPTY; }