mirror of https://gitee.com/openkylin/linux.git
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.com Signed-off-by: David 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: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
65a2aa5f48
commit
e1c158e495
|
@ -286,7 +286,7 @@ static int pseries_remove_memblock(unsigned long base, unsigned long memblock_si
|
|||
{
|
||||
unsigned long block_sz, start_pfn;
|
||||
int sections_per_block;
|
||||
int i, nid;
|
||||
int i;
|
||||
|
||||
start_pfn = base >> PAGE_SHIFT;
|
||||
|
||||
|
@ -297,10 +297,9 @@ static int pseries_remove_memblock(unsigned long base, unsigned long memblock_si
|
|||
|
||||
block_sz = pseries_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++) {
|
||||
__remove_memory(nid, base, MIN_MEMORY_BLOCK_SIZE);
|
||||
__remove_memory(base, MIN_MEMORY_BLOCK_SIZE);
|
||||
base += MIN_MEMORY_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
|
@ -387,7 +386,7 @@ static int dlpar_remove_lmb(struct drmem_lmb *lmb)
|
|||
|
||||
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);
|
||||
|
||||
/* Update memory regions for memory remove */
|
||||
|
@ -660,7 +659,7 @@ static int dlpar_add_lmb(struct drmem_lmb *lmb)
|
|||
|
||||
rc = dlpar_online_lmb(lmb);
|
||||
if (rc) {
|
||||
__remove_memory(nid, lmb->base_addr, block_sz);
|
||||
__remove_memory(lmb->base_addr, block_sz);
|
||||
invalidate_lmb_associativity_index(lmb);
|
||||
} else {
|
||||
lmb->flags |= DRCONF_MEM_ASSIGNED;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
acpi_handle handle = mem_device->device->handle;
|
||||
struct acpi_memory_info *info, *n;
|
||||
int nid = acpi_get_node(handle);
|
||||
|
||||
list_for_each_entry_safe(info, n, &mem_device->res_list, list) {
|
||||
if (!info->enabled)
|
||||
continue;
|
||||
|
||||
if (nid == NUMA_NO_NODE)
|
||||
nid = memory_add_physaddr_to_nid(info->start_addr);
|
||||
|
||||
acpi_unbind_memory_blocks(info);
|
||||
__remove_memory(nid, info->start_addr, info->length);
|
||||
__remove_memory(info->start_addr, info->length);
|
||||
list_del(&info->list);
|
||||
kfree(info);
|
||||
}
|
||||
|
|
|
@ -156,8 +156,7 @@ static void dev_dax_kmem_remove(struct dev_dax *dev_dax)
|
|||
if (rc)
|
||||
continue;
|
||||
|
||||
rc = remove_memory(dev_dax->target_node, range.start,
|
||||
range_len(&range));
|
||||
rc = remove_memory(range.start, range_len(&range));
|
||||
if (rc == 0) {
|
||||
release_resource(data->res[i]);
|
||||
kfree(data->res[i]);
|
||||
|
|
|
@ -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,
|
||||
addr + size - 1);
|
||||
rc = remove_memory(vm->nid, addr, size);
|
||||
rc = remove_memory(addr, size);
|
||||
if (!rc) {
|
||||
atomic64_sub(size, &vm->offline_size);
|
||||
/*
|
||||
|
@ -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,
|
||||
addr + size - 1);
|
||||
|
||||
rc = offline_and_remove_memory(vm->nid, addr, size);
|
||||
rc = offline_and_remove_memory(addr, size);
|
||||
if (!rc) {
|
||||
atomic64_sub(size, &vm->offline_size);
|
||||
/*
|
||||
|
|
|
@ -292,9 +292,9 @@ static inline void pgdat_resize_init(struct pglist_data *pgdat) {}
|
|||
|
||||
extern void try_offline_node(int nid);
|
||||
extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages);
|
||||
extern int remove_memory(int nid, u64 start, u64 size);
|
||||
extern void __remove_memory(int nid, u64 start, u64 size);
|
||||
extern int offline_and_remove_memory(int nid, u64 start, u64 size);
|
||||
extern int remove_memory(u64 start, u64 size);
|
||||
extern void __remove_memory(u64 start, u64 size);
|
||||
extern int offline_and_remove_memory(u64 start, u64 size);
|
||||
|
||||
#else
|
||||
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)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
static inline int remove_memory(int nid, u64 start, u64 size)
|
||||
static inline int remove_memory(u64 start, u64 size)
|
||||
{
|
||||
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 */
|
||||
|
||||
extern void set_zone_contiguous(struct zone *zone);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
int ret = !is_memblock_offlined(mem);
|
||||
int *nid = arg;
|
||||
|
||||
*nid = mem->nid;
|
||||
if (unlikely(ret)) {
|
||||
phys_addr_t beginpa, endpa;
|
||||
|
||||
|
@ -1832,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));
|
||||
|
||||
|
@ -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
|
||||
* 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;
|
||||
|
||||
|
@ -1895,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;
|
||||
|
@ -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
|
||||
* @nid: the node ID
|
||||
* @start: physical address 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)
|
|||
* 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();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
* 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;
|
||||
|
@ -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
|
||||
* 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;
|
||||
|
@ -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.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue