Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

kho: skip memoryless NUMA nodes when reserving scratch areas

kho_reserve_scratch() iterates over all online NUMA nodes to allocate
per-node scratch memory. On systems with memoryless NUMA nodes (nodes
that have CPUs but no memory), memblock_alloc_range_nid() fails because
there is no memory available on that node. This causes KHO initialization
to fail and kho_enable to be set to false.

Some ARM64 systems have NUMA topologies where certain nodes contain only
CPUs without any associated memory. These configurations are valid and
should not prevent KHO from functioning.

Fix this by only counting nodes that have memory (N_MEMORY state) and skip
memoryless nodes in the per-node scratch allocation loop.

Link: https://lkml.kernel.org/r/20260120175913.34368-1-epetron@amazon.de
Fixes: 3dc92c311498 ("kexec: add Kexec HandOver (KHO) generation helpers").
Signed-off-by: Evangelos Petrongonas <epetron@amazon.de>
Reviewed-by: Pratyush Yadav <pratyush@kernel.org>
Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Reviewed-by: Pasha Tatashin <pasha.tatashin@soleen.com>
Cc: Alexander Graf <graf@amazon.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Evangelos Petrongonas and committed by
Andrew Morton
427b2535 96a54b8f

+6 -2
+6 -2
kernel/liveupdate/kexec_handover.c
··· 655 655 scratch_size_update(); 656 656 657 657 /* FIXME: deal with node hot-plug/remove */ 658 - kho_scratch_cnt = num_online_nodes() + 2; 658 + kho_scratch_cnt = nodes_weight(node_states[N_MEMORY]) + 2; 659 659 size = kho_scratch_cnt * sizeof(*kho_scratch); 660 660 kho_scratch = memblock_alloc(size, PAGE_SIZE); 661 661 if (!kho_scratch) { ··· 691 691 kho_scratch[i].size = size; 692 692 i++; 693 693 694 - for_each_online_node(nid) { 694 + /* 695 + * Loop over nodes that have both memory and are online. Skip 696 + * memoryless nodes, as we can not allocate scratch areas there. 697 + */ 698 + for_each_node_state(nid, N_MEMORY) { 695 699 size = scratch_size_node(nid); 696 700 addr = memblock_alloc_range_nid(size, CMA_MIN_ALIGNMENT_BYTES, 697 701 0, MEMBLOCK_ALLOC_ACCESSIBLE,