Commit a1e565aa authored by Tang Chen's avatar Tang Chen Committed by Linus Torvalds
Browse files

memory-hotplug: do not allocate pgdat if it was not freed when offline.

Since there is no way to guarentee the address of pgdat/zone is not on
stack of any kernel threads or used by other kernel objects without
reference counting or other symchronizing method, we cannot reset
node_data and free pgdat when offlining a node.  Just reset pgdat to 0
and reuse the memory when the node is online again.

The problem is suggested by Kamezawa Hiroyuki.  The idea is from Wen

NOTE: If we don't reset pgdat to 0, the WARN_ON in free_area_init_node()
      will be triggered.

[ fix warning when CONFIG_NEED_MULTIPLE_NODES=n]
[ fix the warning again again]
Signed-off-by: default avatarTang Chen <>
Reviewed-by: default avatarWen Congyang <>
Cc: KOSAKI Motohiro <>
Cc: Jiang Liu <>
Cc: Jianguo Wu <>
Cc: Kamezawa Hiroyuki <>
Cc: Lai Jiangshan <>
Cc: Wu Jianguo <>
Cc: Yasuaki Ishimatsu <>
Cc: Ingo Molnar <>
Cc: Thomas Gleixner <>
Cc: "H. Peter Anvin" <>
Signed-off-by: default avatarAndrew Morton <>
Signed-off-by: default avatarLinus Torvalds <>
parent d822b86a
......@@ -1017,11 +1017,14 @@ static pg_data_t __ref *hotadd_new_pgdat(int nid, u64 start)
unsigned long zholes_size[MAX_NR_ZONES] = {0};
unsigned long start_pfn = start >> PAGE_SHIFT;
pgdat = arch_alloc_nodedata(nid);
if (!pgdat)
return NULL;
pgdat = NODE_DATA(nid);
if (!pgdat) {
pgdat = arch_alloc_nodedata(nid);
if (!pgdat)
return NULL;
arch_refresh_nodedata(nid, pgdat);
arch_refresh_nodedata(nid, pgdat);
/* we can use NODE_DATA(nid) from here */
......@@ -1074,7 +1077,8 @@ out:
int __ref add_memory(int nid, u64 start, u64 size)
pg_data_t *pgdat = NULL;
int new_pgdat = 0;
bool new_pgdat;
bool new_node;
struct resource *res;
int ret;
......@@ -1085,12 +1089,16 @@ int __ref add_memory(int nid, u64 start, u64 size)
if (!res)
goto out;
if (!node_online(nid)) {
{ /* Stupid hack to suppress address-never-null warning */
void *p = NODE_DATA(nid);
new_pgdat = !p;
new_node = !node_online(nid);
if (new_node) {
pgdat = hotadd_new_pgdat(nid, start);
ret = -ENOMEM;
if (!pgdat)
goto error;
new_pgdat = 1;
/* call arch's memory hotadd */
......@@ -1102,7 +1110,7 @@ int __ref add_memory(int nid, u64 start, u64 size)
/* we online node here. we can't roll back from here. */
if (new_pgdat) {
if (new_node) {
ret = register_one_node(nid);
* If sysfs file of new node can't create, cpu on the node
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment