Commit e1c158e4 authored by David Hildenbrand's avatar David Hildenbrand Committed by Linus Torvalds

mm/memory_hotplug: remove nid parameter from remove_memory() and friends

There is only a single user remaining.  We can simply lookup the nid only
used for node offlining purposes when walking our memory blocks.  We don't
expect to remove multi-nid ranges; and if we'd ever do, we most probably
don't care about removing multi-nid ranges that actually result in empty
nodes.

If ever required, we can detect the "multi-nid" scenario and simply try
offlining all online nodes.

Link: https://lkml.kernel.org/r/20210712124052.26491-4-david@redhat.comSigned-off-by: default avatarDavid Hildenbrand <david@redhat.com>
Acked-by: Michael Ellerman <mpe@ellerman.id.au> (powerpc)
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Len Brown <lenb@kernel.org>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Vishal Verma <vishal.l.verma@intel.com>
Cc: Dave Jiang <dave.jiang@intel.com>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Jason Wang <jasowang@redhat.com>
Cc: Nathan Lynch <nathanl@linux.ibm.com>
Cc: Laurent Dufour <ldufour@linux.ibm.com>
Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com>
Cc: Scott Cheloha <cheloha@linux.ibm.com>
Cc: Anton Blanchard <anton@ozlabs.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Anshuman Khandual <anshuman.khandual@arm.com>
Cc: Ard Biesheuvel <ardb@kernel.org>
Cc: Baoquan He <bhe@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Christophe Leroy <christophe.leroy@c-s.fr>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jia He <justin.he@arm.com>
Cc: Joe Perches <joe@perches.com>
Cc: Kefeng Wang <wangkefeng.wang@huawei.com>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Michel Lespinasse <michel@lespinasse.org>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: Pankaj Gupta <pankaj.gupta@ionos.com>
Cc: Pankaj Gupta <pankaj.gupta.linux@gmail.com>
Cc: Pavel Tatashin <pasha.tatashin@soleen.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Pierre Morel <pmorel@linux.ibm.com>
Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Cc: Rich Felker <dalias@libc.org>
Cc: Sergei Trofimovich <slyfox@gentoo.org>
Cc: Thiago Jung Bauermann <bauerman@linux.ibm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Vitaly Kuznetsov <vkuznets@redhat.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Wei Yang <richard.weiyang@linux.alibaba.com>
Cc: Will Deacon <will@kernel.org>
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 65a2aa5f
...@@ -286,7 +286,7 @@ static int pseries_remove_memblock(unsigned long base, unsigned long memblock_si ...@@ -286,7 +286,7 @@ static int pseries_remove_memblock(unsigned long base, unsigned long memblock_si
{ {
unsigned long block_sz, start_pfn; unsigned long block_sz, start_pfn;
int sections_per_block; int sections_per_block;
int i, nid; int i;
start_pfn = base >> PAGE_SHIFT; start_pfn = base >> PAGE_SHIFT;
...@@ -297,10 +297,9 @@ static int pseries_remove_memblock(unsigned long base, unsigned long memblock_si ...@@ -297,10 +297,9 @@ static int pseries_remove_memblock(unsigned long base, unsigned long memblock_si
block_sz = pseries_memory_block_size(); block_sz = pseries_memory_block_size();
sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE; sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE;
nid = memory_add_physaddr_to_nid(base);
for (i = 0; i < sections_per_block; i++) { for (i = 0; i < sections_per_block; i++) {
__remove_memory(nid, base, MIN_MEMORY_BLOCK_SIZE); __remove_memory(base, MIN_MEMORY_BLOCK_SIZE);
base += MIN_MEMORY_BLOCK_SIZE; base += MIN_MEMORY_BLOCK_SIZE;
} }
...@@ -387,7 +386,7 @@ static int dlpar_remove_lmb(struct drmem_lmb *lmb) ...@@ -387,7 +386,7 @@ static int dlpar_remove_lmb(struct drmem_lmb *lmb)
block_sz = pseries_memory_block_size(); block_sz = pseries_memory_block_size();
__remove_memory(mem_block->nid, lmb->base_addr, block_sz); __remove_memory(lmb->base_addr, block_sz);
put_device(&mem_block->dev); put_device(&mem_block->dev);
/* Update memory regions for memory remove */ /* Update memory regions for memory remove */
...@@ -660,7 +659,7 @@ static int dlpar_add_lmb(struct drmem_lmb *lmb) ...@@ -660,7 +659,7 @@ static int dlpar_add_lmb(struct drmem_lmb *lmb)
rc = dlpar_online_lmb(lmb); rc = dlpar_online_lmb(lmb);
if (rc) { if (rc) {
__remove_memory(nid, lmb->base_addr, block_sz); __remove_memory(lmb->base_addr, block_sz);
invalidate_lmb_associativity_index(lmb); invalidate_lmb_associativity_index(lmb);
} else { } else {
lmb->flags |= DRCONF_MEM_ASSIGNED; lmb->flags |= DRCONF_MEM_ASSIGNED;
......
...@@ -239,19 +239,14 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) ...@@ -239,19 +239,14 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device)
static void acpi_memory_remove_memory(struct acpi_memory_device *mem_device) static void acpi_memory_remove_memory(struct acpi_memory_device *mem_device)
{ {
acpi_handle handle = mem_device->device->handle;
struct acpi_memory_info *info, *n; struct acpi_memory_info *info, *n;
int nid = acpi_get_node(handle);
list_for_each_entry_safe(info, n, &mem_device->res_list, list) { list_for_each_entry_safe(info, n, &mem_device->res_list, list) {
if (!info->enabled) if (!info->enabled)
continue; continue;
if (nid == NUMA_NO_NODE)
nid = memory_add_physaddr_to_nid(info->start_addr);
acpi_unbind_memory_blocks(info); acpi_unbind_memory_blocks(info);
__remove_memory(nid, info->start_addr, info->length); __remove_memory(info->start_addr, info->length);
list_del(&info->list); list_del(&info->list);
kfree(info); kfree(info);
} }
......
...@@ -156,8 +156,7 @@ static void dev_dax_kmem_remove(struct dev_dax *dev_dax) ...@@ -156,8 +156,7 @@ static void dev_dax_kmem_remove(struct dev_dax *dev_dax)
if (rc) if (rc)
continue; continue;
rc = remove_memory(dev_dax->target_node, range.start, rc = remove_memory(range.start, range_len(&range));
range_len(&range));
if (rc == 0) { if (rc == 0) {
release_resource(data->res[i]); release_resource(data->res[i]);
kfree(data->res[i]); kfree(data->res[i]);
......
...@@ -677,7 +677,7 @@ static int virtio_mem_remove_memory(struct virtio_mem *vm, uint64_t addr, ...@@ -677,7 +677,7 @@ static int virtio_mem_remove_memory(struct virtio_mem *vm, uint64_t addr,
dev_dbg(&vm->vdev->dev, "removing memory: 0x%llx - 0x%llx\n", addr, dev_dbg(&vm->vdev->dev, "removing memory: 0x%llx - 0x%llx\n", addr,
addr + size - 1); addr + size - 1);
rc = remove_memory(vm->nid, addr, size); rc = remove_memory(addr, size);
if (!rc) { if (!rc) {
atomic64_sub(size, &vm->offline_size); atomic64_sub(size, &vm->offline_size);
/* /*
...@@ -720,7 +720,7 @@ static int virtio_mem_offline_and_remove_memory(struct virtio_mem *vm, ...@@ -720,7 +720,7 @@ static int virtio_mem_offline_and_remove_memory(struct virtio_mem *vm,
"offlining and removing memory: 0x%llx - 0x%llx\n", addr, "offlining and removing memory: 0x%llx - 0x%llx\n", addr,
addr + size - 1); addr + size - 1);
rc = offline_and_remove_memory(vm->nid, addr, size); rc = offline_and_remove_memory(addr, size);
if (!rc) { if (!rc) {
atomic64_sub(size, &vm->offline_size); atomic64_sub(size, &vm->offline_size);
/* /*
......
...@@ -292,9 +292,9 @@ static inline void pgdat_resize_init(struct pglist_data *pgdat) {} ...@@ -292,9 +292,9 @@ static inline void pgdat_resize_init(struct pglist_data *pgdat) {}
extern void try_offline_node(int nid); extern void try_offline_node(int nid);
extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages); extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages);
extern int remove_memory(int nid, u64 start, u64 size); extern int remove_memory(u64 start, u64 size);
extern void __remove_memory(int nid, u64 start, u64 size); extern void __remove_memory(u64 start, u64 size);
extern int offline_and_remove_memory(int nid, u64 start, u64 size); extern int offline_and_remove_memory(u64 start, u64 size);
#else #else
static inline void try_offline_node(int nid) {} static inline void try_offline_node(int nid) {}
...@@ -304,12 +304,12 @@ static inline int offline_pages(unsigned long start_pfn, unsigned long nr_pages) ...@@ -304,12 +304,12 @@ static inline int offline_pages(unsigned long start_pfn, unsigned long nr_pages)
return -EINVAL; return -EINVAL;
} }
static inline int remove_memory(int nid, u64 start, u64 size) static inline int remove_memory(u64 start, u64 size)
{ {
return -EBUSY; return -EBUSY;
} }
static inline void __remove_memory(int nid, u64 start, u64 size) {} static inline void __remove_memory(u64 start, u64 size) {}
#endif /* CONFIG_MEMORY_HOTREMOVE */ #endif /* CONFIG_MEMORY_HOTREMOVE */
extern void set_zone_contiguous(struct zone *zone); extern void set_zone_contiguous(struct zone *zone);
......
...@@ -1739,7 +1739,9 @@ int __ref offline_pages(unsigned long start_pfn, unsigned long nr_pages) ...@@ -1739,7 +1739,9 @@ int __ref offline_pages(unsigned long start_pfn, unsigned long nr_pages)
static int check_memblock_offlined_cb(struct memory_block *mem, void *arg) static int check_memblock_offlined_cb(struct memory_block *mem, void *arg)
{ {
int ret = !is_memblock_offlined(mem); int ret = !is_memblock_offlined(mem);
int *nid = arg;
*nid = mem->nid;
if (unlikely(ret)) { if (unlikely(ret)) {
phys_addr_t beginpa, endpa; phys_addr_t beginpa, endpa;
...@@ -1832,12 +1834,12 @@ void try_offline_node(int nid) ...@@ -1832,12 +1834,12 @@ void try_offline_node(int nid)
} }
EXPORT_SYMBOL(try_offline_node); 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 mhp_altmap = {};
struct vmem_altmap *altmap = NULL; struct vmem_altmap *altmap = NULL;
unsigned long nr_vmemmap_pages; unsigned long nr_vmemmap_pages;
int rc = 0, nid = NUMA_NO_NODE;
BUG_ON(check_hotplug_memory_range(start, size)); BUG_ON(check_hotplug_memory_range(start, size));
...@@ -1845,8 +1847,12 @@ static int __ref try_remove_memory(int nid, u64 start, u64 size) ...@@ -1845,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 * All memory blocks must be offlined before removing memory. Check
* whether all memory blocks in question are offline and return error * whether all memory blocks in question are offline and return error
* if this is not the case. * 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) if (rc)
return rc; return rc;
...@@ -1895,7 +1901,8 @@ static int __ref try_remove_memory(int nid, u64 start, u64 size) ...@@ -1895,7 +1901,8 @@ static int __ref try_remove_memory(int nid, u64 start, u64 size)
release_mem_region_adjustable(start, size); release_mem_region_adjustable(start, size);
try_offline_node(nid); if (nid != NUMA_NO_NODE)
try_offline_node(nid);
mem_hotplug_done(); mem_hotplug_done();
return 0; return 0;
...@@ -1903,7 +1910,6 @@ static int __ref try_remove_memory(int nid, u64 start, u64 size) ...@@ -1903,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 * __remove_memory - Remove memory if every memory block is offline
* @nid: the node ID
* @start: physical address of the region to remove * @start: physical address of the region to remove
* @size: size of the region to remove * @size: size of the region to remove
* *
...@@ -1911,14 +1917,14 @@ static int __ref try_remove_memory(int nid, u64 start, u64 size) ...@@ -1911,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 * and online/offline operations before this call, as required by
* try_offline_node(). * 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 * trigger BUG() if some memory is not offlined prior to calling this
* function * function
*/ */
if (try_remove_memory(nid, start, size)) if (try_remove_memory(start, size))
BUG(); BUG();
} }
...@@ -1926,12 +1932,12 @@ void __remove_memory(int nid, u64 start, u64 size) ...@@ -1926,12 +1932,12 @@ void __remove_memory(int nid, u64 start, u64 size)
* Remove memory if every memory block is offline, otherwise return -EBUSY is * Remove memory if every memory block is offline, otherwise return -EBUSY is
* some memory is not offline * some memory is not offline
*/ */
int remove_memory(int nid, u64 start, u64 size) int remove_memory(u64 start, u64 size)
{ {
int rc; int rc;
lock_device_hotplug(); lock_device_hotplug();
rc = try_remove_memory(nid, start, size); rc = try_remove_memory(start, size);
unlock_device_hotplug(); unlock_device_hotplug();
return rc; return rc;
...@@ -1991,7 +1997,7 @@ static int try_reonline_memory_block(struct memory_block *mem, void *arg) ...@@ -1991,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 * unplugged all memory (so it's no longer in use) and want to offline + remove
* that memory. * 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(); const unsigned long mb_count = size / memory_block_size_bytes();
uint8_t *online_types, *tmp; uint8_t *online_types, *tmp;
...@@ -2027,7 +2033,7 @@ int offline_and_remove_memory(int nid, u64 start, u64 size) ...@@ -2027,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. * This cannot fail as it cannot get onlined in the meantime.
*/ */
if (!rc) { if (!rc) {
rc = try_remove_memory(nid, start, size); rc = try_remove_memory(start, size);
if (rc) if (rc)
pr_err("%s: Failed to remove memory: %d", __func__, rc); pr_err("%s: Failed to remove memory: %d", __func__, rc);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment