All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] liveupdate: kho: calculate per-node bootmem sizes before allocating any
@ 2026-10-29 10:34 George Guo
  2026-10-29 10:39 ` sashiko-bot
  0 siblings, 1 reply; 2+ messages in thread
From: George Guo @ 2026-10-29 10:34 UTC (permalink / raw)
  To: rppt, pasha.tatashin, pratyush
  Cc: graf, changyuanl, akpm, chenhuacai, sourabhjain, liukexin,
	guodongtai, kexec, linux-mm, loongarch, linux-kernel

From: George Guo <guodongtai@kylinos.cn>

kho_reserve_bootmem() calculated the per-node bootmem sizes inside the
allocation loop, after the lowmem and global areas had been allocated.

Without CONFIG_NUMA, memblock_get_region_node() returns 0 for every
region, and memblock_reserved_kern_size() attributes a region to a node
by memblock_get_region_node(). Since allocations are marked
MEMBLOCK_RSRV_KERN, the newly allocated lowmem and global areas enter
node 0's baseline and are scaled again by bootmem_size_node().

In the original 1 GiB QEMU reproducer, the default 200% scale made
node 0 request 672 MiB: twice the sum of the 98.45 MiB baseline and
224 MiB lowmem area, rounded up to 32 MiB alignment. The reservation
failed and KHO disabled itself.

With CONFIG_NUMA=y, node-specific accounting excludes the NUMA_NO_NODE
reservations.

The lowmem and global sizes are already calculated by
bootmem_size_update() before any allocation. Calculate the per-node
sizes into the kho_bootmem descriptors before reserving any bootmem
area as well, and allocate the per-node areas from the stored sizes.
Use separate read and write indices to preserve the saved sizes when
zero-sized per-node areas are skipped.

Fixes: 3dc92c311498 ("kexec: add Kexec HandOver (KHO) generation helpers")
Reported-by: Kexin Liu <liukexin@kylinos.cn>
Co-developed-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: Kexin Liu <liukexin@kylinos.cn>
Signed-off-by: George Guo <guodongtai@kylinos.cn>
---
Changes in v2:
- Calculate every size before any allocation (Mike). The lowmem and
  global sizes are already calculated by bootmem_size_update(), so only
  the per-node sizes move out of the allocation loop.
- Rebase onto liveupdate-7.4: follow the "scratch" to "bootmem" rename,
  and keep the zero-size node skip added by "kho: do not reserve empty
  per-node bootmem areas" by reading the saved sizes with a separate
  index.
- Explain why only CONFIG_NUMA=n kernels are affected (Pratyush, Sourabh).
- The global size over-allocation on NUMA systems, which I planned to
  look at as a follow-up, is handled by Sourabh's "kho: fix global
  scratch size calculation" [1]. Mike asked there for a broader rework
  of the sizing; this patch only fixes the CONFIG_NUMA=n double
  counting.
- No Assisted-by tag, although I said on v1 that I would add one: the
  Assisted-by references have since been removed from the documentation
  in mainline.

Tested with the KHO vmtest on a 1 GiB LoongArch QEMU guest, with the
LoongArch KHO series on top: it passes with both CONFIG_NUMA=n and
CONFIG_NUMA=y. Without this patch, KHO disables itself in the
CONFIG_NUMA=n run.

v1: https://lore.kernel.org/all/20260904025101.9959-1-dongtai.guo@linux.dev/
[1] https://lore.kernel.org/all/20260922131217.698809-1-sourabhjain@linux.ibm.com/

 kernel/liveupdate/kexec_handover.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_handover.c
index 6f1f55fe3181..9a53d7750367 100644
--- a/kernel/liveupdate/kexec_handover.c
+++ b/kernel/liveupdate/kexec_handover.c
@@ -831,7 +831,7 @@ bool kho_bootmem_overlap(phys_addr_t phys, size_t size)
  */
 static void __init kho_reserve_bootmem(void)
 {
-	int nid, i = 0, max_nr_bootmem;
+	int nid, i, j, max_nr_bootmem;
 	phys_addr_t addr, size;
 
 	if (!kho_enable)
@@ -848,6 +848,15 @@ static void __init kho_reserve_bootmem(void)
 		goto err_disable_kho;
 	}
 
+	/*
+	 * Save the per-node sizes before allocating bootmem areas. Without
+	 * CONFIG_NUMA, new lowmem and global allocations would otherwise be
+	 * counted as node 0 kernel reservations and scaled again.
+	 */
+	j = 2;
+	for_each_node_state(nid, N_MEMORY)
+		kho_bootmem[j++].size = bootmem_size_node(nid);
+
 	/*
 	 * reserve bootmem area in low memory for lowmem allocations in the
 	 * next kernel
@@ -860,6 +869,7 @@ static void __init kho_reserve_bootmem(void)
 		goto err_free_bootmem_desc;
 	}
 
+	i = 0;
 	kho_bootmem[i].addr = addr;
 	kho_bootmem[i].size = size;
 	i++;
@@ -879,9 +889,12 @@ static void __init kho_reserve_bootmem(void)
 	/*
 	 * Loop over nodes that have both memory and are online. Skip
 	 * memoryless nodes, as we can not allocate bootmem areas there.
+	 * Skipping zero-sized areas leaves i behind j, so writes to
+	 * kho_bootmem[i] cannot overwrite unread sizes.
 	 */
+	j = i;
 	for_each_node_state(nid, N_MEMORY) {
-		size = bootmem_size_node(nid);
+		size = kho_bootmem[j++].size;
 		if (!size)
 			continue;
 

base-commit: 9a6a70aefe77f6fb9ff2b3037dcf87f6dff65c8c
-- 
2.53.0



^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH v2] liveupdate: kho: calculate per-node bootmem sizes before allocating any
  2026-10-29 10:34 [PATCH v2] liveupdate: kho: calculate per-node bootmem sizes before allocating any George Guo
@ 2026-10-29 10:39 ` sashiko-bot
  0 siblings, 0 replies; 2+ messages in thread
From: sashiko-bot @ 2026-10-29 10:39 UTC (permalink / raw)
  To: George Guo, rppt, pasha.tatashin, pratyush
  Cc: graf, changyuanl, akpm, chenhuacai, sourabhjain, liukexin,
	guodongtai, kexec

> From: George Guo <guodongtai@kylinos.cn>
> 
> kho_reserve_bootmem() calculated the per-node bootmem sizes inside the
> allocation loop, after the lowmem and global areas had been allocated.
> 
> Without CONFIG_NUMA, memblock_get_region_node() returns 0 for every
> region, and memblock_reserved_kern_size() attributes a region to a node
> by memblock_get_region_node(). Since allocations are marked
> MEMBLOCK_RSRV_KERN, the newly allocated lowmem and global areas enter
> node 0's baseline and are scaled again by bootmem_size_node().
> 
> In the original 1 GiB QEMU reproducer, the default 200% scale made
> node 0 request 672 MiB: twice the sum of the 98.45 MiB baseline and
> 224 MiB lowmem area, rounded up to 32 MiB alignment. The reservation
> failed and KHO disabled itself.
> [ ... ]
> Fixes: 3dc92c311498 ("kexec: add Kexec HandOver (KHO) generation helpers")
> Reported-by: Kexin Liu <liukexin@kylinos.cn>
> Co-developed-by: Kexin Liu <liukexin@kylinos.cn>
> Signed-off-by: Kexin Liu <liukexin@kylinos.cn>
> Signed-off-by: George Guo <guodongtai@kylinos.cn>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261029103425.14689-1-dongtai.guo@linux.dev?part=1



^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-10-29 10:39 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-29 10:34 [PATCH v2] liveupdate: kho: calculate per-node bootmem sizes before allocating any George Guo
2026-10-29 10:39 ` sashiko-bot

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.