[PATCH -next] mm/hotplug: fix a null-ptr-deref during NUMA boot

From: Qian Cai
Date: Sun May 12 2019 - 00:42:04 EST

The linux-next commit ("x86, numa: always initialize all possible
nodes") introduced a crash below during boot for systems with a
memory-less node. This is due to CPUs that get onlined during SMP boot,
but that onlining triggers a page fault in bus_add_device() during
device registration:

error = sysfs_create_link(&bus->p->devices_kset->kobj,

bus->p is NULL. That "p" is the subsys_private struct, and it should
have been set in,


but that happens in do_basic_setup() after smp_init().

The old code had set this node online via alloc_node_data(), so when it
came time to do_cpu_up() -> try_online_node(), the node was already up
and nothing happened.

Now, it attempts to online the node, which registers the node with
sysfs, but that can't happen before the 'node' subsystem is registered.

Since kernel_init() is running by a kernel thread that is in
SYSTEM_SCHEDULINGi state, fixed this skipping registering with sysfs
during the early boot in __try_online_node().

Call Trace:

Reported-by: Barret Rhoden <brho@xxxxxxxxxx>
Signed-off-by: Qian Cai <cai@xxxxxx>
mm/memory_hotplug.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index b236069ff0d8..5970dd65d698 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -1034,7 +1034,7 @@ static int __try_online_node(int nid, u64 start, bool set_node_online)
pg_data_t *pgdat;
int ret = 1;

- if (node_online(nid))
+ if (node_online(nid) || system_state == SYSTEM_SCHEDULING)
return 0;

pgdat = hotadd_new_pgdat(nid, start);
2.20.1 (Apple Git-117)