Michal Hocko 5fdd3c
From 1b862aecfbd419cdc4553645bf86d07554279bed Mon Sep 17 00:00:00 2001
Jiri Kosina 2028ed
From: Michal Hocko <mhocko@suse.com>
Michal Hocko 5fdd3c
Date: Thu, 6 Jul 2017 15:37:45 -0700
Michal Hocko 5fdd3c
Subject: [PATCH 04/16] mm, memory_hotplug: get rid of is_zone_device_section
Michal Hocko 5fdd3c
Git-commit: 1b862aecfbd419cdc4553645bf86d07554279bed
Michal Hocko 5fdd3c
Patch-mainline: 4.13-rc1
Michal Hocko 9b458a
References: bnc#1027153, bnc#1030659, bnc#1047595, fate#323634
Jiri Kosina 2028ed
Michal Hocko 5fdd3c
Device memory hotplug hooks into regular memory hotplug only half way.
Jiri Kosina 2028ed
It needs memory sections to track struct pages but there is no
Jiri Kosina 2028ed
need/desire to associate those sections with memory blocks and export
Jiri Kosina 2028ed
them to the userspace via sysfs because they cannot be onlined anyway.
Jiri Kosina 2028ed
Jiri Kosina 2028ed
This is currently expressed by for_device argument to arch_add_memory
Jiri Kosina 2028ed
which then makes sure to associate the given memory range with
Michal Hocko 5fdd3c
ZONE_DEVICE.  register_new_memory then relies on is_zone_device_section
Michal Hocko 5fdd3c
to distinguish special memory hotplug from the regular one.  While this
Jiri Kosina 2028ed
works now, later patches in this series want to move __add_zone outside
Jiri Kosina 2028ed
of arch_add_memory path so we have to come up with something else.
Jiri Kosina 2028ed
Jiri Kosina 2028ed
Add want_memblock down the __add_pages path and use it to control
Michal Hocko 5fdd3c
whether the section->memblock association should be done.
Michal Hocko 5fdd3c
arch_add_memory then just trivially want memblock for everything but
Michal Hocko 5fdd3c
for_device hotplug.
Jiri Kosina 2028ed
Michal Hocko 5fdd3c
remove_memory_section doesn't need is_zone_device_section either.  We
Michal Hocko 5fdd3c
can simply skip all the memblock specific cleanup if there is no
Michal Hocko 5fdd3c
memblock for the given section.
Jiri Kosina 2028ed
Jiri Kosina 2028ed
This shouldn't introduce any functional change.
Jiri Kosina 2028ed
Michal Hocko 5fdd3c
Link: http://lkml.kernel.org/r/20170515085827.16474-5-mhocko@kernel.org
Jiri Kosina 2028ed
Signed-off-by: Michal Hocko <mhocko@suse.com>
Michal Hocko 5fdd3c
Tested-by: Dan Williams <dan.j.williams@intel.com>
Michal Hocko 5fdd3c
Acked-by: Vlastimil Babka <vbabka@suse.cz>
Michal Hocko 5fdd3c
Cc: Andi Kleen <ak@linux.intel.com>
Michal Hocko 5fdd3c
Cc: Andrea Arcangeli <aarcange@redhat.com>
Michal Hocko 5fdd3c
Cc: Balbir Singh <bsingharora@gmail.com>
Michal Hocko 5fdd3c
Cc: Daniel Kiper <daniel.kiper@oracle.com>
Michal Hocko 5fdd3c
Cc: David Rientjes <rientjes@google.com>
Michal Hocko 5fdd3c
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Michal Hocko 5fdd3c
Cc: Igor Mammedov <imammedo@redhat.com>
Michal Hocko 5fdd3c
Cc: Jerome Glisse <jglisse@redhat.com>
Michal Hocko 5fdd3c
Cc: Joonsoo Kim <js1304@gmail.com>
Michal Hocko 5fdd3c
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Michal Hocko 5fdd3c
Cc: Mel Gorman <mgorman@suse.de>
Michal Hocko 5fdd3c
Cc: Reza Arbab <arbab@linux.vnet.ibm.com>
Michal Hocko 5fdd3c
Cc: Tobias Regnery <tobias.regnery@gmail.com>
Michal Hocko 5fdd3c
Cc: Toshi Kani <toshi.kani@hpe.com>
Michal Hocko 5fdd3c
Cc: Vitaly Kuznetsov <vkuznets@redhat.com>
Michal Hocko 5fdd3c
Cc: Xishi Qiu <qiuxishi@huawei.com>
Michal Hocko 5fdd3c
Cc: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
Michal Hocko 5fdd3c
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Michal Hocko 5fdd3c
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Jiri Kosina 2028ed
Jiri Kosina 2028ed
---
Michal Hocko 5fdd3c
 arch/ia64/mm/init.c            |  2 +-
