History

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.

David Hildenbrand committed 7 years ago

Commit ea884641 parent fbcf73c4 files · +45 −57Browse files

Unified · Split

4 files
  1. drivers/base/memory.c +42 −0
  2. include/linux/memory.h +3 −0
  3. include/linux/memory_hotplug.h +0 −2
  4. mm/memory_hotplug.c +0 −55
drivers/base/memory.c+42−0
@@ -44,6 +44,11 @@ static inline unsigned long pfn_to_block_id(unsigned long pfn) · 43 unmodified lines
44 return base_memory_block_id(pfn_to_section_nr(pfn));44 return base_memory_block_id(pfn_to_section_nr(pfn));
45}45}
46 46
47static inline unsigned long phys_to_block_id(unsigned long phys)
48{
49 return pfn_to_block_id(PFN_DOWN(phys));
50}
51
47static int memory_subsys_online(struct device *dev);52static int memory_subsys_online(struct device *dev);
48static int memory_subsys_offline(struct device *dev);53static int memory_subsys_offline(struct device *dev);
49 54
@@ -851,3 +856,40 @@ out: · 801 unmodified lines
851 printk(KERN_ERR "%s() failed: %d\n", __func__, ret);856 printk(KERN_ERR "%s() failed: %d\n", __func__, ret);
852 return ret;857 return ret;
853}858}
859
860/**
861 * walk_memory_blocks - walk through all present memory blocks overlapped
862 * by the range [start, start + size)
863 *
864 * @start: start address of the memory range
865 * @size: size of the memory range
866 * @arg: argument passed to func
867 * @func: callback for each memory section walked
868 *
869 * This function walks through all present memory blocks overlapped by the
870 * range [start, start + size), calling func on each memory block.
871 *
872 * In case func() returns an error, walking is aborted and the error is
873 * returned.
874 */
875int walk_memory_blocks(unsigned long start, unsigned long size,
876 void *arg, walk_memory_blocks_func_t func)
877{
878 const unsigned long start_block_id = phys_to_block_id(start);
879 const unsigned long end_block_id = phys_to_block_id(start + size - 1);
880 struct memory_block *mem;
881 unsigned long block_id;
882 int ret = 0;
883
884 for (block_id = start_block_id; block_id <= end_block_id; block_id++) {
885 mem = find_memory_block_by_id(block_id, NULL);
886 if (!mem)
887 continue;
888
889 ret = func(mem, arg);
890 put_device(&mem->dev);
891 if (ret)
892 break;
893 }
894 return ret;
895}
include/linux/memory.h+3−0
@@ -119,6 +119,9 @@ extern int memory_isolate_notify(unsigned long val, void *v); · 118 unmodified lines
119extern struct memory_block *find_memory_block_hinted(struct mem_section *,119extern struct memory_block *find_memory_block_hinted(struct mem_section *,
120 struct memory_block *);120 struct memory_block *);
121extern struct memory_block *find_memory_block(struct mem_section *);121extern struct memory_block *find_memory_block(struct mem_section *);
122typedef int (*walk_memory_blocks_func_t)(struct memory_block *, void *);
123extern int walk_memory_blocks(unsigned long start, unsigned long size,
124 void *arg, walk_memory_blocks_func_t func);
122#define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT)125#define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT)
123#endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */126#endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */
124 127
include/linux/memory_hotplug.h+0−2
@@ -340,8 +340,6 @@ static inline void __remove_memory(int nid, u64 start, u64 size) {} · 339 unmodified lines
340#endif /* CONFIG_MEMORY_HOTREMOVE */340#endif /* CONFIG_MEMORY_HOTREMOVE */
341 341
342extern void __ref free_area_init_core_hotplug(int nid);342extern void __ref free_area_init_core_hotplug(int nid);
343extern int walk_memory_blocks(unsigned long start, unsigned long size,
344 void *arg, int (*func)(struct memory_block *, void *));
345extern int __add_memory(int nid, u64 start, u64 size);343extern int __add_memory(int nid, u64 start, u64 size);
346extern int add_memory(int nid, u64 start, u64 size);344extern int add_memory(int nid, u64 start, u64 size);
347extern int add_memory_resource(int nid, struct resource *resource);345extern int add_memory_resource(int nid, struct resource *resource);
mm/memory_hotplug.c+0−55
@@ -1659,62 +1659,7 @@ int offline_pages(unsigned long start_pfn, unsigned long nr_pages) · 1658 unmodified lines
1659{1659{
1660 return __offline_pages(start_pfn, start_pfn + nr_pages);1660 return __offline_pages(start_pfn, start_pfn + nr_pages);
1661}1661}
1662#endif /* CONFIG_MEMORY_HOTREMOVE */
1663 1662
1664/**
1665 * walk_memory_blocks - walk through all present memory blocks overlapped
1666 * by the range [start, start + size)
1667 *
1668 * @start: start address of the memory range
1669 * @size: size of the memory range
1670 * @arg: argument passed to func
1671 * @func: callback for each memory block walked
1672 *
1673 * This function walks through all present memory blocks overlapped by the
1674 * range [start, start + size), calling func on each memory block.
1675 *
1676 * Returns the return value of func.
1677 */
1678int walk_memory_blocks(unsigned long start, unsigned long size,
1679 void *arg, int (*func)(struct memory_block *, void *))
1680{
1681 const unsigned long start_pfn = PFN_DOWN(start);
1682 const unsigned long end_pfn = PFN_UP(start + size - 1);
1683 struct memory_block *mem = NULL;
1684 struct mem_section *section;
1685 unsigned long pfn, section_nr;
1686 int ret;
1687
1688 for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) {
1689 section_nr = pfn_to_section_nr(pfn);
1690 if (!present_section_nr(section_nr))
1691 continue;
1692
1693 section = __nr_to_section(section_nr);
1694 /* same memblock? */
1695 if (mem)
1696 if ((section_nr >= mem->start_section_nr) &&
1697 (section_nr <= mem->end_section_nr))
1698 continue;
1699
1700 mem = find_memory_block_hinted(section, mem);
1701 if (!mem)
1702 continue;
1703
1704 ret = func(mem, arg);
1705 if (ret) {
1706 kobject_put(&mem->dev.kobj);
1707 return ret;
1708 }
1709 }
1710
1711 if (mem)
1712 kobject_put(&mem->dev.kobj);
1713
1714 return 0;
1715}
1716
1717#ifdef CONFIG_MEMORY_HOTREMOVE
1718static int check_memblock_offlined_cb(struct memory_block *mem, void *arg)1663static int check_memblock_offlined_cb(struct memory_block *mem, void *arg)
1719{1664{
1720 int ret = !is_memblock_offlined(mem);1665 int ret = !is_memblock_offlined(mem);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t