[PATCH v2 18/18] kho: exclude hugetlb memory from scratch size calculation

Pratyush Yadav pratyush at kernel.org
Fri Jun 5 11:34:51 PDT 2026


From: "Pratyush Yadav (Google)" <pratyush at kernel.org>

HugeTLB pages can be preserved memory. So they are never allocated from
scratch. Instead, they are allocated from the memory blocks with no
preserved memory. These areas are detected at runtime on each boot.

But since they are allocated via memblock, they show up as RSRV_KERN,
and blow up the scratch size when scratch scale is in use.

All hugetlb pages are marked RSRV_HUGETLB. Subtract their size from
RSRV_KERN when calculating scratch sizes.

Signed-off-by: Pratyush Yadav (Google) <pratyush at kernel.org>
---
 kernel/liveupdate/kexec_handover.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_handover.c
index b3c33f150e85..0d106c9197d9 100644
--- a/kernel/liveupdate/kexec_handover.c
+++ b/kernel/liveupdate/kexec_handover.c
@@ -744,7 +744,8 @@ static void __init scratch_size_update(void)
 {
 	/*
 	 * If fixed sizes are not provided via command line, calculate them
-	 * now.
+	 * now. Use RSRV_KERN to count allocated memory, but remove HugeTLB
+	 * allocations from it because they never get allocated from scratch.
 	 */
 	if (scratch_scale) {
 		phys_addr_t size;
@@ -752,12 +753,19 @@ static void __init scratch_size_update(void)
 		size = memblock_reserved_size_flags(ARCH_LOW_ADDRESS_LIMIT,
 						    NUMA_NO_NODE,
 						    MEMBLOCK_RSRV_KERN);
+		size -= memblock_reserved_size_flags(ARCH_LOW_ADDRESS_LIMIT,
+						     NUMA_NO_NODE,
+						     MEMBLOCK_RSRV_HUGETLB);
+
 		size = size * scratch_scale / 100;
 		scratch_size_lowmem = size;
 
 		size = memblock_reserved_size_flags(MEMBLOCK_ALLOC_ANYWHERE,
 						    NUMA_NO_NODE,
 						    MEMBLOCK_RSRV_KERN);
+		size -= memblock_reserved_size_flags(MEMBLOCK_ALLOC_ANYWHERE,
+						     NUMA_NO_NODE,
+						     MEMBLOCK_RSRV_HUGETLB);
 		size = size * scratch_scale / 100 - scratch_size_lowmem;
 		scratch_size_global = size;
 	}
@@ -777,6 +785,9 @@ static phys_addr_t __init scratch_size_node(int nid)
 	if (scratch_scale) {
 		size = memblock_reserved_size_flags(MEMBLOCK_ALLOC_ANYWHERE,
 						    nid, MEMBLOCK_RSRV_KERN);
+		/* Do not count HugeTLB pages. */
+		size -= memblock_reserved_size_flags(MEMBLOCK_ALLOC_ANYWHERE,
+						     nid, MEMBLOCK_RSRV_HUGETLB);
 		size = size * scratch_scale / 100;
 	} else {
 		size = scratch_size_pernode;
-- 
2.54.0.1032.g2f8565e1d1-goog




More information about the kexec mailing list