mirror of
https://github.com/torvalds/linux.git
synced 2026-11-09 13:44:03 +01:00
mm/memory_hotplug: factor out node_is_memoryless()
A memoryless node neither spans present pages (populated or ZONE_DEVICE) nor has an offline-but-added memory block still linked to it in sysfs. try_offline_node() presently open-codes this memoryless check. Pull that into a node_is_memoryless() helper and pull the existing check_no_memblock_for_node_cb() helper ahead of the add/online path so it's clearer what is happening here. No functional change. [akpm@linux-foundation.org: move node_is_memoryless() inside CONFIG_MEMORY_HOTREMOVE] Link: https://lore.kernel.org/20260902195507.88655-1-gourry@gourry.net Signed-off-by: Gregory Price <gourry@gourry.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Acked-by: David Hildenbrand (Arm) <david@kernel.org> Cc: Oscar Salvador <osalvador@suse.de>
This commit is contained in:
parent
0e3846146f
commit
a85a8d0327
|
|
@ -1785,6 +1785,37 @@ bool mhp_range_allowed(u64 start, u64 size, bool need_mapping)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_MEMORY_HOTREMOVE
|
||||
|
||||
static int check_no_memblock_for_node_cb(struct memory_block *mem, void *arg)
|
||||
{
|
||||
int nid = *(int *)arg;
|
||||
|
||||
/*
|
||||
* If a memory block belongs to multiple nodes, the stored nid is not
|
||||
* reliable. However, such blocks are always online (e.g., cannot get
|
||||
* offlined) and, therefore, are still spanned by the node.
|
||||
*/
|
||||
return mem->nid == nid ? -EEXIST : 0;
|
||||
}
|
||||
|
||||
/* Caller must hold the memory hotplug lock for this check. */
|
||||
static bool node_is_memoryless(int nid)
|
||||
{
|
||||
/*
|
||||
* A node still spanning pages (especially ZONE_DEVICE) is not
|
||||
* memoryless. A node spans memory after move_pfn_range_to_zone(),
|
||||
* e.g. once a memory block has been onlined.
|
||||
*/
|
||||
if (node_spanned_pages(nid))
|
||||
return false;
|
||||
/*
|
||||
* Offline memory blocks may not be spanned by the node yet, but they
|
||||
* link to it in sysfs and can be onlined later, so the node is not
|
||||
* memoryless while any remain.
|
||||
*/
|
||||
return !for_each_memory_block(&nid, check_no_memblock_for_node_cb);
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan pfn range [start,end) to find movable/migratable pages (LRU and
|
||||
* hugetlb folio, movable_ops pages). Will skip over most unmovable
|
||||
|
|
@ -2214,18 +2245,6 @@ static int check_cpu_on_node(int nid)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int check_no_memblock_for_node_cb(struct memory_block *mem, void *arg)
|
||||
{
|
||||
int nid = *(int *)arg;
|
||||
|
||||
/*
|
||||
* If a memory block belongs to multiple nodes, the stored nid is not
|
||||
* reliable. However, such blocks are always online (e.g., cannot get
|
||||
* offlined) and, therefore, are still spanned by the node.
|
||||
*/
|
||||
return mem->nid == nid ? -EEXIST : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* try_offline_node
|
||||
* @nid: the node ID
|
||||
|
|
@ -2237,23 +2256,7 @@ static int check_no_memblock_for_node_cb(struct memory_block *mem, void *arg)
|
|||
*/
|
||||
void try_offline_node(int nid)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/*
|
||||
* If the node still spans pages (especially ZONE_DEVICE), don't
|
||||
* offline it. A node spans memory after move_pfn_range_to_zone(),
|
||||
* e.g., after the memory block was onlined.
|
||||
*/
|
||||
if (node_spanned_pages(nid))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Especially offline memory blocks might not be spanned by the
|
||||
* node. They will get spanned by the node once they get onlined.
|
||||
* However, they link to the node in sysfs and can get onlined later.
|
||||
*/
|
||||
rc = for_each_memory_block(&nid, check_no_memblock_for_node_cb);
|
||||
if (rc)
|
||||
if (!node_is_memoryless(nid))
|
||||
return;
|
||||
|
||||
if (check_cpu_on_node(nid))
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user