linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/4] Small cleanup for memoryhotplug
@ 2018-06-22 11:18 osalvador
  2018-06-22 11:18 ` [PATCH v2 1/4] mm/memory_hotplug: Make add_memory_resource use __try_online_node osalvador
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: osalvador @ 2018-06-22 11:18 UTC (permalink / raw)
  To: akpm
  Cc: mhocko, vbabka, pasha.tatashin, Jonathan.Cameron, arbab,
	linux-mm, linux-kernel, Oscar Salvador

From: Oscar Salvador <osalvador@suse.de>

Hi,

I this is a small cleanup for the memhotplug's 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.

Signed-off-by: Oscar Salvador <osalvador@suse.de>
Tested-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

Changes since v1:
- Address issues/suggestions in the provided feedback (Pavel Tatashin)
- Rebased

Oscar Salvador (4):
  mm/memory_hotplug: Make add_memory_resource use __try_online_node
  mm/memory_hotplug: Call register_mem_sect_under_node
  mm/memory_hotplug: Make register_mem_sect_under_node a cb of
    walk_memory_range
  mm/memory_hotplug: Drop unnecessary checks from
    register_mem_sect_under_node

 drivers/base/memory.c |  2 --
 drivers/base/node.c   | 49 ++++----------------------
 include/linux/node.h  | 12 ++++---
 mm/memory_hotplug.c   | 96 +++++++++++++++++++++++++--------------------------
 4 files changed, 60 insertions(+), 99 deletions(-)

-- 
2.13.6


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 1/4] mm/memory_hotplug: Make add_memory_resource use __try_online_node
  2018-06-22 11:18 [PATCH v2 0/4] Small cleanup for memoryhotplug osalvador
@ 2018-06-22 11:18 ` osalvador
  2018-06-22 11:18 ` [PATCH v2 2/4] mm/memory_hotplug: Call register_mem_sect_under_node osalvador
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: osalvador @ 2018-06-22 11:18 UTC (permalink / raw)
  To: akpm
  Cc: mhocko, vbabka, pasha.tatashin, Jonathan.Cameron, arbab,
	linux-mm, linux-kernel, Oscar Salvador

From: Oscar Salvador <osalvador@suse.de>

add_memory_resource() contains code to allocate a new node in case
it is necessary.
Since try_online_node() also hast 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().

Signed-off-by: Oscar Salvador <osalvador@suse.de>
Reviewed-by: Pavel Tatashin <pasha.tatashin@oracle.com>
---
 mm/memory_hotplug.c | 67 +++++++++++++++++++++++++++++++----------------------
 1 file changed, 39 insertions(+), 28 deletions(-)

diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 7deb49f69e27..504ba120bdfc 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -1034,8 +1034,10 @@ static pg_data_t __ref *hotadd_new_pgdat(int nid, u64 start)
 	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);
 	free_percpu(pgdat->per_cpu_nodestats);
 	arch_free_nodedata(pgdat);
@@ -1046,28 +1048,48 @@ static void rollback_node_hotadd(int nid, pg_data_t *pgdat)
 /**
  * try_online_node - online a node if offlined
  * @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.
+ *
+ * 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;
-	int	ret;
+	pg_data_t *pgdat;
+	int ret = 1;
 
 	if (node_online(nid))
 		return 0;
 
-	mem_hotplug_begin();
-	pgdat = hotadd_new_pgdat(nid, 0);
+	pgdat = hotadd_new_pgdat(nid, start);
 	if (!pgdat) {
 		pr_err("Cannot online node %d due to NULL pgdat\n", nid);
 		ret = -ENOMEM;
 		goto out;
 	}
-	node_set_online(nid);
-	ret = register_one_node(nid);
-	BUG_ON(ret);
+
+	if (set_node_online) {
+		node_set_online(nid);
+		ret = register_one_node(nid);
+		BUG_ON(ret);
+	}
 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();
 	return ret;
 }
@@ -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)
 {
 	u64 start, size;
-	pg_data_t *pgdat = NULL;
-	bool new_pgdat;
-	bool new_node;
+	bool new_node = false;
 	int ret;
 
 	start = res->start;
@@ -1111,11 +1131,6 @@ int __ref add_memory_resource(int nid, struct resource *res, bool online)
 	if (ret)
 		return ret;
 
-	{	/* Stupid hack to suppress address-never-null warning */
-		void *p = NODE_DATA(nid);
-		new_pgdat = !p;
-	}
-
 	mem_hotplug_begin();
 
 	/*
@@ -1126,17 +1141,13 @@ int __ref add_memory_resource(int nid, struct resource *res, bool online)
 	 */
 	memblock_add_node(start, size, nid);
 
-	new_node = !node_online(nid);
-	if (new_node) {
-		pgdat = hotadd_new_pgdat(nid, start);
-		ret = -ENOMEM;
-		if (!pgdat)
-			goto error;
-	}
+	ret = __try_online_node(nid, start, false);
+	if (ret < 0)
+		goto error;
+	new_node = ret;
 
 	/* call arch's memory hotadd */
 	ret = arch_add_memory(nid, start, size, NULL, true);
-
 	if (ret < 0)
 		goto error;
 
@@ -1180,8 +1191,8 @@ int __ref add_memory_resource(int nid, struct resource *res, bool online)
 
 error:
 	/* rollback pgdat allocation and others */
-	if (new_pgdat && pgdat)
-		rollback_node_hotadd(nid, pgdat);
+	if (new_node)
+		rollback_node_hotadd(nid);
 	memblock_remove(start, size);
 
 out:
-- 
2.13.6


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 2/4] mm/memory_hotplug: Call register_mem_sect_under_node
  2018-06-22 11:18 [PATCH v2 0/4] Small cleanup for memoryhotplug osalvador
  2018-06-22 11:18 ` [PATCH v2 1/4] mm/memory_hotplug: Make add_memory_resource use __try_online_node osalvador
