The patch titled Subject: mm/memory_hotplug: Fix try_offline_node() has been removed from the -mm tree. Its filename was mm-memory_hotplug-fix-try_offline_node-v3.patch This patch was dropped because it was folded into mm-memory_hotplug-fix-try_offline_node.patch ------------------------------------------------------ From: David Hildenbrand <david@xxxxxxxxxx> Subject: mm/memory_hotplug: Fix try_offline_node() Introduce and use for_each_memory_block(), which will run significantly faster than walk_memory_blocks(). Link: http://lkml.kernel.org/r/20191102120221.7553-1-david@xxxxxxxxxx Fixes: 60a5a19e7419 ("memory-hotplug: remove sysfs file of node") Fixes: f1dd2cd13c4b ("mm, memory_hotplug: do not associate hotadded memory to zones until online") # visiable after d0dc12e86b319 Cc: Tang Chen <tangchen@xxxxxxxxxxxxxx> Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> Cc: "Rafael J. Wysocki" <rafael@xxxxxxxxxx> Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> Cc: Keith Busch <keith.busch@xxxxxxxxx> Cc: Jiri Olsa <jolsa@xxxxxxxxxx> Cc: "Peter Zijlstra (Intel)" <peterz@xxxxxxxxxxxxx> Cc: Jani Nikula <jani.nikula@xxxxxxxxx> Cc: Nayna Jain <nayna@xxxxxxxxxxxxx> Cc: Michal Hocko <mhocko@xxxxxxxx> Cc: Oscar Salvador <osalvador@xxxxxxx> Cc: Stephen Rothwell <sfr@xxxxxxxxxxxxxxxx> Cc: Dan Williams <dan.j.williams@xxxxxxxxx> Cc: Pavel Tatashin <pasha.tatashin@xxxxxxxxxx> Signed-off-by: David Hildenbrand <david@xxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- drivers/base/memory.c | 36 ++++++++++++++++++++++++++++++++++++ drivers/base/node.c | 9 --------- fs/sysfs/symlink.c | 21 --------------------- include/linux/memory.h | 1 + include/linux/node.h | 7 ------- include/linux/sysfs.h | 6 ------ mm/memory_hotplug.c | 17 +++++++++-------- 7 files changed, 46 insertions(+), 51 deletions(-) --- a/drivers/base/memory.c~mm-memory_hotplug-fix-try_offline_node-v3 +++ a/drivers/base/memory.c @@ -872,3 +872,39 @@ int walk_memory_blocks(unsigned long sta } return ret; } + +struct for_each_memory_block_cb_data { + walk_memory_blocks_func_t func; + void *arg; +}; + +static int for_each_memory_block_cb(struct device *dev, void *data) +{ + struct memory_block *mem = to_memory_block(dev); + struct for_each_memory_block_cb_data *cb_data = data; + + return cb_data->func(mem, cb_data->arg); +} + +/** + * for_each_memory_block - walk through all present memory blocks + * + * @arg: argument passed to func + * @func: callback for each memory block walked + * + * This function walks through all present memory blocks, calling func on + * each memory block. + * + * In case func() returns an error, walking is aborted and the error is + * returned. + */ +int for_each_memory_block(void *arg, walk_memory_blocks_func_t func) +{ + struct for_each_memory_block_cb_data cb_data = { + .func = func, + .arg = arg, + }; + + return bus_for_each_dev(&memory_subsys, NULL, &cb_data, + for_each_memory_block_cb); +} --- a/drivers/base/node.c~mm-memory_hotplug-fix-try_offline_node-v3 +++ a/drivers/base/node.c @@ -836,15 +836,6 @@ int link_mem_sections(int nid, unsigned register_mem_sect_under_node); } -bool memory_block_registered_under_node(struct memory_block *mem, int nid) -{ - if (mem->nid == nid) - return true; - /* memory blocks can span multiple nodes. Check against the link. */ - return sysfs_link_exists(&mem->dev.kobj, - kobject_name(&node_devices[nid]->dev.kobj)); -} - #ifdef CONFIG_HUGETLBFS /* * Handle per node hstate attribute [un]registration on transistions --- a/fs/sysfs/symlink.c~mm-memory_hotplug-fix-try_offline_node-v3 +++ a/fs/sysfs/symlink.c @@ -154,27 +154,6 @@ void sysfs_remove_link(struct kobject *k EXPORT_SYMBOL_GPL(sysfs_remove_link); /** - * sysfs_link_exists - test if a symlink exists in object's directory. - * @kobj: object we're acting for. - * @name: name of the symlink to test. - */ -bool sysfs_link_exists(struct kobject *kobj, const char *name) -{ - struct kernfs_node *parent = NULL, *kn; - - if (!kobj) - parent = sysfs_root_kn; - else - parent = kobj->sd; - - kn = kernfs_find_and_get(parent, name); - kernfs_put(kn); - - return kn != NULL; -} -EXPORT_SYMBOL_GPL(sysfs_link_exists); - -/** * sysfs_rename_link_ns - rename symlink in object's directory. * @kobj: object we're acting for. * @targ: object we're pointing to. --- a/include/linux/memory.h~mm-memory_hotplug-fix-try_offline_node-v3 +++ a/include/linux/memory.h @@ -119,6 +119,7 @@ extern struct memory_block *find_memory_ typedef int (*walk_memory_blocks_func_t)(struct memory_block *, void *); extern int walk_memory_blocks(unsigned long start, unsigned long size, void *arg, walk_memory_blocks_func_t func); +extern int for_each_memory_block(void *arg, walk_memory_blocks_func_t func); #define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT) #endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */ --- a/include/linux/node.h~mm-memory_hotplug-fix-try_offline_node-v3 +++ a/include/linux/node.h @@ -138,8 +138,6 @@ 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 void unregister_memory_block_under_nodes(struct memory_block *mem_blk); -extern bool memory_block_registered_under_node(struct memory_block *mem, - int nid); extern int register_memory_node_under_compute_node(unsigned int mem_nid, unsigned int cpu_nid, @@ -173,11 +171,6 @@ static inline int unregister_cpu_under_n static inline void unregister_memory_block_under_nodes(struct memory_block *mem_blk) { } -static inline bool memory_block_registered_under_node(struct memory_block *mem, - int nid) -{ - return true; -} static inline void register_hugetlbfs_with_node(node_registration_func_t reg, node_registration_func_t unreg) --- a/include/linux/sysfs.h~mm-memory_hotplug-fix-try_offline_node-v3 +++ a/include/linux/sysfs.h @@ -265,7 +265,6 @@ int __must_check sysfs_create_link_nowar struct kobject *target, const char *name); void sysfs_remove_link(struct kobject *kobj, const char *name); -bool sysfs_link_exists(struct kobject *kobj, const char *name); int sysfs_rename_link_ns(struct kobject *kobj, struct kobject *target, const char *old_name, const char *new_name, @@ -421,11 +420,6 @@ static inline void sysfs_remove_link(str { } -static inline bool sysfs_link_exists(struct kobject *kobj, const char *name) -{ - return true; -} - static inline int sysfs_rename_link_ns(struct kobject *k, struct kobject *t, const char *old_name, const char *new_name, const void *ns) --- a/mm/memory_hotplug.c~mm-memory_hotplug-fix-try_offline_node-v3 +++ a/mm/memory_hotplug.c @@ -1646,13 +1646,16 @@ static int check_cpu_on_node(pg_data_t * return 0; } -static int check_no_memblock_registered_under_node_cb(struct memory_block *mem, - void *arg) +static int check_no_memblock_for_node_cb(struct memory_block *mem, void *arg) { + int nid = *(int *)arg; - const int nid = *(int *)arg; - - return memory_block_registered_under_node(mem, nid) ? -EEXIST : 0; + /* + * If a memory block belongs to multiple nodes, the stored nid is not + * reliable. However, such blocks are always online (e.g., cannot get + * offlined) and, therefore, are still spanned by the node. + */ + return mem->nid == nid ? -EEXIST : 0; } /** @@ -1666,7 +1669,6 @@ static int check_no_memblock_registered_ */ void try_offline_node(int nid) { - unsigned long end_pfn = section_nr_to_pfn(__highest_present_section_nr); pg_data_t *pgdat = NODE_DATA(nid); int rc; @@ -1683,8 +1685,7 @@ void try_offline_node(int nid) * node. They will get spanned by the node once they get onlined. * However, they link to the node in sysfs and can get onlined later. */ - rc = walk_memory_blocks(0, PFN_PHYS(end_pfn), &nid, - check_no_memblock_registered_under_node_cb); + rc = for_each_memory_block(&nid, check_no_memblock_for_node_cb); if (rc) return; _ Patches currently in -mm which might be from david@xxxxxxxxxx are mm-memory_hotplug-fix-try_offline_node.patch mm-memory_hotplug-export-generic_online_page.patch hv_balloon-use-generic_online_page.patch mm-memory_hotplug-remove-__online_page_free-and-__online_page_increment_counters.patch mm-memory_hotplug-dont-access-uninitialized-memmaps-in-shrink_zone_span.patch mm-memory_hotplug-shrink-zones-when-offlining-memory.patch mm-memory_hotplug-poison-memmap-in-remove_pfn_range_from_zone.patch mm-memory_hotplug-we-always-have-a-zone-in-find_smallestbiggest_section_pfn.patch mm-memory_hotplug-dont-check-for-all-holes-in-shrink_zone_span.patch mm-memory_hotplug-drop-local-variables-in-shrink_zone_span.patch mm-memory_hotplug-cleanup-__remove_pages.patch mm-page_allocc-dont-set-pages-pagereserved-when-offlining.patch mm-page_isolationc-convert-skip_hwpoison-to-memory_offline.patch drivers-base-memoryc-drop-the-mem_sysfs_mutex.patch