Skip to content

Commit a84edd5

Browse files
VMoolaakpm00
authored andcommitted
mm/compaction: fix bug in hugetlb handling pathway
The compaction code doesn't take references on pages until we're certain we should attempt to handle it. In the hugetlb case, isolate_or_dissolve_huge_page() may return -EBUSY without taking a reference to the folio associated with our pfn. If our folio's refcount drops to 0, compound_nr() becomes unpredictable, making low_pfn and nr_scanned unreliable. The user-visible effect is minimal - this should rarely happen (if ever). Fix this by storing the folio statistics earlier on the stack (just like the THP and Buddy cases). Also revert commit 66fe1cf ("mm: compaction: use helper compound_nr in isolate_migratepages_block") to make backporting easier. Link: https://lkml.kernel.org/r/[email protected] Fixes: 369fa22 ("mm: make alloc_contig_range handle free hugetlb pages") Signed-off-by: Vishal Moola (Oracle) <[email protected]> Acked-by: Oscar Salvador <[email protected]> Reviewed-by: Zi Yan <[email protected]> Cc: Miaohe Lin <[email protected]> Cc: Oscar Salvador <[email protected]> Cc: <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 770c8d5 commit a84edd5

File tree

1 file changed

+3
-3
lines changed

1 file changed

+3
-3
lines changed

mm/compaction.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -981,13 +981,13 @@ isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn,
981981
}
982982

983983
if (PageHuge(page)) {
984+
const unsigned int order = compound_order(page);
984985
/*
985986
* skip hugetlbfs if we are not compacting for pages
986987
* bigger than its order. THPs and other compound pages
987988
* are handled below.
988989
*/
989990
if (!cc->alloc_contig) {
990-
const unsigned int order = compound_order(page);
991991

992992
if (order <= MAX_PAGE_ORDER) {
993993
low_pfn += (1UL << order) - 1;
@@ -1011,8 +1011,8 @@ isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn,
10111011
/* Do not report -EBUSY down the chain */
10121012
if (ret == -EBUSY)
10131013
ret = 0;
1014-
low_pfn += compound_nr(page) - 1;
1015-
nr_scanned += compound_nr(page) - 1;
1014+
low_pfn += (1UL << order) - 1;
1015+
nr_scanned += (1UL << order) - 1;
10161016
goto isolate_fail;
10171017
}
10181018

0 commit comments

Comments
 (0)