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
4444 return base_memory_block_id(pfn_to_section_nr(pfn));
4545 }
4646
47+static inline unsigned long phys_to_block_id(unsigned long phys)
48+{
49+ return pfn_to_block_id(PFN_DOWN(phys));
50+}
51+
4752 static int memory_subsys_online(struct device *dev);
4853 static int memory_subsys_offline(struct device *dev);
4954
@@ -851,3 +856,40 @@ out: · 801 unmodified lines
851856 printk(KERN_ERR "%s() failed: %d\n", __func__, ret);
852857 return ret;
853858 }
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+ */
875+int 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
119119 extern struct memory_block *find_memory_block_hinted(struct mem_section *,
120120 struct memory_block *);
121121 extern struct memory_block *find_memory_block(struct mem_section *);
122+typedef int (*walk_memory_blocks_func_t)(struct memory_block *, void *);
123+extern int walk_memory_blocks(unsigned long start, unsigned long size,
124+ void *arg, walk_memory_blocks_func_t func);
122125 #define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT)
123126 #endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */
124127
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
340340 #endif /* CONFIG_MEMORY_HOTREMOVE */
341341
342342 extern void __ref free_area_init_core_hotplug(int nid);
343−extern int walk_memory_blocks(unsigned long start, unsigned long size,
344− void *arg, int (*func)(struct memory_block *, void *));
345343 extern int __add_memory(int nid, u64 start, u64 size);
346344 extern int add_memory(int nid, u64 start, u64 size);
347345 extern 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
16591659 {
16601660 return __offline_pages(start_pfn, start_pfn + nr_pages);
16611661 }
1662−#endif /* CONFIG_MEMORY_HOTREMOVE */
16631662
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− */
1678−int 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
17181663 static int check_memblock_offlined_cb(struct memory_block *mem, void *arg)
17191664 {
17201665 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