@ 2018-06-22 11:18 ` osalvador
  2018-06-22 11:18 ` [PATCH v2 3/4] mm/memory_hotplug: Make register_mem_sect_under_node a cb of walk_memory_range osalvador
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: osalvador @ 2018-06-22 11:18 UTC (permalink / raw)
  To: akpm
  Cc: mhocko, vbabka, pasha.tatashin, Jonathan.Cameron, arbab,
	linux-mm, linux-kernel, Oscar Salvador

From: Oscar Salvador <osalvador@suse.de>

When hotpluging memory, it is possible that two calls are being made
to register_mem_sect_under_node().
One comes from __add_section()->hotplug_memory_register()
and the other from add_memory_resource()->link_mem_sections() if
we had to register a new node.

In case we had to register a new node, hotplug_memory_register()
will only handle/allocate the memory_block's since
register_mem_sect_under_node() will return right away because the
node it is not online yet.

I think it is better if we leave hotplug_memory_register() to
handle/allocate only memory_block's and make link_mem_sections()
to call register_mem_sect_under_node().

So this patch removes the call to register_mem_sect_under_node()
from hotplug_memory_register(), and moves the call to link_mem_sections()
out of the condition, so it will always be called.
In this way we only have one place where the memory sections
are registered.

Signed-off-by: Oscar Salvador <osalvador@suse.de>
Reviewed-by: Pavel Tatashin <pasha.tatashin@oracle.com>
---
 drivers/base/memory.c |  2 --
 mm/memory_hotplug.c   | 32 +++++++++++---------------------
 2 files changed, 11 insertions(+), 23 deletions(-)

diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index f5e560188a18..c8a1cb0b6136 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -736,8 +736,6 @@ int hotplug_memory_register(int nid, struct mem_section *section)
 		mem->section_count++;
 	}
 
-	if (mem->section_count == sections_per_block)
-		ret = register_mem_sect_under_node(mem, nid, false);
 out:
 	mutex_unlock(&mem_sysfs_mutex);
 	return ret;
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 504ba120bdfc..e2ed64b994e5 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -1123,6 +1123,7 @@ int __ref add_memory_resource(int nid, struct resource *res, bool online)
 	u64 start, size;
 	bool new_node = false;
 	int ret;
+	unsigned long start_pfn, nr_pages;
 
 	start = res->start;
 	size = resource_size(res);
@@ -1151,34 +1152,23 @@ int __ref add_memory_resource(int nid, struct resource *res, bool online)
 	if (ret < 0)
 		goto error;
 
