[RFC PATCH v2 08/11] mm/memory_hotplug: add MHP_SPM_NODE flag
From: Gregory Price
Date: Wed Nov 12 2025 - 14:30:13 EST
Add support for Specific Purpose Memory (SPM) NUMA nodes.
A SPM node is managed by the page allocator, but can only allocated
by using the __GFP_SP_NODE flag with an appropriate nodemask.
Check/Set the node type (SysRAM vs SPM) at hotplug time.
Disallow SPM from being added to SysRAM nodes and vice-versa.
This prevents normal allocation paths (page faults, kmalloc, etc)
from being directly exposed to these memories, and provides a clear
integration point for buddy-allocation of SPM memory.
Signed-off-by: Gregory Price <gourry@xxxxxxxxxx>
---
include/linux/memory_hotplug.h | 10 ++++++++++
mm/memory_hotplug.c | 7 +++++++
2 files changed, 17 insertions(+)
diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
index 23f038a16231..a50c467951ba 100644
--- a/include/linux/memory_hotplug.h
+++ b/include/linux/memory_hotplug.h
@@ -74,6 +74,16 @@ typedef int __bitwise mhp_t;
* helpful in low-memory situations.
*/
#define MHP_OFFLINE_INACCESSIBLE ((__force mhp_t)BIT(3))
+/*
+ * The hotplugged memory can only be added to a "Specific Purpose Memory"
+ * NUMA node. SPM Nodes are not generally accessible by the page allocator
+ * by way of userland configuration - as most nodemask interfaces
+ * (mempolicy, cpusets) restrict nodes to SysRAM nodes.
+ *
+ * Hotplugging SPM into a SysRAM Node results in -EINVAL.
+ * Hotplugging SysRAM into a SPM Node results in -EINVAL.
+ */
+#define MHP_SPM_NODE ((__force mhp_t)BIT(4))
/*
* Extended parameters for memory hotplug:
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 0be83039c3b5..488cdd8e5f6f 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -20,6 +20,7 @@
#include <linux/memory.h>
#include <linux/memremap.h>
#include <linux/memory_hotplug.h>
+#include <linux/memory-tiers.h>
#include <linux/vmalloc.h>
#include <linux/ioport.h>
#include <linux/delay.h>
@@ -1529,6 +1530,12 @@ int add_memory_resource(int nid, struct resource *res, mhp_t mhp_flags)
mem_hotplug_begin();
+ /* Set the NUMA node type and bail out if the type is wrong */
+ ret = mt_set_node_type(nid, (mhp_flags & MHP_SPM_NODE) ?
+ MT_NODE_TYPE_SPM : MT_NODE_TYPE_SYSRAM);
+ if (ret)
+ goto error_mem_hotplug_end;
+
if (IS_ENABLED(CONFIG_ARCH_KEEP_MEMBLOCK)) {
if (res->flags & IORESOURCE_SYSRAM_DRIVER_MANAGED)
memblock_flags = MEMBLOCK_DRIVER_MANAGED;
--
2.51.1