* [PATCH] kho: Skip zero-sized bootmem areas
@ 2026-10-26 13:18 Chen Pei
2026-10-26 14:22 ` Pratyush Yadav
0 siblings, 1 reply; 5+ messages in thread
From: Chen Pei @ 2026-10-26 13:18 UTC (permalink / raw)
To: rppt, pasha.tatashin, pratyush, graf; +Cc: kexec, linux-mm, linux-kernel
The lowmem and the global bootmem area are reserved unconditionally,
while the per-node loop below already skips nodes whose size works out
to 0. Either can legitimately be 0: the global size is the scaled total
minus the lowmem one, so it is 0 whenever all measured reservations fit
below ARCH_LOW_ADDRESS_LIMIT.
Reserving 0 bytes still succeeds, so an area covering nothing gets
recorded with a valid address. That is not neutral:
kho_bootmem_overlap() reports an overlap for any request straddling
that address, and memblock_alloc_hugetlb() aligns a request to its page
size, so a 1G hugetlb allocation retries a free candidate on account of
an area that holds nothing.
A machine whose memory all starts at or above ARCH_LOW_ADDRESS_LIMIT
hits the other side of the same code: the lowmem size is 0, the range
below the limit is empty, the allocation fails and KHO is disabled
although no lowmem area was needed.
Skip a zero-sized area instead, as the per-node loop does. The
descriptor count stays consistent, as kho_populate() derives it from
the segment length that kho_fill_kimage() serialises.
Fixes: 3dc92c311498 ("kexec: add Kexec HandOver (KHO) generation helpers")
Signed-off-by: Chen Pei <cp0613@linux.alibaba.com>
---
kernel/liveupdate/kexec_handover.c | 38 +++++++++++++++++-------------
1 file changed, 21 insertions(+), 17 deletions(-)
diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_handover.c
index 6f1f55fe3..c9c9fdfac 100644
--- a/kernel/liveupdate/kexec_handover.c
+++ b/kernel/liveupdate/kexec_handover.c
@@ -853,28 +853,32 @@ static void __init kho_reserve_bootmem(void)
* next kernel
*/
size = bootmem_size_lowmem;
- addr = memblock_phys_alloc_range(size, BOOTMEM_ALIGNMENT_BYTES, 0,
- ARCH_LOW_ADDRESS_LIMIT);
- if (!addr) {
- pr_err("Failed to reserve lowmem bootmem\n");
- goto err_free_bootmem_desc;
- }
+ if (size) {
+ addr = memblock_phys_alloc_range(size, BOOTMEM_ALIGNMENT_BYTES,
+ 0, ARCH_LOW_ADDRESS_LIMIT);
+ if (!addr) {
+ pr_err("Failed to reserve lowmem bootmem\n");
+ goto err_free_bootmem_desc;
+ }
- kho_bootmem[i].addr = addr;
- kho_bootmem[i].size = size;
- i++;
+ kho_bootmem[i].addr = addr;
+ kho_bootmem[i].size = size;
+ i++;
+ }
/* reserve large contiguous area for allocations without nid */
size = bootmem_size_global;
- addr = memblock_phys_alloc(size, BOOTMEM_ALIGNMENT_BYTES);
- if (!addr) {
- pr_err("Failed to reserve global bootmem\n");
- goto err_free_bootmem_areas;
- }
+ if (size) {
+ addr = memblock_phys_alloc(size, BOOTMEM_ALIGNMENT_BYTES);
+ if (!addr) {
+ pr_err("Failed to reserve global bootmem\n");
+ goto err_free_bootmem_areas;
+ }
- kho_bootmem[i].addr = addr;
- kho_bootmem[i].size = size;
- i++;
+ kho_bootmem[i].addr = addr;
+ kho_bootmem[i].size = size;
+ i++;
+ }
/*
* Loop over nodes that have both memory and are online. Skip
--
2.50.1
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH] kho: Skip zero-sized bootmem areas
2026-10-26 13:18 [PATCH] kho: Skip zero-sized bootmem areas Chen Pei
@ 2026-10-26 14:22 ` Pratyush Yadav
2026-10-27 7:40 ` Chen Pei
0 siblings, 1 reply; 5+ messages in thread
From: Pratyush Yadav @ 2026-10-26 14:22 UTC (permalink / raw)
To: Chen Pei
Cc: rppt, pasha.tatashin, pratyush, graf, kexec, linux-mm, linux-kernel
On Mon, Oct 26 2026, Chen Pei wrote:
> The lowmem and the global bootmem area are reserved unconditionally,
> while the per-node loop below already skips nodes whose size works out
> to 0. Either can legitimately be 0: the global size is the scaled total
> minus the lowmem one, so it is 0 whenever all measured reservations fit
> below ARCH_LOW_ADDRESS_LIMIT.
>
> Reserving 0 bytes still succeeds, so an area covering nothing gets
> recorded with a valid address. That is not neutral:
> kho_bootmem_overlap() reports an overlap for any request straddling
> that address, and memblock_alloc_hugetlb() aligns a request to its page
> size, so a 1G hugetlb allocation retries a free candidate on account of
> an area that holds nothing.
>
> A machine whose memory all starts at or above ARCH_LOW_ADDRESS_LIMIT
> hits the other side of the same code: the lowmem size is 0, the range
> below the limit is empty, the allocation fails and KHO is disabled
> although no lowmem area was needed.
>
> Skip a zero-sized area instead, as the per-node loop does. The
> descriptor count stays consistent, as kho_populate() derives it from
> the segment length that kho_fill_kimage() serialises.
>
> Fixes: 3dc92c311498 ("kexec: add Kexec HandOver (KHO) generation helpers")
> Signed-off-by: Chen Pei <cp0613@linux.alibaba.com>
Do you see zero sized lowmem or global scratch in practice? If yes, how?
What's your setup?
Note that I already fixed this for per-node areas since those do end up
with no allocations with movable_node set [0].
[0] https://lore.kernel.org/kexec/20261014131547.259138-1-pratyush@kernel.org/
[...]
--
Regards,
Pratyush Yadav
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH] kho: Skip zero-sized bootmem areas
2026-10-26 14:22 ` Pratyush Yadav
@ 2026-10-27 7:40 ` Chen Pei
2026-11-04 12:35 ` Pratyush Yadav
0 siblings, 1 reply; 5+ messages in thread
From: Chen Pei @ 2026-10-27 7:40 UTC (permalink / raw)
To: pratyush; +Cc: graf, kexec, linux-kernel, linux-mm, pasha.tatashin, rppt
> Do you see zero sized lowmem or global scratch in practice? If yes,
> how? What's your setup?
Yes. Enabling KHO for riscv64 gave me three cases. They differ in which
size ends up 0 and in what it costs, and all three are measured:
# condition size cost
1 all memory below the limit global empty area kept
2 no memory below the limit lowmem KHO off
3 kho_bootmem= with explicit 0 either empty area kept
Case 1, measured with a temporary pr_info(), not part of the patch.
riscv64 defconfig plus KEXEC_HANDOVER, cmdline "kho=on", four RAM sizes:
mem reserved_low reserved_any lowmem global
1G 0x32d3ea5 0x32d3ea5 0x6800000 0x0
2G 0x4557164 0x4557165 0x8c00000 0x400000
4G 0x4000000 0xa7116e5 0x8000000 0xd000000
8G 0x4000000 0xed121e5 0x8000000 0x15c00000
riscv does not define ARCH_LOW_ADDRESS_LIMIT, so it uses the 0xffffffff
default and every reservation is below it; the two queries then agree
and the global size is a number scaled minus itself. The 1 GiB case is
exactly 0, and from 2 GiB up a single byte of difference between the two
queries is enough to leave the 4 MiB minimum after rounding up. The 0 is
recorded, not just computed - /sys/kernel/debug/kho/out/ on an
unpatched 1 GiB configuration reads
bootmem_phys: 0xb6400000 0xbcc00000 0xa2c00000
bootmem_len: 0x6800000 0x0 0x13800000
with the middle pair gone after the patch.
Case 2 is the one that actually costs something. On a riscv64 platform
whose memory all starts above the 0xffffffff default limit, unpatched
and with memblock=debug:
memblock_phys_alloc_range: 0 bytes align=0x400000 from=0x0
max_addr=0x00000000ffffffff
KHO: Failed to reserve lowmem bootmem
KHO: Failed to reserve bootmem, disabling kexec handover
The size is 0 because nothing is reserved below a limit that has no
memory under it, and the range below the limit is empty as well, so the
allocation returns 0 and kho_enable is cleared. KHO ends up off on a
machine that needed no lowmem area at all, and /sys/kernel/debug/kho is
not there. With the skip the same machine comes up with two areas and no
error:
bootmem_phys: 0x1000f3400000 0x1000ca000000
bootmem_len: 0xdc00000 0x29400000
Case 3 is a cheap way to reproduce the recording of an empty area on any
architecture: the parser rejects the explicit sizes only when their sum
is 0, so "kho_bootmem=0,128M,128M" is accepted and the zero reaches the
allocator. On an unpatched kernel it gives
bootmem_phys: 0xbcc00000 0xb4c00000 0xacc00000
bootmem_len: 0x0 0x8000000 0x8000000
and with the patch it stops at the two real areas.
> Note that I already fixed this for per-node areas since those do end
> up with no allocations with movable_node set [0].
That one covers the per-node loop only; lowmem and global are still
unconditional in linux-next today, which is what cases 1, 2 and 3 above
are about. Is there anything I have not considered here? Please point
it out and I will follow up accordingly.
Best regards,
Chen
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH] kho: Skip zero-sized bootmem areas
2026-10-27 7:40 ` Chen Pei
@ 2026-11-04 12:35 ` Pratyush Yadav
2026-11-04 13:39 ` Chen Pei
0 siblings, 1 reply; 5+ messages in thread
From: Pratyush Yadav @ 2026-11-04 12:35 UTC (permalink / raw)
To: Chen Pei
Cc: pratyush, graf, kexec, linux-kernel, linux-mm, pasha.tatashin, rppt
Hi Chen,
On Tue, Oct 27 2026, Chen Pei wrote:
>> Do you see zero sized lowmem or global scratch in practice? If yes,
>> how? What's your setup?
>
> Yes. Enabling KHO for riscv64 gave me three cases. They differ in which
> size ends up 0 and in what it costs, and all three are measured:
[...]
>
>> Note that I already fixed this for per-node areas since those do end
>> up with no allocations with movable_node set [0].
>
> That one covers the per-node loop only; lowmem and global are still
> unconditional in linux-next today, which is what cases 1, 2 and 3 above
> are about. Is there anything I have not considered here? Please point
> it out and I will follow up accordingly.
Mike sent out [0] recently which should fix this problem. Please take a
look at that, and see if it works for you.
[0] https://lore.kernel.org/kexec/20261103-kho-bootmem-sizing-v1-1-45aa74098f34@kernel.org/
--
Regards,
Pratyush Yadav
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] kho: Skip zero-sized bootmem areas
2026-11-04 12:35 ` Pratyush Yadav
@ 2026-11-04 13:39 ` Chen Pei
0 siblings, 0 replies; 5+ messages in thread
From: Chen Pei @ 2026-11-04 13:39 UTC (permalink / raw)
To: pratyush; +Cc: graf, kexec, linux-kernel, linux-mm, pasha.tatashin, rppt
> Mike sent out [0] recently which should fix this problem. Please take a
> look at that, and see if it works for you.
Yes, that covers it. The zero check sits in the one helper all three
allocations go through, so the three cases in my other mail are all
handled and my patch is not needed - please consider it withdrawn, there
is no competing change from my side.
Thanks for pointing me at it, and thanks Mike for picking this up.
Best regards,
Chen
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-11-04 13:41 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-26 13:18 [PATCH] kho: Skip zero-sized bootmem areas Chen Pei
2026-10-26 14:22 ` Pratyush Yadav
2026-10-27 7:40 ` Chen Pei
2026-11-04 12:35 ` Pratyush Yadav
2026-11-04 13:39 ` Chen Pei
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®