-	/* we online node here. we can't roll back from here. */
-	node_set_online(nid);
-
 	if (new_node) {
-		unsigned long start_pfn = start >> PAGE_SHIFT;
-		unsigned long nr_pages = size >> PAGE_SHIFT;
-
-		ret = __register_one_node(nid);
-		if (ret)
-			goto register_fail;
-
-		/*
-		 * link memory sections under this node. This is already
-		 * done when creatig memory section in register_new_memory
-		 * but that depends to have the node registered so offline
-		 * nodes have to go through register_node.
-		 * TODO clean up this mess.
-		 */
-		ret = link_mem_sections(nid, start_pfn, nr_pages, false);
-register_fail:
-		/*
-		 * If sysfs file of new node can't create, cpu on the node
+		/* If sysfs file of new node can't be created, cpu on the node
 		 * can't be hot-added. There is no rollback way now.
 		 * So, check by BUG_ON() to catch it reluctantly..
+		 * We online node here. We can't roll back from here.
 		 */
+		node_set_online(nid);
+		ret = __register_one_node(nid);
 		BUG_ON(ret);
 	}
 
+	/* link memory sections under this node.*/
+	start_pfn = start >> PAGE_SHIFT;
+	nr_pages = size >> PAGE_SHIFT;
+	ret = link_mem_sections(nid, start_pfn, nr_pages, false);
+	BUG_ON(ret);
+
 	/* create new memmap entry */
 	firmware_map_add_hotplug(start, start + size, "System RAM");
 
-- 
2.13.6


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 3/4] mm/memory_hotplug: Make register_mem_sect_under_node a cb of walk_memory_range
  2018-06-22 11:18 [PATCH v2 0/4] Small cleanup for memoryhotplug osalvador
  2018-06-22 11:18 ` [PATCH v2 1/4] mm/memory_hotplug: Make add_memory_resource use __try_online_node osalvador
  2018-06-22 11:18 ` [PATCH v2 2/4] mm/memory_hotplug: Call register_mem_sect_under_node osalvador