Michal Hocko 5fdd3c
 arch/powerpc/mm/mem.c          |  2 +-
Michal Hocko 5fdd3c
 arch/s390/mm/init.c            |  2 +-
Michal Hocko 5fdd3c
 arch/sh/mm/init.c              |  2 +-
Michal Hocko 5fdd3c
 arch/x86/mm/init_32.c          |  2 +-
Michal Hocko 5fdd3c
 arch/x86/mm/init_64.c          |  2 +-
Michal Hocko 5fdd3c
 drivers/base/memory.c          | 23 +++++++++--------------
Michal Hocko 5fdd3c
 include/linux/memory_hotplug.h |  2 +-
Michal Hocko 5fdd3c
 mm/memory_hotplug.c            |  9 ++++++---
Jiri Kosina 2028ed
 9 files changed, 22 insertions(+), 24 deletions(-)
Jiri Kosina 2028ed
Michal Hocko 5fdd3c
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
Michal Hocko 5fdd3c
index 8f3efa682ee8..39e2aeb4669d 100644
Jiri Kosina 2028ed
--- a/arch/ia64/mm/init.c
Jiri Kosina 2028ed
+++ b/arch/ia64/mm/init.c
Michal Hocko 5fdd3c
@@ -658,7 +658,7 @@ int arch_add_memory(int nid, u64 start, u64 size, bool for_device)
Jiri Kosina 2028ed
 
Michal Hocko 5fdd3c
 	zone = pgdat->node_zones +
Michal Hocko 5fdd3c
 		zone_for_memory(nid, start, size, ZONE_NORMAL, for_device);
Michal Hocko 5fdd3c
-	ret = __add_pages(nid, zone, start_pfn, nr_pages);
Michal Hocko 5fdd3c
+	ret = __add_pages(nid, zone, start_pfn, nr_pages, !for_device);
Jiri Kosina 2028ed
 
Jiri Kosina 2028ed
 	if (ret)
Jiri Kosina 2028ed
 		printk("%s: Problem encountered in __add_pages() as ret=%d\n",
Michal Hocko 5fdd3c
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
Michal Hocko 5fdd3c
index 9ee536ec0739..e6b2e6618b6c 100644
Jiri Kosina 2028ed
--- a/arch/powerpc/mm/mem.c
Jiri Kosina 2028ed
+++ b/arch/powerpc/mm/mem.c
Michal Hocko 5fdd3c
@@ -151,7 +151,7 @@ int arch_add_memory(int nid, u64 start, u64 size, bool for_device)
Michal Hocko 5fdd3c
 	zone = pgdata->node_zones +
Michal Hocko 5fdd3c
 		zone_for_memory(nid, start, size, 0, for_device);
Jiri Kosina 2028ed
 
Michal Hocko 5fdd3c
-	return __add_pages(nid, zone, start_pfn, nr_pages);
Michal Hocko 5fdd3c
+	return __add_pages(nid, zone, start_pfn, nr_pages, !for_device);
Jiri Kosina 2028ed
 }
Jiri Kosina 2028ed
 
Jiri Kosina 2028ed
 #ifdef CONFIG_MEMORY_HOTREMOVE
