mm: memory_hotplug: drop memoryless node from fallback lists
authorQi Zheng <zhengqi.arch@bytedance.com>
Thu, 19 Oct 2023 10:43:55 +0000 (18:43 +0800)
committerAndrew Morton <akpm@linux-foundation.org>
Wed, 25 Oct 2023 23:47:14 +0000 (16:47 -0700)
In offline_pages(), if a node becomes memoryless, we will clear its
N_MEMORY state by calling node_states_clear_node().  But we do this
after rebuilding the zonelists by calling build_all_zonelists(), which
will cause this memoryless node to still be in the fallback nodes
(node_order[]) of other nodes.

To drop memoryless nodes from fallback nodes in this case, just call
node_states_clear_node() before calling build_all_zonelists().

In this way, we will not try to allocate pages from memoryless node0,
then the panic mentioned in [1] will also be fixed.  Even though this
problem has been solved by dropping the NODE_MIN_SIZE constrain in x86
[2], it would be better to fix it in the core MM as well.

https://lore.kernel.org/all/20230212110305.93670-1-zhengqi.arch@bytedance.com/ [1]
https://lore.kernel.org/all/20231017062215.171670-1-rppt@kernel.org/ [2]

Link: https://lkml.kernel.org/r/9f1dbe7ee1301c7163b2770e32954ff5e3ecf2c4.1697711415.git.zhengqi.arch@bytedance.com
Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
Acked-by: David Hildenbrand <david@redhat.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
Cc: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Cc: "Huang, Ying" <ying.huang@intel.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Mel Gorman <mgorman@techsingularity.net>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: Vlastimil Babka <vbabka@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/memory_hotplug.c

index 3b301c4023ffc2a5a06a7643b5affad8591d8b1a..ab41a511e20a8ed054a0e79db37dc1aa25e8ecd3 100644 (file)
@@ -2012,12 +2012,16 @@ int __ref offline_pages(unsigned long start_pfn, unsigned long nr_pages,
        /* reinitialise watermarks and update pcp limits */
        init_per_zone_wmark_min();
 
+       /*
+        * Make sure to mark the node as memory-less before rebuilding the zone
+        * list. Otherwise this node would still appear in the fallback lists.
+        */
+       node_states_clear_node(node, &arg);
        if (!populated_zone(zone)) {
                zone_pcp_reset(zone);
                build_all_zonelists(NULL);
        }
 
-       node_states_clear_node(node, &arg);
        if (arg.status_change_nid >= 0) {
                kcompactd_stop(node);
                kswapd_stop(node);