Re: [PATCH] mm/memory-tiers: reset demotion targets of nodes without memory

From: Zi Yan

Date: Mon Oct 19 2026 - 15:08:07 EST


On Mon Oct 19, 2026 at 2:47 PM EDT, Gregory Price (Meta) wrote:
> When a node loses its last memory, offline_pages() clears N_MEMORY
> before the memory-tier callback rebuilds the demotion targets.
> disable_all_demotion_targets() resets only N_MEMORY nodes, so the node
> keeps its old node_demotion[] entry while it has no memory. Before
> 6c542ab75714, the reset covered every online node.

establish_demotion_targets() uses for_each_node_state(node, N_MEMORY),
because the to-be-online node is already added into N_MEMORY?

>
> A reclaimer reads the stale entry only between the node regaining memory
> and its targets being rebuilt, and it filters the entry against the
> current allowed targets, so there is no user-visible effect. To see it,
> online and then offline a node's only DIMM: a debugger still finds the
> lower-tier node in node_demotion[nid].preferred.
>
> Reset the targets of every node.
>
> Fixes: 6c542ab75714 ("mm/demotion: build demotion targets based on explicit memory tiers")
> Signed-off-by: Gregory Price (Meta) <gourry@xxxxxxxxxx>
> ---
> mm/memory-tiers.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/mm/memory-tiers.c b/mm/memory-tiers.c
> index 25e121851b586..7197f1a67a340 100644
> --- a/mm/memory-tiers.c
> +++ b/mm/memory-tiers.c
> @@ -378,7 +378,7 @@ static void disable_all_demotion_targets(void)
> struct memory_tier *memtier;
> int node;
>
> - for_each_node_state(node, N_MEMORY) {
> + for_each_node(node) {

I think the above code deserves a comment explaining why for_each_node()
is needed instead of for_each_node_state(N_MEMORY), because when a node
is added or removed during memory hotadd or hotremove matters here.

> node_demotion[node].preferred = NODE_MASK_NONE;
> /*
> * We are holding memory_tier_lock, it is safe


--
Best Regards,
Yan, Zi