@ 2018-06-22 11:18 ` osalvador
  2018-08-15 22:21   ` Andrew Morton
  2018-08-16 17:20   ` Pasha Tatashin
  2018-06-22 11:18 ` [PATCH v2 4/4] mm/memory_hotplug: Drop unnecessary checks from register_mem_sect_under_node osalvador
  2018-06-22 21:16 ` [PATCH v2 0/4] Small cleanup for memoryhotplug Reza Arbab
  4 siblings, 2 replies; 9+ messages in thread
From: osalvador @ 2018-06-22 11:18 UTC (permalink / raw)
  To: akpm
  Cc: mhocko, vbabka, pasha.tatashin, Jonathan.Cameron, arbab,
	linux-mm, linux-kernel, Oscar Salvador

From: Oscar Salvador <osalvador@suse.de>

link_mem_sections() and walk_memory_range() share most of the code,
so we can use convert link_mem_sections() into a dummy function that calls
walk_memory_range() with a callback to register_mem_sect_under_node().

This patch converts register_mem_sect_under_node() in order to
match a walk_memory_range's callback, getting rid of the
check_nid argument and checking instead if the system is still
boothing, since we only have to check for the nid if the system
is in such state.

Signed-off-by: Oscar Salvador <osalvador@suse.de>
Suggested-by: Pavel Tatashin <pasha.tatashin@oracle.com>
---
 drivers/base/node.c  | 44 ++++++--------------------------------------
 include/linux/node.h | 12 +++++++-----
 mm/memory_hotplug.c  |  5 +----
 3 files changed, 14 insertions(+), 47 deletions(-)

diff --git a/drivers/base/node.c b/drivers/base/node.c
index a5e821d09656..845d5523812b 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -399,10 +399,9 @@ static int __ref get_nid_for_pfn(unsigned long pfn)
 }
 
 /* register memory section under specified node if it spans that node */
-int register_mem_sect_under_node(struct memory_block *mem_blk, int nid,
-				 bool check_nid)
+int register_mem_sect_under_node(struct memory_block *mem_blk, void *arg)
 {
-	int ret;
+	int ret, nid = *(int *)arg;
 	unsigned long pfn, sect_start_pfn, sect_end_pfn;
 
 	if (!mem_blk)
@@ -433,7 +432,7 @@ int register_mem_sect_under_node(struct memory_block *mem_blk, int nid,
 		 * case, during hotplug we know that all pages in the memory
 		 * block belong to the same node.
 		 */
-		if (check_nid) {
+		if (system_state == SYSTEM_BOOTING) {
 			page_nid = get_nid_for_pfn(pfn);
 			if (page_nid < 0)
 				continue;
@@ -490,41 +489,10 @@ int unregister_mem_sect_under_nodes(struct memory_block *mem_blk,
 	return 0;
 }
 
-int link_mem_sections(int nid, unsigned long start_pfn, unsigned long nr_pages,
-		      bool check_nid)
+int link_mem_sections(int nid, unsigned long start_pfn, unsigned long end_pfn)
 {
-	unsigned long end_pfn = start_pfn + nr_pages;
-	unsigned long pfn;
-	struct memory_block *mem_blk = NULL;
-	int err = 0;
-
-	for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) {
-		unsigned long section_nr = pfn_to_section_nr(pfn);
-		struct mem_section *mem_sect;
-		int ret;
-
-		if (!present_section_nr(section_nr))
-			continue;
-		mem_sect = __nr_to_section(section_nr);
-
-		/* same memblock ? */
-		if (mem_blk)
-			if ((section_nr >= mem_blk->start_section_nr) &&
-			    (section_nr <= mem_blk->end_section_nr))
-				continue;
-
-		mem_blk = find_memory_block_hinted(mem_sect, mem_blk);
-
-		ret = register_mem_sect_under_node(mem_blk, nid, check_nid);
-		if (!err)
-			err = ret;
-
-		/* discard ref obtained in find_memory_block() */
-	}
-
-	if (mem_blk)
-		kobject_put(&mem_blk->dev.kobj);
-	return err;
+	return walk_memory_range(start_pfn, end_pfn, (void *)&nid,
+					register_mem_sect_under_node);
 }
 
 #ifdef CONFIG_HUGETLBFS
diff --git a/include/linux/node.h b/include/linux/node.h
index 6d336e38d155..257bb3d6d014 100644
--- a/include/linux/node.h
+++ b/include/linux/node.h
@@ -33,10 +33,10 @@ typedef  void (*node_registration_func_t)(struct node *);
 
 #if defined(CONFIG_MEMORY_HOTPLUG_SPARSE) && defined(CONFIG_NUMA)
 extern int link_mem_sections(int nid, unsigned long start_pfn,
-			     unsigned long nr_pages, bool check_nid);
+			     unsigned long end_pfn);
 #else
 static inline int link_mem_sections(int nid, unsigned long start_pfn,
-				    unsigned long nr_pages, bool check_nid)
+				    unsigned long end_pfn)
 {
 	return 0;
 }
@@ -54,12 +54,14 @@ static inline int register_one_node(int nid)
 
 	if (node_online(nid)) {
 		struct pglist_data *pgdat = NODE_DATA(nid);
+		unsigned long start_pfn = pgdat->node_start_pfn;
+		unsigned long end_pfn = start_pfn + pgdat->node_spanned_pages;
 
 		error = __register_one_node(nid);
 		if (error)
 			return error;
 		/* link memory sections under this node */
-		error = link_mem_sections(nid, pgdat->node_start_pfn, pgdat->node_spanned_pages, true);
+		error = link_mem_sections(nid, start_pfn, end_pfn);
 	}
 
 	return error;
@@ -69,7 +71,7 @@ extern void unregister_one_node(int nid);
 extern int register_cpu_under_node(unsigned int cpu, unsigned int nid);
 extern int unregister_cpu_under_node(unsigned int cpu, unsigned int nid);
 extern int register_mem_sect_under_node(struct memory_block *mem_blk,
-						int nid, bool check_nid);
+						void *arg);
 extern int unregister_mem_sect_under_nodes(struct memory_block *mem_blk,
 					   unsigned long phys_index);
 
@@ -99,7 +101,7 @@ static inline int unregister_cpu_under_node(unsigned int cpu, unsigned int nid)
 	return 0;
 }
 static inline int register_mem_sect_under_node(struct memory_block *mem_blk,
-							int nid, bool check_nid)
+							void *arg)
 {
 	return 0;
 }
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index e2ed64b994e5..4eb6e824a80c 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -1123,7 +1123,6 @@ int __ref add_memory_resource(int nid, struct resource *res, bool online)
 	u64 start, size;
 	bool new_node = false;
 	int ret;
-	unsigned long start_pfn, nr_pages;
 
 	start = res->start;
 	size = resource_size(res);
@@ -1164,9 +1163,7 @@ int __ref add_memory_resource(int nid, struct resource *res, bool online)
 	}
 
 	/* link memory sections under this node.*/
-	start_pfn = start >> PAGE_SHIFT;
-	nr_pages = size >> PAGE_SHIFT;
-	ret = link_mem_sections(nid, start_pfn, nr_pages, false);
+	ret = link_mem_sections(nid, PFN_DOWN(start), PFN_UP(start + size - 1));
 	BUG_ON(ret);
 
 	/* create new memmap entry */
-- 
2.13.6


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 4/4] mm/memory_hotplug: Drop unnecessary checks from register_mem_sect_under_node
  2018-06-22 11:18 [PATCH v2 0/4] Small cleanup for memoryhotplug osalvador
                   ` (2 preceding siblings ...)
  2018-06-22 11:18 ` [PATCH v2 3/4] mm/memory_hotplug: Make register_mem_sect_under_node a cb of walk_memory_range osalvador
@ 2018-06-22 11:18 ` osalvador
  2018-06-22 21:16 ` [PATCH v2 0/4] Small cleanup for memoryhotplug Reza Arbab
  4 siblings, 0 replies; 9+ messages in thread
From: osalvador @ 2018-06-22 11:18 UTC (permalink / raw)
  To: akpm
  Cc: mhocko, vbabka, pasha.tatashin, Jonathan.Cameron, arbab,
	linux-mm, linux-kernel, Oscar Salvador

From: Oscar Salvador <osalvador@suse.de>

Callers of register_mem_sect_under_node() are always passing a valid
memory_block (not NULL), so we can safely drop the check for NULL.

In the same way, register_mem_sect_under_node() is only called in case
the node is online, so we can safely remove that check as well.

Signed-off-by: Oscar Salvador <osalvador@suse.de>
Reviewed-by: Pavel Tatashin <pasha.tatashin@oracle.com>
---
 drivers/base/node.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/drivers/base/node.c b/drivers/base/node.c
index 845d5523812b..1ac4c36e13bb 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -404,12 +404,7 @@ int register_mem_sect_under_node(struct memory_block *mem_blk, void *arg)
 	int ret, nid = *(int *)arg;
 	unsigned long pfn, sect_start_pfn, sect_end_pfn;
 
-	if (!mem_blk)
-		return -EFAULT;
-
 	mem_blk->nid = nid;
-	if (!node_online(nid))
-		return 0;
 
 	sect_start_pfn = section_nr_to_pfn(mem_blk->start_section_nr);
 	sect_end_pfn = section_nr_to_pfn(mem_blk->end_section_nr);
-- 
2.13.6


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 0/4] Small cleanup for memoryhotplug
  2018-06-22 11:18 [PATCH v2 0/4] Small cleanup for memoryhotplug osalvador
                   ` (3 preceding siblings ...)
  2018-06-22 11:18 ` [PATCH v2 4/4] mm/memory_hotplug: Drop unnecessary checks from register_mem_sect_under_node osalvador
@ 2018-06-22 21:16 ` Reza Arbab
  4 siblings, 0 replies; 9+ messages in thread
