__add_pages() doesn't add the memory resource, so __remove_pages()
shouldn't remove it. Let's factor it out. Especially as it is a special
case for memory used as system memory, added via add_memory() and
friends.

We now remove the resource after removing the sections instead of doing
it the other way around. I don't think this change is problematic.

add_memory()
        register memory resource
        arch_add_memory()

remove_memory
        arch_remove_memory()
        release memory resource

While at it, explain why we ignore errors and that it only happeny if
we remove memory in a different granularity as we added it.

Cc: Andrew Morton <a...@linux-foundation.org>
Cc: Oscar Salvador <osalva...@suse.de>
Cc: Michal Hocko <mho...@suse.com>
Cc: David Hildenbrand <da...@redhat.com>
Cc: Pavel Tatashin <pasha.tatas...@soleen.com>
Cc: Wei Yang <richard.weiy...@gmail.com>
Cc: Qian Cai <c...@lca.pw>
Cc: Arun KS <aru...@codeaurora.org>
Cc: Mathieu Malaterre <ma...@debian.org>
Signed-off-by: David Hildenbrand <da...@redhat.com>
---
 mm/memory_hotplug.c | 34 ++++++++++++++++++++--------------
 1 file changed, 20 insertions(+), 14 deletions(-)

diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 4970ff658055..696ed7ee5e28 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -562,20 +562,6 @@ int __remove_pages(struct zone *zone, unsigned long 
phys_start_pfn,
        if (is_dev_zone(zone)) {
                if (altmap)
                        map_offset = vmem_altmap_offset(altmap);
-       } else {
-               resource_size_t start, size;
-
-               start = phys_start_pfn << PAGE_SHIFT;
-               size = nr_pages * PAGE_SIZE;
-
-               ret = release_mem_region_adjustable(&iomem_resource, start,
-                                       size);
-               if (ret) {
-                       resource_size_t endres = start + size - 1;
-
-                       pr_warn("Unable to release resource <%pa-%pa> (%d)\n",
-                                       &start, &endres, ret);
-               }
        }
 
        clear_zone_contiguous(zone);
@@ -1820,6 +1806,25 @@ void try_offline_node(int nid)
 }
 EXPORT_SYMBOL(try_offline_node);
 
+static void __release_memory_resource(u64 start, u64 size)
+{
+       int ret;
+
+       /*
+        * When removing memory in the same granularity as it was added,
+        * this function never fails. It might only fail if resources
+        * have to be adjusted or split. We'll ignore the error, as
+        * removing of memory cannot fail.
+        */
+       ret = release_mem_region_adjustable(&iomem_resource, start, size);
+       if (ret) {
+               resource_size_t endres = start + size - 1;
+
+               pr_warn("Unable to release resource <%pa-%pa> (%d)\n",
+                       &start, &endres, ret);
+       }
+}
+
 /**
  * remove_memory
  * @nid: the node ID
@@ -1854,6 +1859,7 @@ void __ref __remove_memory(int nid, u64 start, u64 size)
        memblock_remove(start, size);
 
        arch_remove_memory(nid, start, size, NULL);
+       __release_memory_resource(start, size);
 
        try_offline_node(nid);
 
-- 
2.17.2

Reply via email to