summaryrefslogtreecommitdiff
path: root/mm/memory_hotplug.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-04-18 10:45:02 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-04-18 10:45:02 +0200
commit6e93ccc29258103e1fc652464b4ff75bc022da73 (patch)
tree85f741fa600ee0745b818a8c9cfdfc9b5b824c86 /mm/memory_hotplug.c
parent327d73d5ef3ac25ffb58648c2c588c897b7efc41 (diff)
parent47a33eea6d5145d53e42315381ef28286c2218fb (diff)
Merge v6.18.23linux-rolling-lts
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'mm/memory_hotplug.c')
-rw-r--r--mm/memory_hotplug.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 0be83039c3b5e..aa1f744143077 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -1218,6 +1218,13 @@ int online_pages(unsigned long pfn, unsigned long nr_pages,
if (node_arg.nid >= 0)
node_set_state(nid, N_MEMORY);
+ /*
+ * Check whether we are adding normal memory to the node for the first
+ * time.
+ */
+ if (!node_state(nid, N_NORMAL_MEMORY) && zone_idx(zone) <= ZONE_NORMAL)
+ node_set_state(nid, N_NORMAL_MEMORY);
+
if (need_zonelists_rebuild)
build_all_zonelists(NULL);
@@ -1919,6 +1926,8 @@ int offline_pages(unsigned long start_pfn, unsigned long nr_pages,
unsigned long flags;
char *reason;
int ret;
+ unsigned long normal_pages = 0;
+ enum zone_type zt;
/*
* {on,off}lining is constrained to full memory sections (or more
@@ -2067,6 +2076,17 @@ int offline_pages(unsigned long start_pfn, unsigned long nr_pages,
init_per_zone_wmark_min();
/*
+ * Check whether this operation removes the last normal memory from
+ * the node. We do this before clearing N_MEMORY to avoid the possible
+ * transient "!N_MEMORY && N_NORMAL_MEMORY" state.
+ */
+ if (zone_idx(zone) <= ZONE_NORMAL) {
+ for (zt = 0; zt <= ZONE_NORMAL; zt++)
+ normal_pages += pgdat->node_zones[zt].present_pages;
+ if (!normal_pages)
+ node_clear_state(node, N_NORMAL_MEMORY);
+ }
+ /*
* Make sure to mark the node as memory-less before rebuilding the zone
* list. Otherwise this node would still appear in the fallback lists.
*/