From: Reza Arbab @ 2018-06-22 21:16 UTC (permalink / raw)
  To: osalvador
  Cc: akpm, mhocko, vbabka, pasha.tatashin, Jonathan.Cameron, linux-mm,
	linux-kernel, Oscar Salvador

On Thu, Jun 21, 2018 at 10:32:58AM +0200, Michal Hocko wrote:
>[Cc Reza Arbab - I remember he was able to hit some bugs in memblock
>registration code when I was reworking that area previously]

Thanks for the heads-up!

I have verified that this patchset doesn't seem to cause any regression 
in the kooky memoryless node use case I was testing.

-- 
Reza Arbab


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 3/4] mm/memory_hotplug: Make register_mem_sect_under_node a cb of walk_memory_range
  2018-06-22 11:18 ` [PATCH v2 3/4] mm/memory_hotplug: Make register_mem_sect_under_node a cb of walk_memory_range osalvador
@ 2018-08-15 22:21   ` Andrew Morton
  2018-08-16  6:15     ` Oscar Salvador
  2018-08-16 17:20   ` Pasha Tatashin
  1 sibling, 1 reply; 9+ messages in thread
From: Andrew Morton @ 2018-08-15 22:21 UTC (permalink / raw)
  To: osalvador
  Cc: mhocko, vbabka, pasha.tatashin, Jonathan.Cameron, arbab,
	linux-mm, linux-kernel, Oscar Salvador

