powerpc/pseries: Revert 'Auto-online hotplugged memory'

This reverts commit ec99907244 ("powerpc/pseries: Auto-online
hotplugged memory"), and 9dc512819e ("powerpc: Fix unused function
warning 'lmb_to_memblock'").

Using the auto-online acpability does online added memory but does not
update the associated device struct to indicate that the memory is
online. This causes the pseries memory DLPAR code to fail when trying to
remove a LMB that was previously removed and added back. This happens
when validating that the LMB is removable.

This patch reverts to the previous behavior of calling device_online()
to online the LMB when it is DLPAR added and moves the lmb_to_memblock()
routine out of CONFIG_MEMORY_HOTREMOVE now that we call it for add.

Fixes: ec99907244 ("powerpc/pseries: Auto-online hotplugged memory")
Cc: stable@vger.kernel.org # v4.8+
Signed-off-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
Nathan Fontenot 2017-02-15 13:45:30 -05:00 committed by Michael Ellerman
parent a311e738b6
commit 943db62c31
2 changed files with 37 additions and 16 deletions

View file

@ -58,7 +58,6 @@ CONFIG_KEXEC_FILE=y
CONFIG_IRQ_ALL_CPUS=y
CONFIG_MEMORY_HOTPLUG=y
CONFIG_MEMORY_HOTREMOVE=y
CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE=y
CONFIG_KSM=y
CONFIG_TRANSPARENT_HUGEPAGE=y
CONFIG_PPC_64K_PAGES=y

View file

@ -320,6 +320,19 @@ static int dlpar_remove_device_tree_lmb(struct of_drconf_cell *lmb)
return dlpar_update_device_tree_lmb(lmb);
}
static struct memory_block *lmb_to_memblock(struct of_drconf_cell *lmb)
{
unsigned long section_nr;
struct mem_section *mem_sect;
struct memory_block *mem_block;
section_nr = pfn_to_section_nr(PFN_DOWN(lmb->base_addr));
mem_sect = __nr_to_section(section_nr);
mem_block = find_memory_block(mem_sect);
return mem_block;
}
#ifdef CONFIG_MEMORY_HOTREMOVE
static int pseries_remove_memblock(unsigned long base, unsigned int memblock_size)
{
@ -407,19 +420,6 @@ static bool lmb_is_removable(struct of_drconf_cell *lmb)
static int dlpar_add_lmb(struct of_drconf_cell *);
static struct memory_block *lmb_to_memblock(struct of_drconf_cell *lmb)
{
unsigned long section_nr;
struct mem_section *mem_sect;
struct memory_block *mem_block;
section_nr = pfn_to_section_nr(PFN_DOWN(lmb->base_addr));
mem_sect = __nr_to_section(section_nr);
mem_block = find_memory_block(mem_sect);
return mem_block;
}
static int dlpar_remove_lmb(struct of_drconf_cell *lmb)
{
struct memory_block *mem_block;
@ -728,6 +728,20 @@ static int dlpar_memory_remove_by_ic(u32 lmbs_to_remove, u32 drc_index,
}
#endif /* CONFIG_MEMORY_HOTREMOVE */
static int dlpar_online_lmb(struct of_drconf_cell *lmb)
{
struct memory_block *mem_block;
int rc;
mem_block = lmb_to_memblock(lmb);
if (!mem_block)
return -EINVAL;
rc = device_online(&mem_block->dev);
put_device(&mem_block->dev);
return rc;
}
static int dlpar_add_lmb(struct of_drconf_cell *lmb)
{
unsigned long block_sz;
@ -751,10 +765,18 @@ static int dlpar_add_lmb(struct of_drconf_cell *lmb)
/* Add the memory */
rc = add_memory(nid, lmb->base_addr, block_sz);
if (rc)
if (rc) {
dlpar_remove_device_tree_lmb(lmb);
else
return rc;
}
rc = dlpar_online_lmb(lmb);
if (rc) {
remove_memory(nid, lmb->base_addr, block_sz);
dlpar_remove_device_tree_lmb(lmb);
} else {
lmb->flags |= DRCONF_MEM_ASSIGNED;
}
return rc;
}