From: Qiqi Liu The memory tier subsystem tracks node-to-tier relationships via pglist_data::memtier, which is an RCU-protected pointer. This makes it unsuitable for lockless, low-overhead contexts. Introduce pglist_data::node_tier_id to cache the stable memory tier dev.id for each NUMA node. The field is updated together with pgdat->memtier and can be safely read using READ_ONCE() from any context. Key properties: - Stable across tier reconfiguration - Safe for lockless readers - Does not require RCU protection - Complements, but does not replace, pglist_data::memtier This is infrastructure work. Future consumers can build on top of this mechanism. No functional change intended. Signed-off-by: Qiqi Liu --- include/linux/mmzone.h | 2 ++ mm/memory-tiers.c | 4 +++- mm/mm_init.c | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 9adb2ad21da5..6b5a6da3f821 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -1605,6 +1605,8 @@ typedef struct pglist_data { atomic_long_t vm_stat[NR_VM_NODE_STAT_ITEMS]; #ifdef CONFIG_NUMA struct memory_tier __rcu *memtier; + /* stable tier dev.id, lockless, hot-path safe. */ + int node_tier_id; #endif #ifdef CONFIG_MEMORY_FAILURE struct memory_failure_stats mf_stats; diff --git a/mm/memory-tiers.c b/mm/memory-tiers.c index 54851d8a195b..cfb3aa56b4c3 100644 --- a/mm/memory-tiers.c +++ b/mm/memory-tiers.c @@ -566,8 +566,10 @@ static struct memory_tier *set_node_memory_tier(int node) memtype = node_memory_types[node].memtype; node_set(node, memtype->nodes); memtier = find_create_memory_tier(memtype); - if (!IS_ERR(memtier)) + if (!IS_ERR(memtier)) { rcu_assign_pointer(pgdat->memtier, memtier); + pgdat->node_tier_id = memtier->dev.id; + } return memtier; } diff --git a/mm/mm_init.c b/mm/mm_init.c index f9f8e1af921c..db72456fb14c 100644 --- a/mm/mm_init.c +++ b/mm/mm_init.c @@ -1711,6 +1711,7 @@ static void __init free_area_init_node(int nid) pgdat->node_id = nid; pgdat->node_start_pfn = start_pfn; pgdat->per_cpu_nodestats = NULL; + pgdat->node_tier_id = -1; if (start_pfn != end_pfn) { pr_info("Initmem setup node %d [mem %#018Lx-%#018Lx]\n", nid, -- 2.25.1