[PATCH v2 17/18] memblock: allow calculating reserved size by flags
From: Pratyush Yadav
Date: Fri Jun 05 2026 - 14:41:32 EST
From: "Pratyush Yadav (Google)" <pratyush@xxxxxxxxxx>
memblock_reserved_kern_size() returns the total size of all reserved
areas flagged RSRV_KERN. KHO also needs total size of all reserved areas
flagged HUGETLB to correctly size its scratch areas.
Refactor memblock_reserved_kern_size() into
memblock_reserved_size_flags(). The new function returns total size of
all reserved areas which match _any_ of the flags.
Signed-off-by: Pratyush Yadav (Google) <pratyush@xxxxxxxxxx>
---
include/linux/memblock.h | 3 ++-
kernel/liveupdate/kexec_handover.c | 14 ++++++++------
mm/memblock.c | 8 +++++---
3 files changed, 15 insertions(+), 10 deletions(-)
diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index b3b4a6145fad..a3b57066611d 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -487,7 +487,8 @@ static inline __init_memblock bool memblock_bottom_up(void)
phys_addr_t memblock_phys_mem_size(void);
phys_addr_t memblock_reserved_size(void);
-phys_addr_t memblock_reserved_kern_size(phys_addr_t limit, int nid);
+phys_addr_t memblock_reserved_size_flags(phys_addr_t limit, int nid,
+ enum memblock_flags flags);
unsigned long memblock_estimated_nr_free_pages(void);
phys_addr_t memblock_start_of_DRAM(void);
phys_addr_t memblock_end_of_DRAM(void);
diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_handover.c
index 8540608b8602..b3c33f150e85 100644
--- a/kernel/liveupdate/kexec_handover.c
+++ b/kernel/liveupdate/kexec_handover.c
@@ -749,13 +749,15 @@ static void __init scratch_size_update(void)
if (scratch_scale) {
phys_addr_t size;
- size = memblock_reserved_kern_size(ARCH_LOW_ADDRESS_LIMIT,
- NUMA_NO_NODE);
+ size = memblock_reserved_size_flags(ARCH_LOW_ADDRESS_LIMIT,
+ NUMA_NO_NODE,
+ MEMBLOCK_RSRV_KERN);
size = size * scratch_scale / 100;
scratch_size_lowmem = size;
- size = memblock_reserved_kern_size(MEMBLOCK_ALLOC_ANYWHERE,
- NUMA_NO_NODE);
+ size = memblock_reserved_size_flags(MEMBLOCK_ALLOC_ANYWHERE,
+ NUMA_NO_NODE,
+ MEMBLOCK_RSRV_KERN);
size = size * scratch_scale / 100 - scratch_size_lowmem;
scratch_size_global = size;
}
@@ -773,8 +775,8 @@ static phys_addr_t __init scratch_size_node(int nid)
phys_addr_t size;
if (scratch_scale) {
- size = memblock_reserved_kern_size(MEMBLOCK_ALLOC_ANYWHERE,
- nid);
+ size = memblock_reserved_size_flags(MEMBLOCK_ALLOC_ANYWHERE,
+ nid, MEMBLOCK_RSRV_KERN);
size = size * scratch_scale / 100;
} else {
size = scratch_size_pernode;
diff --git a/mm/memblock.c b/mm/memblock.c
index 131e54dd5d8d..cc21f877cb67 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -1893,7 +1893,8 @@ phys_addr_t __init_memblock memblock_reserved_size(void)
return memblock.reserved.total_size;
}
-phys_addr_t __init_memblock memblock_reserved_kern_size(phys_addr_t limit, int nid)
+phys_addr_t __init_memblock memblock_reserved_size_flags(phys_addr_t limit, int nid,
+ enum memblock_flags flags)
{
struct memblock_region *r;
phys_addr_t total = 0;
@@ -1908,7 +1909,7 @@ phys_addr_t __init_memblock memblock_reserved_kern_size(phys_addr_t limit, int n
size = limit - r->base;
if (nid == memblock_get_region_node(r) || !numa_valid_node(nid))
- if (r->flags & MEMBLOCK_RSRV_KERN)
+ if (r->flags & flags)
total += size;
}
@@ -1930,7 +1931,8 @@ phys_addr_t __init_memblock memblock_reserved_kern_size(phys_addr_t limit, int n
unsigned long __init memblock_estimated_nr_free_pages(void)
{
return PHYS_PFN(memblock_phys_mem_size() -
- memblock_reserved_kern_size(MEMBLOCK_ALLOC_ANYWHERE, NUMA_NO_NODE));
+ memblock_reserved_size_flags(MEMBLOCK_ALLOC_ANYWHERE, NUMA_NO_NODE,
+ MEMBLOCK_RSRV_KERN));
}
/* lowest address */
--
2.54.0.1032.g2f8565e1d1-goog