Skip to content

Commit

Permalink
powerpc/pseries: Make the acquire/release of the drc for memory a sep…
Browse files Browse the repository at this point in the history
…erate step

When adding and removing LMBs we should make the acquire/release of
the DRC a separate step to allow for a few improvements. First
this will ensure that LMBs removed during a remove by count operation
are all available if a error occurs and we need to add them back. By
first removeing all the LMBs from the kernel before releasing their
DRCs the LMBs are available to add back should an error occur.

Also, this will allow for faster re-add operations of memory for
PRRN event handling since we can skip the unneeded step of having
to release the DRC and the acquire it back.

Signed-off-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
Signed-off-by: John Allen <jallen@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
  • Loading branch information
John Allen authored and Michael Ellerman committed Feb 2, 2017
1 parent e71ff89 commit c21f515
Showing 1 changed file with 22 additions and 12 deletions.
34 changes: 22 additions & 12 deletions arch/powerpc/platforms/pseries/hotplug-memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -446,9 +446,7 @@ static int dlpar_remove_lmb(struct of_drconf_cell *lmb)
/* Update memory regions for memory remove */
memblock_remove(lmb->base_addr, block_sz);

dlpar_release_drc(lmb->drc_index);
dlpar_remove_device_tree_lmb(lmb);

return 0;
}

Expand Down Expand Up @@ -516,6 +514,7 @@ static int dlpar_memory_remove_by_count(u32 lmbs_to_remove,
if (!lmbs[i].reserved)
continue;

dlpar_release_drc(lmbs[i].drc_index);
pr_info("Memory at %llx was hot-removed\n",
lmbs[i].base_addr);

Expand Down Expand Up @@ -545,6 +544,9 @@ static int dlpar_memory_remove_by_index(u32 drc_index, struct property *prop)
if (lmbs[i].drc_index == drc_index) {
lmb_found = 1;
rc = dlpar_remove_lmb(&lmbs[i]);
if (!rc)
dlpar_release_drc(lmbs[i].drc_index);

break;
}
}
Expand Down Expand Up @@ -599,10 +601,6 @@ static int dlpar_add_lmb(struct of_drconf_cell *lmb)
if (lmb->flags & DRCONF_MEM_ASSIGNED)
return -EINVAL;

rc = dlpar_acquire_drc(lmb->drc_index);
if (rc)
return rc;

rc = dlpar_add_device_tree_lmb(lmb);
if (rc) {
pr_err("Couldn't update device tree for drc index %x\n",
Expand All @@ -618,12 +616,10 @@ 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);
dlpar_release_drc(lmb->drc_index);
} else {
else
lmb->flags |= DRCONF_MEM_ASSIGNED;
}

return rc;
}
Expand Down Expand Up @@ -655,10 +651,16 @@ static int dlpar_memory_add_by_count(u32 lmbs_to_add, struct property *prop)
return -EINVAL;

for (i = 0; i < num_lmbs && lmbs_to_add != lmbs_added; i++) {
rc = dlpar_add_lmb(&lmbs[i]);
rc = dlpar_acquire_drc(lmbs[i].drc_index);
if (rc)
continue;

rc = dlpar_add_lmb(&lmbs[i]);
if (rc) {
dlpar_release_drc(lmbs[i].drc_index);
continue;
}

lmbs_added++;

/* Mark this lmb so we can remove it later if all of the
Expand All @@ -678,6 +680,8 @@ static int dlpar_memory_add_by_count(u32 lmbs_to_add, struct property *prop)
if (rc)
pr_err("Failed to remove LMB, drc index %x\n",
be32_to_cpu(lmbs[i].drc_index));
else
dlpar_release_drc(lmbs[i].drc_index);
}
rc = -EINVAL;
} else {
Expand Down Expand Up @@ -711,7 +715,13 @@ static int dlpar_memory_add_by_index(u32 drc_index, struct property *prop)
for (i = 0; i < num_lmbs; i++) {
if (lmbs[i].drc_index == drc_index) {
lmb_found = 1;
rc = dlpar_add_lmb(&lmbs[i]);
rc = dlpar_acquire_drc(lmbs[i].drc_index);
if (!rc) {
rc = dlpar_add_lmb(&lmbs[i]);
if (rc)
dlpar_release_drc(lmbs[i].drc_index);
}

break;
}
}
Expand Down

0 comments on commit c21f515

Please sign in to comment.