Michal Hocko 5fdd3c
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
Michal Hocko 5fdd3c
index 3348e60dd8ad..a3d549966b6a 100644
Jiri Kosina 2028ed
--- a/arch/s390/mm/init.c
Jiri Kosina 2028ed
+++ b/arch/s390/mm/init.c
Michal Hocko 5fdd3c
@@ -195,7 +195,7 @@ int arch_add_memory(int nid, u64 start, u64 size, bool for_device)
Michal Hocko 5fdd3c
 			continue;
Michal Hocko 5fdd3c
 		nr_pages = (start_pfn + size_pages > zone_end_pfn) ?
Michal Hocko 5fdd3c
 			   zone_end_pfn - start_pfn : size_pages;
Michal Hocko 5fdd3c
-		rc = __add_pages(nid, zone, start_pfn, nr_pages);
Michal Hocko 5fdd3c
+		rc = __add_pages(nid, zone, start_pfn, nr_pages, !for_device);
Michal Hocko 5fdd3c
 		if (rc)
Michal Hocko 5fdd3c
 			break;
Michal Hocko 5fdd3c
 		start_pfn += nr_pages;
Michal Hocko 5fdd3c
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
Michal Hocko 5fdd3c
index 75491862d900..a9d57f75ae8c 100644
Jiri Kosina 2028ed
--- a/arch/sh/mm/init.c
Jiri Kosina 2028ed
+++ b/arch/sh/mm/init.c
Michal Hocko 5fdd3c
@@ -498,7 +498,7 @@ int arch_add_memory(int nid, u64 start, u64 size, bool for_device)
Michal Hocko 5fdd3c
 	ret = __add_pages(nid, pgdat->node_zones +
Michal Hocko 5fdd3c
 			zone_for_memory(nid, start, size, ZONE_NORMAL,
Michal Hocko 5fdd3c
 			for_device),
Michal Hocko 5fdd3c
-			start_pfn, nr_pages);
Michal Hocko 5fdd3c
+			start_pfn, nr_pages, !for_device);
Jiri Kosina 2028ed
 	if (unlikely(ret))
Jiri Kosina 2028ed
 		printk("%s: Failed, __add_pages() == %d\n", __func__, ret);
Jiri Kosina 2028ed
 
Michal Hocko 5fdd3c
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
Michal Hocko 5fdd3c
index 99fb83819a5f..94594b889144 100644
Jiri Kosina 2028ed
--- a/arch/x86/mm/init_32.c
Jiri Kosina 2028ed
+++ b/arch/x86/mm/init_32.c
Michal Hocko 5fdd3c
@@ -831,7 +831,7 @@ int arch_add_memory(int nid, u64 start, u64 size, bool for_device)
Jiri Kosina 2028ed
 	unsigned long start_pfn = start >> PAGE_SHIFT;
Jiri Kosina 2028ed
 	unsigned long nr_pages = size >> PAGE_SHIFT;
Jiri Kosina 2028ed
 
Michal Hocko 5fdd3c
-	return __add_pages(nid, zone, start_pfn, nr_pages);
Michal Hocko 5fdd3c
+	return __add_pages(nid, zone, start_pfn, nr_pages, !for_device);
Jiri Kosina 2028ed
 }
Jiri Kosina 2028ed
 
Jiri Kosina 2028ed
 #ifdef CONFIG_MEMORY_HOTREMOVE
Michal Hocko 5fdd3c
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
Michal Hocko 5fdd3c
index dae6a5e5ad4a..9d64291459b6 100644
Jiri Kosina 2028ed
--- a/arch/x86/mm/init_64.c
Jiri Kosina 2028ed
+++ b/arch/x86/mm/init_64.c
Michal Hocko 5fdd3c
@@ -787,7 +787,7 @@ int arch_add_memory(int nid, u64 start, u64 size, bool for_device)
Jiri Kosina 2028ed
 
Jiri Kosina 2028ed
 	init_memory_mapping(start, start + size);
Jiri Kosina 2028ed
 
Michal Hocko 5fdd3c
-	ret = __add_pages(nid, zone, start_pfn, nr_pages);
Michal Hocko 5fdd3c
+	ret = __add_pages(nid, zone, start_pfn, nr_pages, !for_device);
Jiri Kosina 2028ed
 	WARN_ON_ONCE(ret);
Jiri Kosina 2028ed
 
