powerpc/pseries: Revert 'Auto-online hotplugged memory'
This reverts commitec99907244
("powerpc/pseries: Auto-online hotplugged memory"), and9dc512819e
("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:
Родитель
a311e738b6
Коммит
943db62c31
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче