Skip to content

Commit

Permalink
powerpc/pseries: Revert 'Auto-online hotplugged memory'
Browse files Browse the repository at this point in the history
This reverts commit ec99907 ("powerpc/pseries: Auto-online
hotplugged memory"), and 9dc5128 ("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: ec99907 ("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>
  • Loading branch information
nfont authored and mpe committed Feb 21, 2017
1 parent a311e73 commit 943db62
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 16 deletions.
1 change: 0 additions & 1 deletion arch/powerpc/configs/pseries_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
52 changes: 37 additions & 15 deletions arch/powerpc/platforms/pseries/hotplug-memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
}
Expand Down

0 comments on commit 943db62

Please sign in to comment.