mm/memory_hotplug: remove nid parameter from remove_memory() and friends
[linux-2.6-microblaze.git] / mm / memory_hotplug.c
index 8cb75b2..6ea62ef 100644 (file)
@@ -708,8 +708,8 @@ static inline struct zone *default_zone_for_pfn(int nid, unsigned long start_pfn
        return movable_node_enabled ? movable_zone : kernel_zone;
 }
 
-struct zone *zone_for_pfn_range(int online_type, int nid, unsigned start_pfn,
-               unsigned long nr_pages)
+struct zone *zone_for_pfn_range(int online_type, int nid,
+               unsigned long start_pfn, unsigned long nr_pages)
 {
        if (online_type == MMOP_ONLINE_KERNEL)
                return default_kernel_zone_for_pfn(nid, start_pfn, nr_pages);
@@ -1106,7 +1106,7 @@ int __ref add_memory_resource(int nid, struct resource *res, mhp_t mhp_flags)
        /* create memory block devices after memory was added */
        ret = create_memory_block_devices(start, size, mhp_altmap.alloc);
        if (ret) {
-               arch_remove_memory(nid, start, size, NULL);
+               arch_remove_memory(start, size, NULL);
                goto error;
        }
 
@@ -1298,7 +1298,7 @@ struct zone *test_pages_in_a_zone(unsigned long start_pfn,
        unsigned long pfn, sec_end_pfn;
        struct zone *zone = NULL;
        struct page *page;
-       int i;
+
        for (pfn = start_pfn, sec_end_pfn = SECTION_ALIGN_UP(start_pfn + 1);
             pfn < end_pfn;
             pfn = sec_end_pfn, sec_end_pfn += PAGES_PER_SECTION) {
@@ -1307,17 +1307,10 @@ struct zone *test_pages_in_a_zone(unsigned long start_pfn,
                        continue;
                for (; pfn < sec_end_pfn && pfn < end_pfn;
                     pfn += MAX_ORDER_NR_PAGES) {
-                       i = 0;
-                       /* This is just a CONFIG_HOLES_IN_ZONE check.*/
-                       while ((i < MAX_ORDER_NR_PAGES) &&
-                               !pfn_valid_within(pfn + i))
-                               i++;
-                       if (i == MAX_ORDER_NR_PAGES || pfn + i >= end_pfn)
-                               continue;
                        /* Check if we got outside of the zone */
-                       if (zone && !zone_spans_pfn(zone, pfn + i))
+                       if (zone && !zone_spans_pfn(zone, pfn))
                                return NULL;
-                       page = pfn_to_page(pfn + i);
+                       page = pfn_to_page(pfn);
                        if (zone && page_zone(page) != zone)
                                return NULL;
                        zone = page_zone(page);
@@ -1731,6 +1724,7 @@ failed_removal_isolated:
        undo_isolate_page_range(start_pfn, end_pfn, MIGRATE_MOVABLE);
        memory_notify(MEM_CANCEL_OFFLINE, &arg);
 failed_removal_pcplists_disabled:
+       lru_cache_enable();
        zone_pcp_enable(zone);
 failed_removal:
        pr_debug("memory offlining [mem %#010llx-%#010llx] failed due to %s\n",
@@ -1745,7 +1739,9 @@ failed_removal:
 static int check_memblock_offlined_cb(struct memory_block *mem, void *arg)
 {
        int ret = !is_memblock_offlined(mem);
+       int *nid = arg;
 
+       *nid = mem->nid;
        if (unlikely(ret)) {
                phys_addr_t beginpa, endpa;
 
@@ -1838,12 +1834,12 @@ void try_offline_node(int nid)
 }
 EXPORT_SYMBOL(try_offline_node);
 
-static int __ref try_remove_memory(int nid, u64 start, u64 size)
+static int __ref try_remove_memory(u64 start, u64 size)
 {
-       int rc = 0;
        struct vmem_altmap mhp_altmap = {};
        struct vmem_altmap *altmap = NULL;
        unsigned long nr_vmemmap_pages;
+       int rc = 0, nid = NUMA_NO_NODE;
 
        BUG_ON(check_hotplug_memory_range(start, size));
 
@@ -1851,8 +1847,12 @@ static int __ref try_remove_memory(int nid, u64 start, u64 size)
         * All memory blocks must be offlined before removing memory.  Check
         * whether all memory blocks in question are offline and return error
         * if this is not the case.
+        *
+        * While at it, determine the nid. Note that if we'd have mixed nodes,
+        * we'd only try to offline the last determined one -- which is good
+        * enough for the cases we care about.
         */
-       rc = walk_memory_blocks(start, size, NULL, check_memblock_offlined_cb);
+       rc = walk_memory_blocks(start, size, &nid, check_memblock_offlined_cb);
        if (rc)
                return rc;
 
@@ -1892,7 +1892,7 @@ static int __ref try_remove_memory(int nid, u64 start, u64 size)
 
        mem_hotplug_begin();
 
-       arch_remove_memory(nid, start, size, altmap);
+       arch_remove_memory(start, size, altmap);
 
        if (IS_ENABLED(CONFIG_ARCH_KEEP_MEMBLOCK)) {
                memblock_free(start, size);
@@ -1901,7 +1901,8 @@ static int __ref try_remove_memory(int nid, u64 start, u64 size)
 
        release_mem_region_adjustable(start, size);
 
-       try_offline_node(nid);
+       if (nid != NUMA_NO_NODE)
+               try_offline_node(nid);
 
        mem_hotplug_done();
        return 0;
@@ -1909,7 +1910,6 @@ static int __ref try_remove_memory(int nid, u64 start, u64 size)
 
 /**
  * __remove_memory - Remove memory if every memory block is offline
- * @nid: the node ID
  * @start: physical address of the region to remove
  * @size: size of the region to remove
  *
@@ -1917,14 +1917,14 @@ static int __ref try_remove_memory(int nid, u64 start, u64 size)
  * and online/offline operations before this call, as required by
  * try_offline_node().
  */
-void __remove_memory(int nid, u64 start, u64 size)
+void __remove_memory(u64 start, u64 size)
 {
 
        /*
         * trigger BUG() if some memory is not offlined prior to calling this
         * function
         */
-       if (try_remove_memory(nid, start, size))
+       if (try_remove_memory(start, size))
                BUG();
 }
 
@@ -1932,12 +1932,12 @@ void __remove_memory(int nid, u64 start, u64 size)
  * Remove memory if every memory block is offline, otherwise return -EBUSY is
  * some memory is not offline
  */
-int remove_memory(int nid, u64 start, u64 size)
+int remove_memory(u64 start, u64 size)
 {
        int rc;
 
        lock_device_hotplug();
-       rc  = try_remove_memory(nid, start, size);
+       rc = try_remove_memory(start, size);
        unlock_device_hotplug();
 
        return rc;
@@ -1997,7 +1997,7 @@ static int try_reonline_memory_block(struct memory_block *mem, void *arg)
  * unplugged all memory (so it's no longer in use) and want to offline + remove
  * that memory.
  */
-int offline_and_remove_memory(int nid, u64 start, u64 size)
+int offline_and_remove_memory(u64 start, u64 size)
 {
        const unsigned long mb_count = size / memory_block_size_bytes();
        uint8_t *online_types, *tmp;
@@ -2033,7 +2033,7 @@ int offline_and_remove_memory(int nid, u64 start, u64 size)
         * This cannot fail as it cannot get onlined in the meantime.
         */
        if (!rc) {
-               rc = try_remove_memory(nid, start, size);
+               rc = try_remove_memory(start, size);
                if (rc)
                        pr_err("%s: Failed to remove memory: %d", __func__, rc);
        }