* [PATCH] mm/memblock: Introduce memblock_alloc_node_or_panic() helper
@ 2026-06-04 3:41 Zhen Ni
2026-06-04 5:44 ` Mike Rapoport
0 siblings, 1 reply; 2+ messages in thread
From: Zhen Ni @ 2026-06-04 3:41 UTC (permalink / raw)
To: Yoshinori Sato, Rich Felker, John Paul Adrian Glaubitz,
David S. Miller, Andreas Larsson, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, x86, H. Peter Anvin, Mike Rapoport,
Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Suren Baghdasaryan,
Michal Hocko
Cc: linux-sh, linux-kernel, sparclinux, linux-mm, Zhen Ni
During early boot, several subsystems allocate memory from specific
NUMA nodes using memblock_alloc_node(). When allocation fails, the
typical requirement is to panic immediately.
Introduce memblock_alloc_node_or_panic() to automatically panic on
allocation failure. This reduces repetitive error checking, improves code
consistency across subsystems, and enhances code readability.
Signed-off-by: Zhen Ni <zhen.ni@easystack.cn>
---
arch/sh/mm/numa.c | 10 ++++------
arch/sparc/kernel/setup_64.c | 16 ++++++----------
arch/x86/coco/sev/core.c | 5 ++---
include/linux/memblock.h | 6 ++++++
mm/memblock.c | 22 ++++++++++++++++++++++
mm/mm_init.c | 11 ++++-------
mm/sparse.c | 13 +++++--------
7 files changed, 49 insertions(+), 34 deletions(-)
diff --git a/arch/sh/mm/numa.c b/arch/sh/mm/numa.c
index 9bc212b5e762..32b01697b27f 100644
--- a/arch/sh/mm/numa.c
+++ b/arch/sh/mm/numa.c
@@ -38,12 +38,10 @@ void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end)
__add_active_range(nid, start_pfn, end_pfn);
/* Node-local pgdat */
- NODE_DATA(nid) = memblock_alloc_node(sizeof(struct pglist_data),
- SMP_CACHE_BYTES, nid);
- if (!NODE_DATA(nid))
- panic("%s: Failed to allocate %zu bytes align=0x%x nid=%d\n",
- __func__, sizeof(struct pglist_data), SMP_CACHE_BYTES,
- nid);
+ NODE_DATA(nid) = memblock_alloc_node_or_panic(
+ sizeof(struct pglist_data),
+ SMP_CACHE_BYTES,
+ nid);
NODE_DATA(nid)->node_start_pfn = start_pfn;
NODE_DATA(nid)->node_spanned_pages = end_pfn - start_pfn;
diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c
index 63615f5c99b4..57e3a45f4750 100644
--- a/arch/sparc/kernel/setup_64.c
+++ b/arch/sparc/kernel/setup_64.c
@@ -606,16 +606,12 @@ static void __init alloc_irqstack_bootmem(void)
for_each_possible_cpu(i) {
node = cpu_to_node(i);
- softirq_stack[i] = memblock_alloc_node(THREAD_SIZE,
- THREAD_SIZE, node);
- if (!softirq_stack[i])
- panic("%s: Failed to allocate %lu bytes align=%lx nid=%d\n",
- __func__, THREAD_SIZE, THREAD_SIZE, node);
- hardirq_stack[i] = memblock_alloc_node(THREAD_SIZE,
- THREAD_SIZE, node);
- if (!hardirq_stack[i])
- panic("%s: Failed to allocate %lu bytes align=%lx nid=%d\n",
- __func__, THREAD_SIZE, THREAD_SIZE, node);
+ softirq_stack[i] = memblock_alloc_node_or_panic(THREAD_SIZE,
+ THREAD_SIZE,
+ node);
+ hardirq_stack[i] = memblock_alloc_node_or_panic(THREAD_SIZE,
+ THREAD_SIZE,
+ node);
}
}
diff --git a/arch/x86/coco/sev/core.c b/arch/x86/coco/sev/core.c
index 7ed3da998489..0191835dd5de 100644
--- a/arch/x86/coco/sev/core.c
+++ b/arch/x86/coco/sev/core.c
@@ -1191,9 +1191,8 @@ static void __init alloc_runtime_data(int cpu)
{
struct sev_es_runtime_data *data;
- data = memblock_alloc_node(sizeof(*data), PAGE_SIZE, cpu_to_node(cpu));
- if (!data)
- panic("Can't allocate SEV-ES runtime data");
+ data = memblock_alloc_node_or_panic(sizeof(*data), PAGE_SIZE,
+ cpu_to_node(cpu));
per_cpu(runtime_data, cpu) = data;
diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index b0f750d22a7b..9b22d7fc0dc7 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -433,6 +433,12 @@ void *__memblock_alloc_or_panic(phys_addr_t size, phys_addr_t align,
#define memblock_alloc_or_panic(size, align) \
__memblock_alloc_or_panic(size, align, __func__)
+void *__memblock_alloc_node_or_panic(phys_addr_t size, phys_addr_t align,
+ int nid, const char *func);
+
+#define memblock_alloc_node_or_panic(size, align, nid) \
+ __memblock_alloc_node_or_panic(size, align, nid, __func__)
+
static inline void *memblock_alloc_raw(phys_addr_t size,
phys_addr_t align)
{
diff --git a/mm/memblock.c b/mm/memblock.c
index ccd43f3abb82..2e97cd6d21a1 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -1845,6 +1845,28 @@ void *__init __memblock_alloc_or_panic(phys_addr_t size, phys_addr_t align,
return addr;
}
+/**
+ * __memblock_alloc_node_or_panic - Try to allocate memory on a node and panic on failure
+ * @size: size of memory block to be allocated in bytes
+ * @align: alignment of the region and block's size
+ * @nid: nid of the free area to find, %NUMA_NO_NODE for any node
+ * @func: caller func name
+ *
+ * This function attempts to allocate memory on a specific node using memblock_alloc_node,
+ * and in case of failure, it calls panic with the formatted message.
+ * This function should not be used directly, please use the macro memblock_alloc_node_or_panic.
+ */
+void *__init __memblock_alloc_node_or_panic(phys_addr_t size, phys_addr_t align,
+ int nid, const char *func)
+{
+ void *addr = memblock_alloc_node(size, align, nid);
+
+ if (unlikely(!addr))
+ panic("%s: Failed to allocate %pap bytes on node %d\n",
+ func, &size, nid);
+ return addr;
+}
+
/*
* Remaining API functions
*/
diff --git a/mm/mm_init.c b/mm/mm_init.c
index f9f8e1af921c..7c69056c1a8c 100644
--- a/mm/mm_init.c
+++ b/mm/mm_init.c
@@ -1477,14 +1477,11 @@ static void __ref setup_usemap(struct zone *zone)
unsigned long usemapsize = usemap_size(zone->zone_start_pfn,
zone->spanned_pages);
zone->pageblock_flags = NULL;
- if (usemapsize) {
+ if (usemapsize)
zone->pageblock_flags =
- memblock_alloc_node(usemapsize, SMP_CACHE_BYTES,
- zone_to_nid(zone));
- if (!zone->pageblock_flags)
- panic("Failed to allocate %ld bytes for zone %s pageblock flags on node %d\n",
- usemapsize, zone->name, zone_to_nid(zone));
- }
+ memblock_alloc_node_or_panic(usemapsize,
+ SMP_CACHE_BYTES,
+ zone_to_nid(zone));
}
#else
static inline void setup_usemap(struct zone *zone) {}
diff --git a/mm/sparse.c b/mm/sparse.c
index effdac6b0ab1..c7c80783b6be 100644
--- a/mm/sparse.c
+++ b/mm/sparse.c
@@ -66,15 +66,12 @@ static noinline struct mem_section __ref *sparse_index_alloc(int nid)
unsigned long array_size = SECTIONS_PER_ROOT *
sizeof(struct mem_section);
- if (slab_is_available()) {
+ if (slab_is_available())
section = kzalloc_node(array_size, GFP_KERNEL, nid);
- } else {
- section = memblock_alloc_node(array_size, SMP_CACHE_BYTES,
- nid);
- if (!section)
- panic("%s: Failed to allocate %lu bytes nid=%d\n",
- __func__, array_size, nid);
- }
+ else
+ section = memblock_alloc_node_or_panic(array_size,
+ SMP_CACHE_BYTES,
+ nid);
return section;
}
--
2.20.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] mm/memblock: Introduce memblock_alloc_node_or_panic() helper
2026-06-04 3:41 [PATCH] mm/memblock: Introduce memblock_alloc_node_or_panic() helper Zhen Ni
@ 2026-06-04 5:44 ` Mike Rapoport
0 siblings, 0 replies; 2+ messages in thread
From: Mike Rapoport @ 2026-06-04 5:44 UTC (permalink / raw)
To: Zhen Ni
Cc: Yoshinori Sato, Rich Felker, John Paul Adrian Glaubitz,
David S. Miller, Andreas Larsson, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, x86, H. Peter Anvin, Andrew Morton,
David Hildenbrand, Lorenzo Stoakes, Liam R. Howlett,
Vlastimil Babka, Suren Baghdasaryan, Michal Hocko, linux-sh,
linux-kernel, sparclinux, linux-mm
On Thu, Jun 04, 2026 at 11:41:39AM +0800, Zhen Ni wrote:
> During early boot, several subsystems allocate memory from specific
> NUMA nodes using memblock_alloc_node(). When allocation fails, the
> typical requirement is to panic immediately.
>
> Introduce memblock_alloc_node_or_panic() to automatically panic on
> allocation failure. This reduces repetitive error checking, improves code
> consistency across subsystems, and enhances code readability.
memblock_alloc_or_panic() made sense because it's the most used memblock
API.
Adding panic() versions for a handful of uses is unnecessary churn.
A better patch would be to update panic() messages to convey more useful
information.
> Signed-off-by: Zhen Ni <zhen.ni@easystack.cn>
> ---
> arch/sh/mm/numa.c | 10 ++++------
> arch/sparc/kernel/setup_64.c | 16 ++++++----------
> arch/x86/coco/sev/core.c | 5 ++---
> include/linux/memblock.h | 6 ++++++
> mm/memblock.c | 22 ++++++++++++++++++++++
> mm/mm_init.c | 11 ++++-------
> mm/sparse.c | 13 +++++--------
> 7 files changed, 49 insertions(+), 34 deletions(-)
>
> diff --git a/arch/sh/mm/numa.c b/arch/sh/mm/numa.c
> index 9bc212b5e762..32b01697b27f 100644
> --- a/arch/sh/mm/numa.c
> +++ b/arch/sh/mm/numa.c
> @@ -38,12 +38,10 @@ void __init setup_bootmem_node(int nid, unsigned long start, unsigned long end)
> __add_active_range(nid, start_pfn, end_pfn);
>
> /* Node-local pgdat */
> - NODE_DATA(nid) = memblock_alloc_node(sizeof(struct pglist_data),
> - SMP_CACHE_BYTES, nid);
> - if (!NODE_DATA(nid))
> - panic("%s: Failed to allocate %zu bytes align=0x%x nid=%d\n",
> - __func__, sizeof(struct pglist_data), SMP_CACHE_BYTES,
> - nid);
> + NODE_DATA(nid) = memblock_alloc_node_or_panic(
> + sizeof(struct pglist_data),
> + SMP_CACHE_BYTES,
> + nid);
Please don't touch this, the entire file is going away after rc1.
>
> NODE_DATA(nid)->node_start_pfn = start_pfn;
> NODE_DATA(nid)->node_spanned_pages = end_pfn - start_pfn;
--
Sincerely yours,
Mike.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-06-04 5:44 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-04 3:41 [PATCH] mm/memblock: Introduce memblock_alloc_node_or_panic() helper Zhen Ni
2026-06-04 5:44 ` Mike Rapoport
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox