Commit 343e35e5 authored by Kemeng Shi's avatar Kemeng Shi Committed by Liu Shixin
Browse files

mm/compaction: correctly return failure with bogus compound_order in strict mode

mainline inclusion
from mainline-v6.7-rc1
commit 3da0272a4c7d0d37b47b28e87014f421296fc2be
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IBE66K
CVE: NA

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=3da0272a4c7d0d37b47b28e87014f421296fc2be

--------------------------------

In strict mode, we should return 0 if there is any hole in pageblock.  If
we successfully isolated pages at beginning at pageblock and then have a
bogus compound_order outside pageblock in next page.  We will abort search
loop with blockpfn > end_pfn.  Although we will limit blockpfn to end_pfn,
we will treat it as a successful isolation in strict mode as blockpfn is
not < end_pfn and return partial isolated pages.  Then
isolate_freepages_range may success unexpectly with hole in isolated
range.

Link: https://lkml.kernel.org/r/20230901155141.249860-4-shikemeng@huaweicloud.com


Fixes: 9fcd6d2e ("mm, compaction: skip compound pages by order in free scanner")
Signed-off-by: default avatarKemeng Shi <shikemeng@huaweicloud.com>
Reviewed-by: default avatarBaolin Wang <baolin.wang@linux.alibaba.com>
Acked-by: default avatarMel Gorman <mgorman@techsingularity.net>
Cc: David Hildenbrand <david@redhat.com>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Conflicts:
	mm/compaction.c
[ Context conflicts. ]
Signed-off-by: default avatarLiu Shixin <liushixin2@huawei.com>
parent a8a9daf9
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -476,10 +476,11 @@ static unsigned long isolate_freepages_block(struct compact_control *cc,
		if (PageCompound(page)) {
			const unsigned int order = compound_order(page);

			if (likely(order < MAX_ORDER)) {
			if (blockpfn + (1UL << order) <= end_pfn) {
				blockpfn += (1UL << order) - 1;
				cursor += (1UL << order) - 1;
			}

			goto isolate_fail;
		}

@@ -544,8 +545,7 @@ static unsigned long isolate_freepages_block(struct compact_control *cc,
		spin_unlock_irqrestore(&cc->zone->lock, flags);

	/*
	 * There is a tiny chance that we have read bogus compound_order(),
	 * so be careful to not go outside of the pageblock.
	 * Be careful to not go outside of the pageblock.
	 */
	if (unlikely(blockpfn > end_pfn))
		blockpfn = end_pfn;