In preparation for sub-section memory hotplug support, remove a dependency on ->section_mem_map being populated. In SPARSEMEM_VMEMMAP=y configurations pfn_to_page() does not use ->section_mem_map. The sub-section hotplug support relies on this fact and skips initializing it. Without ->section_mem_map populated, or aligned to section boundary, conversions of mem_section instances to zones is not possible. So, this removes a false dependency on a structure field that will only be valid in the SPARSEMEM_VMEMMAP=n case, and only used for pfn_to_page() (and similar) operations. Cc: Michal Hocko <mhocko@xxxxxxxx> Cc: Vlastimil Babka <vbabka@xxxxxxx> Cc: Johannes Weiner <hannes@xxxxxxxxxxx> Cc: Logan Gunthorpe <logang@xxxxxxxxxxxx> Cc: Mel Gorman <mgorman@xxxxxxxxxxxxxxxxxxx> Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> Cc: Stephen Bates <stephen.bates@xxxxxxxxxxxxx> Signed-off-by: Dan Williams <dan.j.williams@xxxxxxxxx> --- drivers/base/memory.c | 26 +++++++++----------------- include/linux/memory.h | 4 ++-- mm/memory_hotplug.c | 4 ++-- 3 files changed, 13 insertions(+), 21 deletions(-) diff --git a/drivers/base/memory.c b/drivers/base/memory.c index cc4f1d0cbffe..2cf8e97c15ce 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -685,24 +685,16 @@ static int add_memory_block(int base_section_nr) return 0; } -static bool is_zone_device_section(struct mem_section *ms) -{ - struct page *page; - - page = sparse_decode_mem_map(ms->section_mem_map, __section_nr(ms)); - return is_zone_device_page(page); -} - /* * need an interface for the VM to add new memory regions, * but without onlining it. */ -int register_new_memory(int nid, struct mem_section *section) +int register_new_memory(struct zone *zone, int nid, struct mem_section *section) { int ret = 0; struct memory_block *mem; - if (is_zone_device_section(section)) + if (is_dev_zone(zone)) return 0; mutex_lock(&mem_sysfs_mutex); @@ -736,14 +728,11 @@ unregister_memory(struct memory_block *memory) device_unregister(&memory->dev); } -static int remove_memory_section(unsigned long node_id, - struct mem_section *section, int phys_device) +static int remove_memory_section(struct zone *zone, unsigned long node_id, + struct mem_section *section, int phys_device) { struct memory_block *mem; - if (is_zone_device_section(section)) - return 0; - mutex_lock(&mem_sysfs_mutex); mem = find_memory_block(section); unregister_mem_sect_under_nodes(mem, __section_nr(section)); @@ -758,12 +747,15 @@ static int remove_memory_section(unsigned long node_id, return 0; } -int unregister_memory_section(struct mem_section *section) +int unregister_memory_section(struct zone *zone, struct mem_section *section) { + if (is_dev_zone(zone)) + return 0; + if (!present_section(section)) return -EINVAL; - return remove_memory_section(0, section, 0); + return remove_memory_section(zone, 0, section, 0); } #endif /* CONFIG_MEMORY_HOTREMOVE */ diff --git a/include/linux/memory.h b/include/linux/memory.h index b723a686fc10..e42df1abcb55 100644 --- a/include/linux/memory.h +++ b/include/linux/memory.h @@ -108,9 +108,9 @@ extern int register_memory_notifier(struct notifier_block *nb); extern void unregister_memory_notifier(struct notifier_block *nb); extern int register_memory_isolate_notifier(struct notifier_block *nb); extern void unregister_memory_isolate_notifier(struct notifier_block *nb); -extern int register_new_memory(int, struct mem_section *); +extern int register_new_memory(struct zone *, int, struct mem_section *); #ifdef CONFIG_MEMORY_HOTREMOVE -extern int unregister_memory_section(struct mem_section *); +extern int unregister_memory_section(struct zone *, struct mem_section *); #endif extern int memory_dev_init(void); extern int memory_notify(unsigned long val, void *v); diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 07accab8441d..dc6f815c2d37 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -524,7 +524,7 @@ static int __meminit __add_section(int nid, struct zone *zone, if (ret < 0) return ret; - return register_new_memory(nid, __pfn_to_section(phys_start_pfn)); + return register_new_memory(zone, nid, __pfn_to_section(phys_start_pfn)); } /* @@ -791,7 +791,7 @@ static int __remove_section(struct zone *zone, struct mem_section *ms, if (!valid_section(ms)) return ret; - ret = unregister_memory_section(ms); + ret = unregister_memory_section(zone, ms); if (ret) return ret; -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>