Commit b9ff0360 authored by Oscar Salvador's avatar Oscar Salvador Committed by Linus Torvalds

mm/memory_hotplug.c: make add_memory_resource use __try_online_node

This is a small cleanup for the memhotplug code.  A lot more could be
done, but it is better to start somewhere.  I tried to unify/remove
duplicated code.

The following is what this patchset does:

1) add_memory_resource() has code to allocate a node in case it was
   offline.  Since try_online_node has some code for that as well, I just
   made add_memory_resource() to use that so we can remove duplicated
   code..  This is better explained in patch 1/4.

2) register_mem_sect_under_node() will be called only from
   link_mem_sections()

3) Make register_mem_sect_under_node() a callback of
   walk_memory_range()

4) Drop unnecessary checks from register_mem_sect_under_node()

I have done some tests and I could not see anything broken because of
this patchset.

add_memory_resource() contains code to allocate a new node in case it is
necessary.  Since try_online_node() also has some code for this purpose,
let us make use of that and remove duplicate code.

This introduces __try_online_node(), which is called by
add_memory_resource() and try_online_node().  __try_online_node() has
two new parameters, start_addr of the node, and if the node should be
onlined and registered right away.  This is always wanted if we are
calling from do_cpu_up(), but not when we are calling from memhotplug
code.  Nothing changes from the point of view of the users of
try_online_node(), since try_online_node passes start_addr=0 and
online_node=true to __try_online_node().

Link: http://lkml.kernel.org/r/20180622111839.10071-2-osalvador@techadventures.netSigned-off-by: default avatarOscar Salvador <osalvador@suse.de>
Reviewed-by: default avatarPavel Tatashin <pasha.tatashin@oracle.com>
Tested-by: default avatarReza Arbab <arbab@linux.vnet.ibm.com>
Tested-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
Cc: Pasha Tatashin <Pavel.Tatashin@microsoft.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Pavel Tatashin <pasha.tatashin@oracle.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 930eaac5
...@@ -1034,8 +1034,10 @@ static pg_data_t __ref *hotadd_new_pgdat(int nid, u64 start) ...@@ -1034,8 +1034,10 @@ static pg_data_t __ref *hotadd_new_pgdat(int nid, u64 start)
return pgdat; return pgdat;
} }
static void rollback_node_hotadd(int nid, pg_data_t *pgdat) static void rollback_node_hotadd(int nid)
{ {
pg_data_t *pgdat = NODE_DATA(nid);
arch_refresh_nodedata(nid, NULL); arch_refresh_nodedata(nid, NULL);
free_percpu(pgdat->per_cpu_nodestats); free_percpu(pgdat->per_cpu_nodestats);
arch_free_nodedata(pgdat); arch_free_nodedata(pgdat);
...@@ -1046,28 +1048,48 @@ static void rollback_node_hotadd(int nid, pg_data_t *pgdat) ...@@ -1046,28 +1048,48 @@ static void rollback_node_hotadd(int nid, pg_data_t *pgdat)
/** /**
* try_online_node - online a node if offlined * try_online_node - online a node if offlined
* @nid: the node ID * @nid: the node ID
* * @start: start addr of the node
* @set_node_online: Whether we want to online the node
* called by cpu_up() to online a node without onlined memory. * called by cpu_up() to online a node without onlined memory.
*
* Returns:
* 1 -> a new node has been allocated
* 0 -> the node is already online
* -ENOMEM -> the node could not be allocated
*/ */
int try_online_node(int nid) static int __try_online_node(int nid, u64 start, bool set_node_online)
{ {
pg_data_t *pgdat; pg_data_t *pgdat;
int ret; int ret = 1;
if (node_online(nid)) if (node_online(nid))
return 0; return 0;
mem_hotplug_begin(); pgdat = hotadd_new_pgdat(nid, start);
pgdat = hotadd_new_pgdat(nid, 0);
if (!pgdat) { if (!pgdat) {
pr_err("Cannot online node %d due to NULL pgdat\n", nid); pr_err("Cannot online node %d due to NULL pgdat\n", nid);
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto out;
} }
if (set_node_online) {
node_set_online(nid); node_set_online(nid);
ret = register_one_node(nid); ret = register_one_node(nid);
BUG_ON(ret); BUG_ON(ret);
}
out: out:
return ret;
}
/*
* Users of this function always want to online/register the node
*/
int try_online_node(int nid)
{
int ret;
mem_hotplug_begin();
ret = __try_online_node(nid, 0, true);
mem_hotplug_done(); mem_hotplug_done();
return ret; return ret;
} }
...@@ -1099,9 +1121,7 @@ static int online_memory_block(struct memory_block *mem, void *arg) ...@@ -1099,9 +1121,7 @@ static int online_memory_block(struct memory_block *mem, void *arg)
int __ref add_memory_resource(int nid, struct resource *res, bool online) int __ref add_memory_resource(int nid, struct resource *res, bool online)
{ {
u64 start, size; u64 start, size;
pg_data_t *pgdat = NULL; bool new_node = false;
bool new_pgdat;
bool new_node;
int ret; int ret;
start = res->start; start = res->start;
...@@ -1111,11 +1131,6 @@ int __ref add_memory_resource(int nid, struct resource *res, bool online) ...@@ -1111,11 +1131,6 @@ int __ref add_memory_resource(int nid, struct resource *res, bool online)
if (ret) if (ret)
return ret; return ret;
{ /* Stupid hack to suppress address-never-null warning */
void *p = NODE_DATA(nid);
new_pgdat = !p;
}
mem_hotplug_begin(); mem_hotplug_begin();
/* /*
...@@ -1126,17 +1141,13 @@ int __ref add_memory_resource(int nid, struct resource *res, bool online) ...@@ -1126,17 +1141,13 @@ int __ref add_memory_resource(int nid, struct resource *res, bool online)
*/ */
memblock_add_node(start, size, nid); memblock_add_node(start, size, nid);
new_node = !node_online(nid); ret = __try_online_node(nid, start, false);
if (new_node) { if (ret < 0)
pgdat = hotadd_new_pgdat(nid, start);
ret = -ENOMEM;
if (!pgdat)
goto error; goto error;
} new_node = ret;
/* call arch's memory hotadd */ /* call arch's memory hotadd */
ret = arch_add_memory(nid, start, size, NULL, true); ret = arch_add_memory(nid, start, size, NULL, true);
if (ret < 0) if (ret < 0)
goto error; goto error;
...@@ -1180,8 +1191,8 @@ int __ref add_memory_resource(int nid, struct resource *res, bool online) ...@@ -1180,8 +1191,8 @@ int __ref add_memory_resource(int nid, struct resource *res, bool online)
error: error:
/* rollback pgdat allocation and others */ /* rollback pgdat allocation and others */
if (new_pgdat && pgdat) if (new_node)
rollback_node_hotadd(nid, pgdat); rollback_node_hotadd(nid);
memblock_remove(start, size); memblock_remove(start, size);
out: out:
......
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