From: George Guo <dongtai.guo@linux.dev>
To: rppt@kernel.org, pasha.tatashin@soleen.com, pratyush@kernel.org
Cc: graf@amazon.com, changyuanl@google.com,
akpm@linux-foundation.org, chenhuacai@kernel.org,
sourabhjain@linux.ibm.com, liukexin@kylinos.cn,
guodongtai@kylinos.cn, kexec@lists.infradead.org,
linux-mm@kvack.org, loongarch@lists.linux.dev,
linux-kernel@vger.kernel.org
Subject: [PATCH v2] liveupdate: kho: calculate per-node bootmem sizes before allocating any
Date: Thu, 29 Oct 2026 19:34:25 +0900 [thread overview]
Message-ID: <20261029103425.14689-1-dongtai.guo@linux.dev> (raw)
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
reply other threads:[~2026-10-29 10:34 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261029103425.14689-1-dongtai.guo@linux.dev \
--to=dongtai.guo@linux.dev \
--cc=akpm@linux-foundation.org \
--cc=changyuanl@google.com \
--cc=chenhuacai@kernel.org \
--cc=graf@amazon.com \
--cc=guodongtai@kylinos.cn \
--cc=kexec@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=liukexin@kylinos.cn \
--cc=loongarch@lists.linux.dev \
--cc=pasha.tatashin@soleen.com \
--cc=pratyush@kernel.org \
--cc=rppt@kernel.org \
--cc=sourabhjain@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®