The patch titled Subject: mm/memory_hotplug: move and simplify walk_memory_blocks() has been added to the -mm tree. Its filename is mm-memory_hotplug-move-and-simplify-walk_memory_blocks.patch This patch should soon appear at http://ozlabs.org/~akpm/mmots/broken-out/mm-memory_hotplug-move-and-simplify-walk_memory_blocks.patch and later at http://ozlabs.org/~akpm/mmotm/broken-out/mm-memory_hotplug-move-and-simplify-walk_memory_blocks.patch Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/process/submit-checklist.rst when testing your code *** The -mm tree is included into linux-next and is updated there every 3-4 working days ------------------------------------------------------ From: David Hildenbrand <david@xxxxxxxxxx> Subject: mm/memory_hotplug: move and simplify walk_memory_blocks() Let's move walk_memory_blocks() to the place where memory block logic resides and simplify it. While at it, add a type for the callback function. Link: http://lkml.kernel.org/r/20190614100114.311-6-david@xxxxxxxxxx Signed-off-by: David Hildenbrand <david@xxxxxxxxxx> Reviewed-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> Cc: "Rafael J. Wysocki" <rafael@xxxxxxxxxx> Cc: David Hildenbrand <david@xxxxxxxxxx> Cc: Stephen Rothwell <sfr@xxxxxxxxxxxxxxxx> Cc: Pavel Tatashin <pasha.tatashin@xxxxxxxxxx> Cc: Andrew Banman <andrew.banman@xxxxxxx> Cc: Mike Travis <mike.travis@xxxxxxx> Cc: Oscar Salvador <osalvador@xxxxxxxx> Cc: Michal Hocko <mhocko@xxxxxxxx> Cc: Wei Yang <richard.weiyang@xxxxxxxxx> Cc: Arun KS <arunks@xxxxxxxxxxxxxx> Cc: Qian Cai <cai@xxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- drivers/base/memory.c | 42 +++++++++++++++++++++++ include/linux/memory.h | 3 + include/linux/memory_hotplug.h | 2 - mm/memory_hotplug.c | 55 ------------------------------- 4 files changed, 45 insertions(+), 57 deletions(-) --- a/drivers/base/memory.c~mm-memory_hotplug-move-and-simplify-walk_memory_blocks +++ a/drivers/base/memory.c @@ -44,6 +44,11 @@ static inline unsigned long pfn_to_block return base_memory_block_id(pfn_to_section_nr(pfn)); } +static inline unsigned long phys_to_block_id(unsigned long phys) +{ + return pfn_to_block_id(PFN_DOWN(phys)); +} + static int memory_subsys_online(struct device *dev); static int memory_subsys_offline(struct device *dev); @@ -853,3 +858,40 @@ out: printk(KERN_ERR "%s() failed: %d\n", __func__, ret); return ret; } + +/** + * walk_memory_blocks - walk through all present memory blocks overlapped + * by the range [start, start + size) + * + * @start: start address of the memory range + * @size: size of the memory range + * @arg: argument passed to func + * @func: callback for each memory section walked + * + * This function walks through all present memory blocks overlapped by the + * range [start, start + size), calling func on each memory block. + * + * In case func() returns an error, walking is aborted and the error is + * returned. + */ +int walk_memory_blocks(unsigned long start, unsigned long size, + void *arg, walk_memory_blocks_func_t func) +{ + const unsigned long start_block_id = phys_to_block_id(start); + const unsigned long end_block_id = phys_to_block_id(start + size - 1); + struct memory_block *mem; + unsigned long block_id; + int ret = 0; + + for (block_id = start_block_id; block_id <= end_block_id; block_id++) { + mem = find_memory_block_by_id(block_id, NULL); + if (!mem) + continue; + + ret = func(mem, arg); + put_device(&mem->dev); + if (ret) + break; + } + return ret; +} --- a/include/linux/memory.h~mm-memory_hotplug-move-and-simplify-walk_memory_blocks +++ a/include/linux/memory.h @@ -119,6 +119,9 @@ extern int memory_isolate_notify(unsigne extern struct memory_block *find_memory_block_hinted(struct mem_section *, struct memory_block *); extern struct memory_block *find_memory_block(struct mem_section *); +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); #define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT) #endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */ --- a/include/linux/memory_hotplug.h~mm-memory_hotplug-move-and-simplify-walk_memory_blocks +++ a/include/linux/memory_hotplug.h @@ -340,8 +340,6 @@ static inline void __remove_memory(int n #endif /* CONFIG_MEMORY_HOTREMOVE */ extern void __ref free_area_init_core_hotplug(int nid); -extern int walk_memory_blocks(unsigned long start, unsigned long size, - void *arg, int (*func)(struct memory_block *, void *)); extern int __add_memory(int nid, u64 start, u64 size); extern int add_memory(int nid, u64 start, u64 size); extern int add_memory_resource(int nid, struct resource *resource); --- a/mm/memory_hotplug.c~mm-memory_hotplug-move-and-simplify-walk_memory_blocks +++ a/mm/memory_hotplug.c @@ -1661,62 +1661,7 @@ int offline_pages(unsigned long start_pf { return __offline_pages(start_pfn, start_pfn + nr_pages); } -#endif /* CONFIG_MEMORY_HOTREMOVE */ -/** - * walk_memory_blocks - walk through all present memory blocks overlapped - * by the range [start, start + size) - * - * @start: start address of the memory range - * @size: size of the memory range - * @arg: argument passed to func - * @func: callback for each memory block walked - * - * This function walks through all present memory blocks overlapped by the - * range [start, start + size), calling func on each memory block. - * - * Returns the return value of func. - */ -int walk_memory_blocks(unsigned long start, unsigned long size, - void *arg, int (*func)(struct memory_block *, void *)) -{ - const unsigned long start_pfn = PFN_DOWN(start); - const unsigned long end_pfn = PFN_UP(start + size - 1); - struct memory_block *mem = NULL; - struct mem_section *section; - unsigned long pfn, section_nr; - int ret; - - for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) { - section_nr = pfn_to_section_nr(pfn); - if (!present_section_nr(section_nr)) - continue; - - section = __nr_to_section(section_nr); - /* same memblock? */ - if (mem) - if ((section_nr >= mem->start_section_nr) && - (section_nr <= mem->end_section_nr)) - continue; - - mem = find_memory_block_hinted(section, mem); - if (!mem) - continue; - - ret = func(mem, arg); - if (ret) { - kobject_put(&mem->dev.kobj); - return ret; - } - } - - if (mem) - kobject_put(&mem->dev.kobj); - - return 0; -} - -#ifdef CONFIG_MEMORY_HOTREMOVE static int check_memblock_offlined_cb(struct memory_block *mem, void *arg) { int ret = !is_memblock_offlined(mem); _ Patches currently in -mm which might be from david@xxxxxxxxxx are mm-memory_hotplug-simplify-and-fix-check_hotplug_memory_range.patch s390x-mm-fail-when-an-altmap-is-used-for-arch_add_memory.patch s390x-mm-implement-arch_remove_memory.patch arm64-mm-add-temporary-arch_remove_memory-implementation.patch drivers-base-memory-pass-a-block_id-to-init_memory_block.patch mm-memory_hotplug-allow-arch_remove_pages-without-config_memory_hotremove.patch mm-memory_hotplug-create-memory-block-devices-after-arch_add_memory.patch mm-memory_hotplug-drop-mhp_memblock_api.patch mm-memory_hotplug-remove-memory-block-devices-before-arch_remove_memory.patch mm-memory_hotplug-make-unregister_memory_block_under_nodes-never-fail.patch mm-memory_hotplug-remove-zone-parameter-from-sparse_remove_one_section.patch mm-section-numbers-use-the-type-unsigned-long.patch drivers-base-memory-use-unsigned-long-for-block-ids.patch mm-make-register_mem_sect_under_node-static.patch mm-memory_hotplug-rename-walk_memory_range-and-pass-startsize-instead-of-pfns.patch mm-memory_hotplug-move-and-simplify-walk_memory_blocks.patch drivers-base-memoryc-get-rid-of-find_memory_block_hinted.patch