On Fri, 22 Jun 2018 13:18:38 +0200 osalvador@techadventures.net wrote:

> From: Oscar Salvador <osalvador@suse.de>
> 
> link_mem_sections() and walk_memory_range() share most of the code,
> so we can use convert link_mem_sections() into a dummy function that calls
> walk_memory_range() with a callback to register_mem_sect_under_node().
> 
> This patch converts register_mem_sect_under_node() in order to
> match a walk_memory_range's callback, getting rid of the
> check_nid argument and checking instead if the system is still
> boothing, since we only have to check for the nid if the system
> is in such state.
> 
> Signed-off-by: Oscar Salvador <osalvador@suse.de>
> Suggested-by: Pavel Tatashin <pasha.tatashin@oracle.com>

We have two tested-by's bu no reviewers or ackers?

From: Oscar Salvador <osalvador@suse.de>
Subject: mm/memory_hotplug.c: make register_mem_sect_under_node() a callback of walk_memory_range()

link_mem_sections() and walk_memory_range() share most of the code, so we
can use convert link_mem_sections() into a dummy function that calls
walk_memory_range() with a callback to register_mem_sect_under_node().

This patch converts register_mem_sect_under_node() in order to match a
walk_memory_range's callback, getting rid of the check_nid argument and
checking instead if the system is still boothing, since we only have to
check for the nid if the system is in such state.

Link: http://lkml.kernel.org/r/20180622111839.10071-4-osalvador@techadventures.net
Signed-off-by: Oscar Salvador <osalvador@suse.de>
Suggested-by: Pavel Tatashin <pasha.tatashin@oracle.com>
Tested-by: Reza Arbab <arbab@linux.vnet.ibm.com>
Tested-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 drivers/base/node.c  |   44 +++++------------------------------------
 include/linux/node.h |   12 ++++++-----
 mm/memory_hotplug.c  |    5 ----
 3 files changed, 14 insertions(+), 47 deletions(-)

--- a/drivers/base/node.c~mm-memory_hotplug-make-register_mem_sect_under_node-a-cb-of-walk_memory_range
+++ a/drivers/base/node.c
@@ -399,10 +399,9 @@ static int __ref get_nid_for_pfn(unsigne
 }
 
 /* register memory section under specified node if it spans that node */
