mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/
synced 2025-04-19 20:58:31 +09:00
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 66fe1cf7f581 ("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: 369fa227c219 ("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>
This commit is contained in:
parent
770c8d55c4
commit
a84edd52f0
@ -981,13 +981,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;
|
||||
@ -1011,8 +1011,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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user