Jiri Kosina 2028ed
 	/* update max_pfn, max_low_pfn and high_memory */
Michal Hocko 5fdd3c
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
Michal Hocko 5fdd3c
index 90225ffee501..f8fd562c3f18 100644
Jiri Kosina 2028ed
--- a/drivers/base/memory.c
Jiri Kosina 2028ed
+++ b/drivers/base/memory.c
Michal Hocko 5fdd3c
@@ -685,14 +685,6 @@ static int add_memory_block(int base_section_nr)
Jiri Kosina 2028ed
 	return 0;
Jiri Kosina 2028ed
 }
Jiri Kosina 2028ed
 
Jiri Kosina 2028ed
-static bool is_zone_device_section(struct mem_section *ms)
Jiri Kosina 2028ed
-{
Jiri Kosina 2028ed
-	struct page *page;
Jiri Kosina 2028ed
-
Jiri Kosina 2028ed
-	page = sparse_decode_mem_map(ms->section_mem_map, __section_nr(ms));
Jiri Kosina 2028ed
-	return is_zone_device_page(page);
Jiri Kosina 2028ed
-}
Jiri Kosina 2028ed
-
Jiri Kosina 2028ed
 /*
Jiri Kosina 2028ed
  * need an interface for the VM to add new memory regions,
Jiri Kosina 2028ed
  * but without onlining it.
Michal Hocko 5fdd3c
@@ -702,9 +694,6 @@ int register_new_memory(int nid, struct mem_section *section)
Jiri Kosina 2028ed
 	int ret = 0;
Jiri Kosina 2028ed
 	struct memory_block *mem;
Jiri Kosina 2028ed
 
Jiri Kosina 2028ed
-	if (is_zone_device_section(section))
Jiri Kosina 2028ed
-		return 0;
Jiri Kosina 2028ed
-
Jiri Kosina 2028ed
 	mutex_lock(&mem_sysfs_mutex);
Jiri Kosina 2028ed
 
Jiri Kosina 2028ed
 	mem = find_memory_block(section);
Michal Hocko 5fdd3c
@@ -741,11 +730,16 @@ static int remove_memory_section(unsigned long node_id,
Jiri Kosina 2028ed
 {
Jiri Kosina 2028ed
 	struct memory_block *mem;
Jiri Kosina 2028ed
 
Jiri Kosina 2028ed
-	if (is_zone_device_section(section))
Jiri Kosina 2028ed
-		return 0;
Jiri Kosina 2028ed
-
Jiri Kosina 2028ed
 	mutex_lock(&mem_sysfs_mutex);
Jiri Kosina 2028ed
+
Jiri Kosina 2028ed
+	/*
Jiri Kosina 2028ed
+	 * Some users of the memory hotplug do not want/need memblock to
Jiri Kosina 2028ed
+	 * track all sections. Skip over those.
Jiri Kosina 2028ed
+	 */
Jiri Kosina 2028ed
 	mem = find_memory_block(section);
Jiri Kosina 2028ed
+	if (!mem)
Michal Hocko 5fdd3c
+		goto out_unlock;
Jiri Kosina 2028ed
+
Jiri Kosina 2028ed
 	unregister_mem_sect_under_nodes(mem, __section_nr(section));
Jiri Kosina 2028ed
 
Jiri Kosina 2028ed
 	mem->section_count--;
Michal Hocko 5fdd3c
@@ -754,6 +748,7 @@ static int remove_memory_section(unsigned long node_id,
Michal Hocko 5fdd3c
 	else
Michal Hocko 5fdd3c
 		put_device(&mem->dev);
Michal Hocko 5fdd3c
 
Michal Hocko 5fdd3c
+out_unlock:
Michal Hocko 5fdd3c
 	mutex_unlock(&mem_sysfs_mutex);
Michal Hocko 5fdd3c
 	return 0;
Michal Hocko 5fdd3c
 }
