All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH] mm/memory_hotplug: use public nodes for migration targets
@ 2026-09-14  7:43 Zimo.Lu
  2026-09-14  7:58 ` sashiko-bot
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Zimo.Lu @ 2026-09-14  7:43 UTC (permalink / raw)
  To: Gregory Price
  Cc: David Hildenbrand, Oscar Salvador, Andrew Morton, linux-mm,
	linux-cxl, linux-kernel

do_migrate_range() excludes the source node from node_states[N_MEMORY]
and adds it back only when the nmask is empty. With private nodes in
N_MEMORY, this can leave a nonempty nmask containing only private nodes,
when the system has only one public node and others are private nodes.
Ordinary migration allocations use the public fallback zonelist, so none
of those nodes can satisfy the allocation.

Build the nmask from N_MEMORY_PUBLIC so that private nodes do not prevent
this fallback.

For HugeTLB migration during memory offlining, this also excludes other
private nodes from the nmask when the source node is private and public
nodes are present.

Signed-off-by: Zimo.Lu <louis2665573906@gmail.com>
Assisted-by: LLM
---
Should we use public targets for private-source HugeTLB migration during
memory offlining as well, or should this fix be limited to the same-node
fallback problem on a public source node?

Based on the author's node_features_v6 WIP snapshot (base below).
This is not a patch against mainline or the posted v5 series.
Private-source HugeTLB migration has not been tested.

 mm/memory_hotplug.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 22d20ee96bb1..8a95ba26552d 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -1937,7 +1937,7 @@ put_folio:
 		folio_put(folio);
 	}
 	if (!list_empty(&source)) {
-		nodemask_t nmask = node_states[N_MEMORY];
+		nodemask_t nmask = node_states[N_MEMORY_PUBLIC];
 		struct migration_target_control mtc = {
 			.nmask = &nmask,
 			.gfp_mask = GFP_KERNEL | __GFP_MOVABLE | __GFP_RETRY_MAYFAIL,
@@ -1953,8 +1953,8 @@ put_folio:
 
 		/*
 		 * try to allocate from a different node but reuse this node
-		 * if there are no other online nodes to be used (e.g. we are
-		 * offlining a part of the only existing node)
+		 * if there are no other public nodes to be used (e.g. we are
+		 * offlining a part of the only public node)
 		 */
 		node_clear(mtc.nid, nmask);
 		if (nodes_empty(nmask))

base-commit: 38c7f48162aa282dc6a9edfb7011378594057c10

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [RFC PATCH] mm/memory_hotplug: use public nodes for migration targets
  2026-09-14  7:43 [RFC PATCH] mm/memory_hotplug: use public nodes for migration targets Zimo.Lu
@ 2026-09-14  7:58 ` sashiko-bot
  2026-09-14  8:40 ` David Hildenbrand (Arm)
  2026-09-14 14:38 ` Gregory Price
  2 siblings, 0 replies; 4+ messages in thread
From: sashiko-bot @ 2026-09-14  7:58 UTC (permalink / raw)
  To: Zimo.Lu; +Cc: linux-cxl

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:

New issues:
- [Medium] Restricting the migration target nodemask to N_MEMORY_PUBLIC prevents HugeTLB folios from migrating between private nodes.
- [Low] N_MEMORY_PUBLIC is undeclared, causing a build failure.

Pre-existing issues:
- [High] Infinite loop during memory offlining when encountering a hwpoisoned large folio.
- [High] HWPoisoned folios are permanently leaked from the LRU and their refcounts are permanently elevated during memory hotplug offlining.
--

commit a396d55b92bfae38e85ebc68194e34af029a9db7
Author: Zimo.Lu <louis2665573906@gmail.com>

mm/memory_hotplug: use public nodes for migration targets

This commit modifies do_migrate_range() to use N_MEMORY_PUBLIC for the
migration target nodemask instead of N_MEMORY. This aims to prevent
private nodes from blocking fallback to public nodes when allocating
migration targets, which also impacts HugeTLB migration targets during
memory offlining.

> diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
> index d7a59167bec43..683925183df6b 100644
> --- a/mm/memory_hotplug.c
> +++ b/mm/memory_hotplug.c
> @@ -1928,7 +1928,7 @@ static void do_migrate_range(unsigned long start_pfn, unsigned long end_pfn)

[Severity: High]
This is a pre-existing issue, but does skipping poisoned large folios earlier
in do_migrate_range() cause a livelock?