-int register_mem_sect_under_node(struct memory_block *mem_blk, int nid,
-				 bool check_nid)
+int register_mem_sect_under_node(struct memory_block *mem_blk, void *arg)
 {
-	int ret;
+	int ret, nid = *(int *)arg;
 	unsigned long pfn, sect_start_pfn, sect_end_pfn;
 
 	if (!mem_blk)
@@ -433,7 +432,7 @@ int register_mem_sect_under_node(struct
 		 * case, during hotplug we know that all pages in the memory
 		 * block belong to the same node.
 		 */
-		if (check_nid) {
+		if (system_state == SYSTEM_BOOTING) {
 			page_nid = get_nid_for_pfn(pfn);
 			if (page_nid < 0)
 				continue;
@@ -490,41 +489,10 @@ int unregister_mem_sect_under_nodes(stru
 	return 0;
 }
 
-int link_mem_sections(int nid, unsigned long start_pfn, unsigned long nr_pages,
-		      bool check_nid)
+int link_mem_sections(int nid, unsigned long start_pfn, unsigned long end_pfn)
 {
-	unsigned long end_pfn = start_pfn + nr_pages;
-	unsigned long pfn;
-	struct memory_block *mem_blk = NULL;
-	int err = 0;
-
-	for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) {
-		unsigned long section_nr = pfn_to_section_nr(pfn);
-		struct mem_section *mem_sect;
-		int ret;
-
-		if (!present_section_nr(section_nr))
-			continue;
-		mem_sect = __nr_to_section(section_nr);
-
-		/* same memblock ? */
-		if (mem_blk)
-			if ((section_nr >= mem_blk->start_section_nr) &&
-			    (section_nr <= mem_blk->end_section_nr))
-				continue;
-
-		mem_blk = find_memory_block_hinted(mem_sect, mem_blk);
-
-		ret = register_mem_sect_under_node(mem_blk, nid, check_nid);
-		if (!err)
-			err = ret;
-
-		/* discard ref obtained in find_memory_block() */
-	}
-
-	if (mem_blk)
-		kobject_put(&mem_blk->dev.kobj);
-	return err;
+	return walk_memory_range(start_pfn, end_pfn, (void *)&nid,
+					register_mem_sect_under_node);
 }
 
 #ifdef CONFIG_HUGETLBFS
--- a/include/linux/node.h~mm-memory_hotplug-make-register_mem_sect_under_node-a-cb-of-walk_memory_range
+++ a/include/linux/node.h
@@ -33,10 +33,10 @@ typedef  void (*node_registration_func_t
 
 #if defined(CONFIG_MEMORY_HOTPLUG_SPARSE) && defined(CONFIG_NUMA)
 extern int link_mem_sections(int nid, unsigned long start_pfn,
-			     unsigned long nr_pages, bool check_nid);
+			     unsigned long end_pfn);
 #else
 static inline int link_mem_sections(int nid, unsigned long start_pfn,
-				    unsigned long nr_pages, bool check_nid)
+				    unsigned long end_pfn)
 {
 	return 0;
 }
@@ -54,12 +54,14 @@ static inline int register_one_node(int
 
 	if (node_online(nid)) {
 		struct pglist_data *pgdat = NODE_DATA(nid);
+		unsigned long start_pfn = pgdat->node_start_pfn;
+		unsigned long end_pfn = start_pfn + pgdat->node_spanned_pages;
 
 		error = __register_one_node(nid);
 		if (error)
 			return error;
 		/* link memory sections under this node */
-		error = link_mem_sections(nid, pgdat->node_start_pfn, pgdat->node_spanned_pages, true);
+		error = link_mem_sections(nid, start_pfn, end_pfn);
 	}
 
 	return error;
@@ -69,7 +71,7 @@ extern void unregister_one_node(int nid)
 extern int register_cpu_under_node(unsigned int cpu, unsigned int nid);
 extern int unregister_cpu_under_node(unsigned int cpu, unsigned int nid);
 extern int register_mem_sect_under_node(struct memory_block *mem_blk,
-						int nid, bool check_nid);
+						void *arg);
 extern int unregister_mem_sect_under_nodes(struct memory_block *mem_blk,
 					   unsigned long phys_index);
 
@@ -99,7 +101,7 @@ static inline int unregister_cpu_under_n
 	return 0;
 }
 static inline int register_mem_sect_under_node(struct memory_block *mem_blk,
-							int nid, bool check_nid)
+							void *arg)
 {
 	return 0;
 }
--- a/mm/memory_hotplug.c~mm-memory_hotplug-make-register_mem_sect_under_node-a-cb-of-walk_memory_range
+++ a/mm/memory_hotplug.c
@@ -1123,7 +1123,6 @@ int __ref add_memory_resource(int nid, s
 	u64 start, size;
 	bool new_node = false;
 	int ret;
-	unsigned long start_pfn, nr_pages;
 
 	start = res->start;
 	size = resource_size(res);
@@ -1164,9 +1163,7 @@ int __ref add_memory_resource(int nid, s
 	}
 
 	/* link memory sections under this node.*/
-	start_pfn = start >> PAGE_SHIFT;
-	nr_pages = size >> PAGE_SHIFT;
-	ret = link_mem_sections(nid, start_pfn, nr_pages, false);
+	ret = link_mem_sections(nid, PFN_DOWN(start), PFN_UP(start + size - 1));
 	BUG_ON(ret);
 
 	/* create new memmap entry */
_


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 3/4] mm/memory_hotplug: Make register_mem_sect_under_node a cb of walk_memory_range
  2018-08-15 22:21   ` Andrew Morton
@ 2018-08-16  6:15     ` Oscar Salvador
  0 siblings, 0 replies; 9+ messages in thread
