mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [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®