* FAILED: patch "[PATCH] mm/hugetlb: do not dissolve gigantic pages without runtime" failed to apply to 5.15-stable tree
@ 2026-09-29 8:27 gregkh
2026-09-30 0:44 ` [PATCH 5.15.y 1/2] mm/hugetlb: fix surplus pages in dissolve_free_huge_page() Sasha Levin
0 siblings, 1 reply; 3+ messages in thread
From: gregkh @ 2026-09-29 8:27 UTC (permalink / raw)
To: xialonglong, akpm, david, linmiaohe, mhocko, muchun.song,
osalvador, stable
Cc: stable
The patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable@vger.kernel.org>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y
git checkout FETCH_HEAD
git cherry-pick -x a363c62a653cc8b3e21da9545fa4e028ef50f9c3
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<stable@vger.kernel.org>' --in-reply-to '2026092905-mystified-upstart-3f7b@gregkh' --subject-prefix 'PATCH 5.15.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From a363c62a653cc8b3e21da9545fa4e028ef50f9c3 Mon Sep 17 00:00:00 2001
From: Longlong Xia <xialonglong@kylinos.cn>
Date: Sun, 23 Aug 2026 12:40:51 +0800
Subject: [PATCH] mm/hugetlb: do not dissolve gigantic pages without runtime
support
dissolve_free_hugetlb_folio() doesn't check
hstate_is_gigantic_no_runtime(h) though remove_hugetlb_folio()/
update_and_free_hugetlb_folio() silently bail for such folios, so it frees
a still-listed folio and, on vmemmap restore failure, the
add_hugetlb_folio() rollback corrupts the free list.
Link: https://lore.kernel.org/20260823044118.1097121-2-xialonglong2025@163.com
Fixes: 6eb4e88a6d27 ("hugetlb: create remove_hugetlb_page() to separate functionality")
Signed-off-by: Longlong Xia <xialonglong@kylinos.cn>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Assisted-by: Codex:gpt-5.6-sol
Acked-by: Muchun Song <muchun.song@linux.dev>
Cc: David Hildenbrand <david@kernel.org>
Cc: Miaohe Lin <linmiaohe@huawei.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: <stable@vger.kernel.org>
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 4f6f58bf3db6..d28972cd33f5 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -1967,6 +1967,15 @@ int dissolve_free_hugetlb_folio(struct folio *folio)
struct hstate *h = folio_hstate(folio);
bool adjust_surplus = false;
+ /*
+ * remove_hugetlb_folio()/update_and_free_hugetlb_folio() bail
+ * for gigantic hstates without runtime support, so dissolving one
+ * here would leave it on the free list and, on vmemmap restore
+ * failure, the add_hugetlb_folio() rollback corrupts that list.
+ */
+ if (hstate_is_gigantic_no_runtime(h))
+ goto out;
+
if (!available_huge_pages(h))
goto out;
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 5.15.y 1/2] mm/hugetlb: fix surplus pages in dissolve_free_huge_page()
2026-09-29 8:27 FAILED: patch "[PATCH] mm/hugetlb: do not dissolve gigantic pages without runtime" failed to apply to 5.15-stable tree gregkh
@ 2026-09-30 0:44 ` Sasha Levin
2026-09-30 0:44 ` [PATCH 5.15.y 2/2] mm/hugetlb: do not dissolve gigantic pages without runtime support Sasha Levin
0 siblings, 1 reply; 3+ messages in thread
From: Sasha Levin @ 2026-09-30 0:44 UTC (permalink / raw)
To: stable
Cc: Jinjiang Tu, David Hildenbrand, Oscar Salvador, Kefeng Wang,
Muchun Song, Nanyong Sun, Andrew Morton, Sasha Levin
From: Jinjiang Tu <tujinjiang@huawei.com>
[ Upstream commit cb402bbdabcaa5a765068c5b8673bbfc1c264242 ]
In dissolve_free_huge_page(), free huge pages are dissolved without
adjusting surplus count. However, free huge pages may be accounted as
surplus pages, and will lead to wrong surplus count.
I reproduce this issue on qemu. The steps are:
1) Node1 is memory-less at first. Hot-add memory to node1 by executing
the two commands in qemu monitor:
object_add memory-backend-ram,id=mem1,size=1G
device_add pc-dimm,id=dimm1,memdev=mem1,node=1
2) online one memory block of Node1 with:
echo online_movable > /sys/devices/system/node/node1/memoryX/state
3) create 64 huge pages for node1
4) run a program to reserve (don't consume) all the huge pages
5) echo 0 > nr_huge_pages for node1. After this step, free huge pages in
Node1 are surplus.
6) create 80 huge pages for node0
7) offline memory of node1, The memory range to offline contains the free
surplus huge pages created in step3) ~ step5)
echo offline > /sys/devices/system/node/node1/memoryX/state
8) kill the program in step 4)
The result:
Node0 Node1
total 80 0
free 80 0
surplus 0 61
To fix it, adjust surplus when destroying huge pages if the node has
surplus pages in dissolve_free_hugetlb_folio().
The result with this patch:
Node0 Node1
total 80 0
free 80 0
surplus 0 0
Link: https://lkml.kernel.org/r/20250304132106.2872754-1-tujinjiang@huawei.com
Fixes: c8721bbbdd36 ("mm: memory-hotplug: enable memory hotplug to handle hugepage")
Signed-off-by: Jinjiang Tu <tujinjiang@huawei.com>
Acked-by: David Hildenbrand <david@redhat.com>
Acked-by: Oscar Salvador <osalvador@suse.de>
Cc: Jinjiang Tu <tujinjiang@huawei.com>
Cc: Kefeng Wang <wangkefeng.wang@huawei.com>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Nanyong Sun <sunnanyong@huawei.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Backport notes for Linux 5.15:
- Use compound_head(), page_to_nid(), remove_hugetlb_page(), and
add_hugetlb_page() for surplus accounting. Preserve the existing vmemmap
restoration and raw hardware-poison handling.
- Keep max_huge_pages unchanged when removing or restoring a surplus
page, as fixed upstream by 267bede12d3b ("mm/hugetlb: keep max_huge_pages
when dissolving surplus folios"). This avoids corrupting or underflowing
the persistent pool target.
- Define available_huge_pages() and hstate_is_gigantic_no_runtime() as
local expression macros using the existing 5.15 operations. Reuse the
latter in the existing runtime-support checks. These prepare the
context and predicate needed for a clean cherry-pick of a363c62a653c
without adding functions or importing the folio conversion.
Stable-dep-of: a363c62a653c ("mm/hugetlb: do not dissolve gigantic pages without runtime support")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/hugetlb.c | 26 ++++++++++++++++++--------
1 file changed, 18 insertions(+), 8 deletions(-)
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index e0908e491065d..f4b296c3f6d3b 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -44,6 +44,10 @@
#include "internal.h"
#include "hugetlb_vmemmap.h"
+#define available_huge_pages(h) ((h)->free_huge_pages - (h)->resv_huge_pages)
+#define hstate_is_gigantic_no_runtime(h) \
+ (hstate_is_gigantic(h) && !gigantic_page_runtime_supported())
+
int hugetlb_max_hstate __read_mostly;
unsigned int default_hstate_idx;
struct hstate hstates[HUGE_MAX_HSTATE];
@@ -1368,7 +1372,7 @@ static void remove_hugetlb_page(struct hstate *h, struct page *page,
VM_BUG_ON_PAGE(hugetlb_cgroup_from_page_rsvd(page), page);
lockdep_assert_held(&hugetlb_lock);
- if (hstate_is_gigantic(h) && !gigantic_page_runtime_supported())
+ if (hstate_is_gigantic_no_runtime(h))
return;
list_del(&page->lru);
@@ -1456,7 +1460,7 @@ static void __update_and_free_page(struct hstate *h, struct page *page)
int i;
struct page *subpage = page;
- if (hstate_is_gigantic(h) && !gigantic_page_runtime_supported())
+ if (hstate_is_gigantic_no_runtime(h))
return;
if (alloc_huge_page_vmemmap(h, page)) {
@@ -1969,7 +1973,9 @@ int dissolve_free_huge_page(struct page *page)
if (!page_count(page)) {
struct page *head = compound_head(page);
struct hstate *h = page_hstate(head);
- if (h->free_huge_pages - h->resv_huge_pages == 0)
+ bool adjust_surplus = false;
+
+ if (!available_huge_pages(h))
goto out;
/*
@@ -1991,8 +1997,11 @@ int dissolve_free_huge_page(struct page *page)
goto retry;
}
- remove_hugetlb_page(h, head, false);
- h->max_huge_pages--;
+ if (h->surplus_huge_pages_node[page_to_nid(head)])
+ adjust_surplus = true;
+ remove_hugetlb_page(h, head, adjust_surplus);
+ if (!adjust_surplus)
+ h->max_huge_pages--;
spin_unlock_irq(&hugetlb_lock);
/*
@@ -2017,8 +2026,9 @@ int dissolve_free_huge_page(struct page *page)
update_and_free_page(h, head, false);
} else {
spin_lock_irq(&hugetlb_lock);
- add_hugetlb_page(h, head, false);
- h->max_huge_pages++;
+ add_hugetlb_page(h, head, adjust_surplus);
+ if (!adjust_surplus)
+ h->max_huge_pages++;
spin_unlock_irq(&hugetlb_lock);
}
@@ -3285,7 +3295,7 @@ static ssize_t __nr_hugepages_store_common(bool obey_mempolicy,
int err;
nodemask_t nodes_allowed, *n_mask;
- if (hstate_is_gigantic(h) && !gigantic_page_runtime_supported())
+ if (hstate_is_gigantic_no_runtime(h))
return -EINVAL;
if (nid == NUMA_NO_NODE) {
--
2.53.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 5.15.y 2/2] mm/hugetlb: do not dissolve gigantic pages without runtime support
2026-09-30 0:44 ` [PATCH 5.15.y 1/2] mm/hugetlb: fix surplus pages in dissolve_free_huge_page() Sasha Levin
@ 2026-09-30 0:44 ` Sasha Levin
0 siblings, 0 replies; 3+ messages in thread
From: Sasha Levin @ 2026-09-30 0:44 UTC (permalink / raw)
To: stable
Cc: Longlong Xia, Andrew Morton, Muchun Song, David Hildenbrand,
Miaohe Lin, Michal Hocko, Oscar Salvador, Sasha Levin
From: Longlong Xia <xialonglong@kylinos.cn>
[ Upstream commit a363c62a653cc8b3e21da9545fa4e028ef50f9c3 ]
dissolve_free_hugetlb_folio() doesn't check
hstate_is_gigantic_no_runtime(h) though remove_hugetlb_folio()/
update_and_free_hugetlb_folio() silently bail for such folios, so it frees
a still-listed folio and, on vmemmap restore failure, the
add_hugetlb_folio() rollback corrupts the free list.
Link: https://lore.kernel.org/20260823044118.1097121-2-xialonglong2025@163.com
Fixes: 6eb4e88a6d27 ("hugetlb: create remove_hugetlb_page() to separate functionality")
Signed-off-by: Longlong Xia <xialonglong@kylinos.cn>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Assisted-by: Codex:gpt-5.6-sol
Acked-by: Muchun Song <muchun.song@linux.dev>
Cc: David Hildenbrand <david@kernel.org>
Cc: Miaohe Lin <linmiaohe@huawei.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/hugetlb.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index f4b296c3f6d3b..a7ceac999a3fa 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -1975,6 +1975,15 @@ int dissolve_free_huge_page(struct page *page)
struct hstate *h = page_hstate(head);
bool adjust_surplus = false;
+ /*
+ * remove_hugetlb_folio()/update_and_free_hugetlb_folio() bail
+ * for gigantic hstates without runtime support, so dissolving one
+ * here would leave it on the free list and, on vmemmap restore
+ * failure, the add_hugetlb_folio() rollback corrupts that list.
+ */
+ if (hstate_is_gigantic_no_runtime(h))
+ goto out;
+
if (!available_huge_pages(h))
goto out;
--
2.53.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-09-30 0:44 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-29 8:27 FAILED: patch "[PATCH] mm/hugetlb: do not dissolve gigantic pages without runtime" failed to apply to 5.15-stable tree gregkh
2026-09-30 0:44 ` [PATCH 5.15.y 1/2] mm/hugetlb: fix surplus pages in dissolve_free_huge_page() Sasha Levin
2026-09-30 0:44 ` [PATCH 5.15.y 2/2] mm/hugetlb: do not dissolve gigantic pages without runtime support Sasha Levin
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.