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

powerpc/pseries/hotplug-memory: stop checking is_mem_section_removable()

In commit 53cdc1cb ("drivers/base/memory.c: indicate all memory blocks
as removable"), the user space interface to compute whether a memory block
can be offlined (exposed via /sys/devices/system/memory/memoryX/removable)
has effectively been deprecated.  We want to remove the leftovers of the
kernel implementation.

When offlining a memory block (mm/memory_hotplug.c:__offline_pages()),
we'll start by:
 1. Testing if it contains any holes, and reject if so
 2. Testing if pages belong to different zones, and reject if so
 3. Isolating the page range, checking if it contains any unmovable pages

Using is_mem_section_removable() before trying to offline is not only
racy, it can easily result in false positives/negatives.  Let's stop
manually checking is_mem_section_removable(), and let device_offline()
handle it completely instead.  We can remove the racy
is_mem_section_removable() implementation next.

We now take more locks (e.g., memory hotplug lock when offlining and the
zone lock when isolating), but maybe we should optimize that
implementation instead if this ever becomes a real problem (after all,
memory unplug is already an expensive operation).  We started using
is_mem_section_removable() in commit 51925fb3 ("powerpc/pseries:
Implement memory hotplug remove in the kernel"), with the initial
hotremove support of lmbs.
Signed-off-by: default avatarDavid Hildenbrand <david@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Cc: Nathan Fontenot <nfont@linux.vnet.ibm.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: Baoquan He <bhe@redhat.com>
Cc: Wei Yang <richard.weiyang@gmail.com>
Link: http://lkml.kernel.org/r/20200407135416.24093-2-david@redhat.comSigned-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent fa6d9ec7
...@@ -337,39 +337,19 @@ static int pseries_remove_mem_node(struct device_node *np) ...@@ -337,39 +337,19 @@ static int pseries_remove_mem_node(struct device_node *np)
static bool lmb_is_removable(struct drmem_lmb *lmb) static bool lmb_is_removable(struct drmem_lmb *lmb)
{ {
int i, scns_per_block;
bool rc = true;
unsigned long pfn, block_sz;
u64 phys_addr;
if (!(lmb->flags & DRCONF_MEM_ASSIGNED)) if (!(lmb->flags & DRCONF_MEM_ASSIGNED))
return false; return false;
block_sz = memory_block_size_bytes();
scns_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE;
phys_addr = lmb->base_addr;
#ifdef CONFIG_FA_DUMP #ifdef CONFIG_FA_DUMP
/* /*
* Don't hot-remove memory that falls in fadump boot memory area * Don't hot-remove memory that falls in fadump boot memory area
* and memory that is reserved for capturing old kernel memory. * and memory that is reserved for capturing old kernel memory.
*/ */
if (is_fadump_memory_area(phys_addr, block_sz)) if (is_fadump_memory_area(lmb->base_addr, memory_block_size_bytes()))
return false; return false;
#endif #endif
/* device_offline() will determine if we can actually remove this lmb */
for (i = 0; i < scns_per_block; i++) { return true;
pfn = PFN_DOWN(phys_addr);
if (!pfn_in_present_section(pfn)) {
phys_addr += MIN_MEMORY_BLOCK_SIZE;
continue;
}
rc = rc && is_mem_section_removable(pfn, PAGES_PER_SECTION);
phys_addr += MIN_MEMORY_BLOCK_SIZE;
}
return rc;
} }
static int dlpar_add_lmb(struct drmem_lmb *); static int dlpar_add_lmb(struct drmem_lmb *);
......
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