From: Oscar Salvador @ 2018-08-16  6:15 UTC (permalink / raw)
  To: Andrew Morton
  Cc: mhocko, vbabka, pavel.tatashin, Jonathan.Cameron, arbab,
	linux-mm, linux-kernel, Oscar Salvador

On Wed, Aug 15, 2018 at 03:21:35PM -0700, Andrew Morton wrote:
> On Fri, 22 Jun 2018 13:18:38 +0200 osalvador@techadventures.net wrote:
> 
> > From: Oscar Salvador <osalvador@suse.de>
> > 
> > link_mem_sections() and walk_memory_range() share most of the code,
> > so we can use convert link_mem_sections() into a dummy function that calls
> > walk_memory_range() with a callback to register_mem_sect_under_node().
> > 
> > This patch converts register_mem_sect_under_node() in order to
> > match a walk_memory_range's callback, getting rid of the
> > check_nid argument and checking instead if the system is still
> > boothing, since we only have to check for the nid if the system
> > is in such state.
> > 
> > Signed-off-by: Oscar Salvador <osalvador@suse.de>
> > Suggested-by: Pavel Tatashin <pasha.tatashin@oracle.com>
> 
> We have two tested-by's bu no reviewers or ackers?
 
Pavel, would you be so kind to review this patch?
It is the only patch from the patchset which did not get a 
review.

Thanks!
-- 
Oscar Salvador
SUSE L3

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 3/4] mm/memory_hotplug: Make register_mem_sect_under_node a cb of walk_memory_range
  2018-06-22 11:18 ` [PATCH v2 3/4] mm/memory_hotplug: Make register_mem_sect_under_node a cb of walk_memory_range osalvador
  2018-08-15 22:21   ` Andrew Morton
@ 2018-08-16 17:20   ` Pasha Tatashin
  1 sibling, 0 replies; 9+ messages in thread
From: Pasha Tatashin @ 2018-08-16 17:20 UTC (permalink / raw)
  To: osalvador
  Cc: akpm, mhocko, vbabka, Pasha Tatashin, Jonathan.Cameron, arbab,
	linux-mm, linux-kernel, Oscar Salvador

On 18-06-22 13:18:38, osalvador@techadventures.net wrote:
> From: Oscar Salvador <osalvador@suse.de>
> 
> link_mem_sections() and walk_memory_range() share most of the code,
> so we can use convert link_mem_sections() into a dummy function that calls
> walk_memory_range() with a callback to register_mem_sect_under_node().
> 
> This patch converts register_mem_sect_under_node() in order to
> match a walk_memory_range's callback, getting rid of the
> check_nid argument and checking instead if the system is still
> boothing, since we only have to check for the nid if the system
> is in such state.
> 
> Signed-off-by: Oscar Salvador <osalvador@suse.de>
> Suggested-by: Pavel Tatashin <pasha.tatashin@oracle.com>

Reviewed-by: Pavel Tatashin <pavel.tatashin@microsoft.com>

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2018-08-16 17:20 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-22 11:18 [PATCH v2 0/4] Small cleanup for memoryhotplug osalvador
2018-06-22 11:18 ` [PATCH v2 1/4] mm/memory_hotplug: Make add_memory_resource use __try_online_node osalvador
2018-06-22 11:18 ` [PATCH v2 2/4] mm/memory_hotplug: Call register_mem_sect_under_node osalvador
2018-06-22 11:18 ` [PATCH v2 3/4] mm/memory_hotplug: Make register_mem_sect_under_node a cb of walk_memory_range osalvador
2018-08-15 22:21   ` Andrew Morton
2018-08-16  6:15     ` Oscar Salvador
2018-08-16 17:20   ` Pasha Tatashin
2018-06-22 11:18 ` [PATCH v2 4/4] mm/memory_hotplug: Drop unnecessary checks from register_mem_sect_under_node osalvador
2018-06-22 21:16 ` [PATCH v2 0/4] Small cleanup for memoryhotplug Reza Arbab

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).