[PATCH v3 21/21] kho: exclude hugetlb memory from scratch size calculation

From: Pratyush Yadav

Date: Thu Jul 09 2026 - 13:47:43 EST


From: "Pratyush Yadav (Google)" <pratyush@xxxxxxxxxx>

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@xxxxxxxxxx>
---
kernel/liveupdate/kexec_handover.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_handover.c
index 2c4848874629..9dc79b7103bd 100644
--- a/kernel/liveupdate/kexec_handover.c
+++ b/kernel/liveupdate/kexec_handover.c
@@ -742,19 +742,24 @@ early_param("kho_scratch", kho_parse_scratch_size);
static void __init scratch_size_update(void)
{
/*
- * If fixed sizes are not provided via command line, calculate them
- * now.
+ * If fixed sizes are not provided via command line, calculate them now.
+ * Remove HugeTLB allocations from it because they never get allocated
+ * from scratch.
*/
if (scratch_scale) {
phys_addr_t size;

size = memblock_reserved_kern_size(ARCH_LOW_ADDRESS_LIMIT,
NUMA_NO_NODE);
+ size -= memblock_reserved_hugetlb_size(ARCH_LOW_ADDRESS_LIMIT,
+ NUMA_NO_NODE);
size = size * scratch_scale / 100;
scratch_size_lowmem = size;

size = memblock_reserved_kern_size(MEMBLOCK_ALLOC_ANYWHERE,
NUMA_NO_NODE);
+ size -= memblock_reserved_hugetlb_size(MEMBLOCK_ALLOC_ANYWHERE,
+ NUMA_NO_NODE);
size = size * scratch_scale / 100 - scratch_size_lowmem;
scratch_size_global = size;
}
@@ -774,6 +779,9 @@ static phys_addr_t __init scratch_size_node(int nid)
if (scratch_scale) {
size = memblock_reserved_kern_size(MEMBLOCK_ALLOC_ANYWHERE,
nid);
+ /* Do not count HugeTLB pages. */
+ size -= memblock_reserved_hugetlb_size(MEMBLOCK_ALLOC_ANYWHERE,
+ nid);
size = size * scratch_scale / 100;
} else {
size = scratch_size_pernode;
--
2.55.0.141.g00534a21ce-goog