Michal Hocko 5fdd3c
diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
Michal Hocko 5fdd3c
index 134a2f69c21a..3c8cf86201c3 100644
Jiri Kosina 2028ed
--- a/include/linux/memory_hotplug.h
Jiri Kosina 2028ed
+++ b/include/linux/memory_hotplug.h
Michal Hocko 5fdd3c
@@ -111,7 +111,7 @@ extern int __remove_pages(struct zone *zone, unsigned long start_pfn,
Jiri Kosina 2028ed
 
Michal Hocko 5fdd3c
 /* reasonably generic interface to expand the physical pages in a zone  */
Michal Hocko 5fdd3c
 extern int __add_pages(int nid, struct zone *zone, unsigned long start_pfn,
Jiri Kosina 2028ed
-	unsigned long nr_pages);
Jiri Kosina 2028ed
+	unsigned long nr_pages, bool want_memblock);
Jiri Kosina 2028ed
 
Jiri Kosina 2028ed
 #ifdef CONFIG_NUMA
Jiri Kosina 2028ed
 extern int memory_add_physaddr_to_nid(u64 start);
Michal Hocko 5fdd3c
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
Michal Hocko 5fdd3c
index 6b6362819be2..c0147d3024eb 100644
Jiri Kosina 2028ed
--- a/mm/memory_hotplug.c
Jiri Kosina 2028ed
+++ b/mm/memory_hotplug.c
Michal Hocko 5fdd3c
@@ -494,7 +494,7 @@ static int __meminit __add_zone(struct zone *zone, unsigned long phys_start_pfn)
Jiri Kosina 2028ed
 }
Jiri Kosina 2028ed
 
Michal Hocko 5fdd3c
 static int __meminit __add_section(int nid, struct zone *zone,
Michal Hocko 5fdd3c
-					unsigned long phys_start_pfn)
Michal Hocko 5fdd3c
+		unsigned long phys_start_pfn, bool want_memblock)
Jiri Kosina 2028ed
 {
Jiri Kosina 2028ed
 	int ret;
Michal Hocko 5fdd3c
 
Michal Hocko 5fdd3c
@@ -511,6 +511,9 @@ static int __meminit __add_section(int nid, struct zone *zone,
Michal Hocko 5fdd3c
 	if (ret < 0)
Michal Hocko 5fdd3c
 		return ret;
Jiri Kosina 2028ed
 
Jiri Kosina 2028ed
+	if (!want_memblock)
Jiri Kosina 2028ed
+		return 0;
Jiri Kosina 2028ed
+
Jiri Kosina 2028ed
 	return register_new_memory(nid, __pfn_to_section(phys_start_pfn));
Jiri Kosina 2028ed
 }
Jiri Kosina 2028ed
 
Michal Hocko 5fdd3c
@@ -521,7 +524,7 @@ static int __meminit __add_section(int nid, struct zone *zone,
Jiri Kosina 2028ed
  * add the new pages.
Jiri Kosina 2028ed
  */
Michal Hocko 5fdd3c
 int __ref __add_pages(int nid, struct zone *zone, unsigned long phys_start_pfn,
Jiri Kosina 2028ed
-			unsigned long nr_pages)
Jiri Kosina 2028ed
+			unsigned long nr_pages, bool want_memblock)
Jiri Kosina 2028ed
 {
Jiri Kosina 2028ed
 	unsigned long i;
Jiri Kosina 2028ed
 	int err = 0;
Michal Hocko 5fdd3c
@@ -549,7 +552,7 @@ int __ref __add_pages(int nid, struct zone *zone, unsigned long phys_start_pfn,
Michal Hocko 5fdd3c
 	}
Jiri Kosina 2028ed
 
Jiri Kosina 2028ed
 	for (i = start_sec; i <= end_sec; i++) {
Michal Hocko 5fdd3c
-		err = __add_section(nid, zone, section_nr_to_pfn(i));
Michal Hocko 5fdd3c
+		err = __add_section(nid, zone, section_nr_to_pfn(i), want_memblock);
Jiri Kosina 2028ed
 
Jiri Kosina 2028ed
 		/*
Jiri Kosina 2028ed
 		 * EEXIST is finally dealt with by ioresource collision
Michal Hocko 5fdd3c
-- 
Michal Hocko 5fdd3c
1.8.5.6
Michal Hocko 5fdd3c