Skip to content

Commit

Permalink
mm/compaction: fix bug in hugetlb handling pathway
Browse files Browse the repository at this point in the history
commit a84edd5 upstream.

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/20250401021025.637333-1-vishal.moola@gmail.com
Fixes: 369fa22 ("mm: make alloc_contig_range handle free hugetlb pages")
Signed-off-by: Vishal Moola (Oracle) <vishal.moola@gmail.com>
Acked-by: Oscar Salvador <osalvador@suse.de>
Reviewed-by: Zi Yan <ziy@nvidia.com>
Cc: Miaohe Lin <linmiaohe@huawei.com>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Vishal Moola (Oracle) authored and Greg Kroah-Hartman committed Apr 25, 2025
1 parent c45ba83 commit 4f34d6f
Showing 1 changed file with 3 additions and 3 deletions.
6 changes: 3 additions & 3 deletions mm/compaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -980,13 +980,13 @@ isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn,
}

if (PageHuge(page)) {
const unsigned int order = compound_order(page);
/*
* skip hugetlbfs if we are not compacting for pages
* bigger than its order. THPs and other compound pages
* are handled below.
*/
if (!cc->alloc_contig) {
const unsigned int order = compound_order(page);

if (order <= MAX_PAGE_ORDER) {
low_pfn += (1UL << order) - 1;
Expand All @@ -1010,8 +1010,8 @@ isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn,
/* Do not report -EBUSY down the chain */
if (ret == -EBUSY)
ret = 0;
low_pfn += compound_nr(page) - 1;
nr_scanned += compound_nr(page) - 1;
low_pfn += (1UL << order) - 1;
nr_scanned += (1UL << order) - 1;
goto isolate_fail;
}

Expand Down

0 comments on commit 4f34d6f

Please sign in to comment.