During memory offlining, skipping the folio without splitting it means
isolation fails and the folio is never handled:

		if (folio_contain_hwpoisoned_page(folio)) {
			/*
			 * unmap_poisoned_folio() cannot handle large folios
			 * in all cases yet.
			 */
			if (folio_test_large(folio) && !folio_test_hugetlb(folio))
				goto put_folio;

This causes test_pages_isolated() to fail, which forces the outer do-while
loop in offline_pages() to retry indefinitely, holding global hotplug locks
and causing a system-wide denial of service.

Can this be fixed by splitting the large folio before evaluating
unmap_poisoned_folio()?

[Severity: High]
This is also a pre-existing issue, but does this leak the isolation reference
and permanently elevate the folio refcount for hwpoisoned folios?

When folio_isolate_lru() succeeds, it removes the folio from the LRU and
takes an isolation reference:

			if (folio_test_lru(folio) && !folio_isolate_lru(folio))
				goto put_folio;
			if (folio_mapped(folio)) {
				folio_lock(folio);
				unmap_poisoned_folio(folio, pfn, false);
				folio_unlock(folio);
			}

			goto put_folio;
		}

By jumping to put_folio, the code drops only the initial reference from
folio_try_get():

>  		folio_put(folio);

This leaves the isolation reference permanently leaked and the folio
permanently off the LRU list, preventing the memory block from being offlined.

>  	}
>  	if (!list_empty(&source)) {
> -		nodemask_t nmask = node_states[N_MEMORY];
> +		nodemask_t nmask = node_states[N_MEMORY_PUBLIC];

[Severity: Low]
Does this cause a build failure? N_MEMORY_PUBLIC is undeclared in the kernel
source, causing compilation to fail.

[Severity: Medium]
Does restricting this nodemask to N_MEMORY_PUBLIC break HugeTLB migration
between private nodes?

Since alloc_hugetlb_folio_nodemask() strictly iterates the provided nmask,
initializing it to N_MEMORY_PUBLIC strips out all private nodes as potential
targets.

If a private node with HugeTLB pages is offlined, and public nodes lack
sufficient HugeTLB pages, offlining will fail even if other private nodes
could accept them.

>  		struct migration_target_control mtc = {
>  			.nmask = &nmask,
>  			.gfp_mask = GFP_KERNEL | __GFP_MOVABLE | __GFP_RETRY_MAYFAIL,

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260914074323.3567923-1-louis2665573906@gmail.com?part=1

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RFC PATCH] mm/memory_hotplug: use public nodes for migration targets
  2026-09-14  7:43 [RFC PATCH] mm/memory_hotplug: use public nodes for migration targets Zimo.Lu
  2026-09-14  7:58 ` sashiko-bot
@ 2026-09-14  8:40 ` David Hildenbrand (Arm)
  2026-09-14 14:38 ` Gregory Price
  2 siblings, 0 replies; 4+ messages in thread
From: David Hildenbrand (Arm) @ 2026-09-14  8:40 UTC (permalink / raw)
  To: Zimo.Lu, Gregory Price
  Cc: Oscar Salvador, Andrew Morton, linux-mm, linux-cxl, linux-kernel

On 9/14/26 09:43, Zimo.Lu wrote:
> do_migrate_range() excludes the source node from node_states[N_MEMORY]
> and adds it back only when the nmask is empty. With private nodes in
> N_MEMORY, this can leave a nonempty nmask containing only private nodes,
> when the system has only one public node and others are private nodes.
> Ordinary migration allocations use the public fallback zonelist, so none
> of those nodes can satisfy the allocation.
> 
> Build the nmask from N_MEMORY_PUBLIC so that private nodes do not prevent
> this fallback.
> 
> For HugeTLB migration during memory offlining, this also excludes other
> private nodes from the nmask when the source node is private and public
> nodes are present.
> 
> Signed-off-by: Zimo.Lu <louis2665573906@gmail.com>
> Assisted-by: LLM
> ---

This should be discussed in the relevant patch set.

-- 
Cheers,

David

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RFC PATCH] mm/memory_hotplug: use public nodes for migration targets
  2026-09-14  7:43 [RFC PATCH] mm/memory_hotplug: use public nodes for migration targets Zimo.Lu
  2026-09-14  7:58 ` sashiko-bot
  2026-09-14  8:40 ` David Hildenbrand (Arm)
@ 2026-09-14 14:38 ` Gregory Price
  2 siblings, 0 replies; 4+ messages in thread
From: Gregory Price @ 2026-09-14 14:38 UTC (permalink / raw)
  To: Zimo.Lu
  Cc: David Hildenbrand, Oscar Salvador, Andrew Morton, linux-mm,
	linux-cxl, linux-kernel

On Mon, Sep 14, 2026 at 03:43:22PM +0800, Zimo.Lu wrote:
> base-commit: 38c7f48162aa282dc6a9edfb7011378594057c10

This commit is a random github hash from my v6 working branch that no
one cares to (or should) know about.

I haven't even RFC'd this to the list yet.

I'm happy to work with you if you have feedback, but you're getting well
ahead of the work here.

~Gregory

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-09-14 14:38 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-14  7:43 [RFC PATCH] mm/memory_hotplug: use public nodes for migration targets Zimo.Lu
2026-09-14  7:58 ` sashiko-bot
2026-09-14  8:40 ` David Hildenbrand (Arm)
2026-09-14 14:38 ` Gregory Price

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.