summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLonglong Xia <xialonglong@kylinos.cn>2026-08-14 16:30:27 +0800
committerAndrew Morton <akpm@linux-foundation.org>2026-09-01 20:26:21 -0700
commit267bede12d3b108ca29997ce280e927a570ec97f (patch)
treeb5111ca29ae43aa280d3e9157fdac2b4a684a9fc
parentdc41e961a269f2ca4196e669d6d8e05480899cd4 (diff)
mm/hugetlb: keep max_huge_pages when dissolving surplus folios
dissolve_free_hugetlb_folio() can remove a free folio as surplus when its node has surplus pages. In that case remove_hugetlb_folio() decrements both nr_huge_pages and surplus_huge_pages, leaving the persistent pool size unchanged. Updating max_huge_pages as if a persistent folio had been removed can therefore corrupt the persistent pool target and underflow it when max_huge_pages is zero. Keep max_huge_pages unchanged for surplus folios, including the vmemmap restoration rollback path. Link: https://lore.kernel.org/20260814083027.1419487-1-xialonglong2025@163.com Fixes: cb402bbdabca ("mm/hugetlb: fix surplus pages in dissolve_free_huge_page()") Assisted-by: Codex:gpt-5.6-sol Signed-off-by: Longlong Xia <xialonglong@kylinos.cn> Reviewed-by: Muchun Song <muchun.song@linux.dev> Cc: David Hildenbrand <david@kernel.org> Cc: Jinjiang Tu <tujinjiang@huawei.com> Cc: Longlong Xia <xialonglong@kylinos.cn> Cc: Oscar Salvador <osalvador@suse.de> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-rw-r--r--mm/hugetlb.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 785772845795..885017e26fd4 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -1992,7 +1992,8 @@ retry:
if (h->surplus_huge_pages_node[folio_nid(folio)])
adjust_surplus = true;
remove_hugetlb_folio(h, folio, adjust_surplus);
- h->max_huge_pages--;
+ if (!adjust_surplus)
+ h->max_huge_pages--;
spin_unlock_irq(&hugetlb_lock);
/*
@@ -2012,7 +2013,8 @@ retry:
if (rc) {
spin_lock_irq(&hugetlb_lock);
add_hugetlb_folio(h, folio, adjust_surplus);
- h->max_huge_pages++;
+ if (!adjust_surplus)
+ h->max_huge_pages++;
goto out;
}
} else {