*   assumes that all children remain in the lower address entry for
  *   simplicity.  Enhance this logic when necessary.
  */
-int release_mem_region_adjustable(struct resource *parent,
-                                 resource_size_t start, resource_size_t size)
+void release_mem_region_adjustable(struct resource *parent,
+                                  resource_size_t start, resource_size_t size)
 {
+       struct resource *new_res = NULL;
+       bool alloc_nofail = false;
        struct resource **p;
        struct resource *res;
-       struct resource *new_res;
        resource_size_t end;
-       int ret = -EINVAL;
 
        end = start + size - 1;
-       if ((start < parent->start) || (end > parent->end))
-               return ret;
+       if (WARN_ON_ONCE((start < parent->start) || (end > parent->end)))
+               return;
 
-       /* The alloc_resource() result gets checked later */
-       new_res = alloc_resource(GFP_KERNEL);
+       /*
+        * We free up quite a lot of memory on memory hotunplug (esp., memap),
+        * just before releasing the region. This is highly unlikely to
+        * fail - let's play save and make it never fail as the caller cannot
+        * perform any error handling (e.g., trying to re-add memory will fail
+        * similarly).
+        */
+retry:
+       new_res = alloc_resource(GFP_KERNEL | (alloc_nofail ? __GFP_NOFAIL : 0));
 
        p = &parent->child;
        write_lock(&resource_lock);
                 * so if we are dealing with them, let us just back off here.
                 */
                if (!(res->flags & IORESOURCE_SYSRAM)) {
-                       ret = 0;
                        break;
                }
 
                        /* free the whole entry */
                        *p = res->sibling;
                        free_resource(res);
-                       ret = 0;
                } else if (res->start == start && res->end != end) {
                        /* adjust the start */
-                       ret = __adjust_resource(res, end + 1,
-                                               res->end - end);
+                       WARN_ON_ONCE(__adjust_resource(res, end + 1,
+                                                      res->end - end));
                } else if (res->start != start && res->end == end) {
                        /* adjust the end */
-                       ret = __adjust_resource(res, res->start,
-                                               start - res->start);
+                       WARN_ON_ONCE(__adjust_resource(res, res->start,
+                                                      start - res->start));
                } else {
-                       /* split into two entries */
+                       /* split into two entries - we need a new resource */
                        if (!new_res) {
-                               ret = -ENOMEM;
-                               break;
+                               new_res = alloc_resource(GFP_ATOMIC);
+                               if (!new_res) {
+                                       alloc_nofail = true;
+                                       write_unlock(&resource_lock);
+                                       goto retry;
+                               }
                        }
                        new_res->name = res->name;
                        new_res->start = end + 1;
                        new_res->sibling = res->sibling;
                        new_res->child = NULL;
 
-                       ret = __adjust_resource(res, res->start,
-                                               start - res->start);
-                       if (ret)
+                       if (WARN_ON_ONCE(__adjust_resource(res, res->start,
+                                                          start - res->start)))
                                break;
                        res->sibling = new_res;
                        new_res = NULL;
 
        write_unlock(&resource_lock);
        free_resource(new_res);
-       return ret;
 }
 #endif /* CONFIG_MEMORY_HOTREMOVE */
 
 
 }
 EXPORT_SYMBOL(try_offline_node);
 
-static void __release_memory_resource(resource_size_t start,
-                                     resource_size_t 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);
-       }
-}
-
 static int __ref try_remove_memory(int nid, u64 start, u64 size)
 {
        int rc = 0;
                memblock_remove(start, size);
        }
 
-       __release_memory_resource(start, size);
+       release_mem_region_adjustable(&iomem_resource, start, size);
 
        try_offline_node(nid);