powerpc/papr_scm: Update drc_pmem_unbind() to use H_SCM_UNBIND_ALL
The new hcall named H_SCM_UNBIND_ALL has been introduce that can unbind all or specific scm memory assigned to an lpar. This is more efficient than using H_SCM_UNBIND_MEM as currently we don't support partial unbind of scm memory. Hence this patch proposes following changes to drc_pmem_unbind(): * Update drc_pmem_unbind() to replace hcall H_SCM_UNBIND_MEM to H_SCM_UNBIND_ALL. * Update drc_pmem_unbind() to handles cases when PHYP asks the guest kernel to wait for specific amount of time before retrying the hcall via the 'LONG_BUSY' return value. * Ensure appropriate error code is returned back from the function in case of an error. Reviewed-by: Oliver O'Halloran <oohall@gmail.com> Signed-off-by: Vaibhav Jain <vaibhav@linux.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20190629160610.23402-3-vaibhav@linux.ibm.com
This commit is contained in:
parent
6d140e7569
commit
0d7fc080ba
|
@ -11,6 +11,7 @@
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/libnvdimm.h>
|
#include <linux/libnvdimm.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
|
||||||
#include <asm/plpar_wrappers.h>
|
#include <asm/plpar_wrappers.h>
|
||||||
|
|
||||||
|
@ -78,22 +79,36 @@ static int drc_pmem_bind(struct papr_scm_priv *p)
|
||||||
static int drc_pmem_unbind(struct papr_scm_priv *p)
|
static int drc_pmem_unbind(struct papr_scm_priv *p)
|
||||||
{
|
{
|
||||||
unsigned long ret[PLPAR_HCALL_BUFSIZE];
|
unsigned long ret[PLPAR_HCALL_BUFSIZE];
|
||||||
uint64_t rc, token;
|
uint64_t token = 0;
|
||||||
|
int64_t rc;
|
||||||
|
|
||||||
token = 0;
|
dev_dbg(&p->pdev->dev, "unbind drc %x\n", p->drc_index);
|
||||||
|
|
||||||
/* NB: unbind has the same retry requirements mentioned above */
|
/* NB: unbind has the same retry requirements as drc_pmem_bind() */
|
||||||
do {
|
do {
|
||||||
rc = plpar_hcall(H_SCM_UNBIND_MEM, ret, p->drc_index,
|
|
||||||
p->bound_addr, p->blocks, token);
|
/* Unbind of all SCM resources associated with drcIndex */
|
||||||
|
rc = plpar_hcall(H_SCM_UNBIND_ALL, ret, H_UNBIND_SCOPE_DRC,
|
||||||
|
p->drc_index, token);
|
||||||
token = ret[0];
|
token = ret[0];
|
||||||
cond_resched();
|
|
||||||
|
/* Check if we are stalled for some time */
|
||||||
|
if (H_IS_LONG_BUSY(rc)) {
|
||||||
|
msleep(get_longbusy_msecs(rc));
|
||||||
|
rc = H_BUSY;
|
||||||
|
} else if (rc == H_BUSY) {
|
||||||
|
cond_resched();
|
||||||
|
}
|
||||||
|
|
||||||
} while (rc == H_BUSY);
|
} while (rc == H_BUSY);
|
||||||
|
|
||||||
if (rc)
|
if (rc)
|
||||||
dev_err(&p->pdev->dev, "unbind error: %lld\n", rc);
|
dev_err(&p->pdev->dev, "unbind error: %lld\n", rc);
|
||||||
|
else
|
||||||
|
dev_dbg(&p->pdev->dev, "unbind drc %x complete\n",
|
||||||
|
p->drc_index);
|
||||||
|
|
||||||
return !!rc;
|
return rc == H_SUCCESS ? 0 : -ENXIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int papr_scm_meta_get(struct papr_scm_priv *p,
|
static int papr_scm_meta_get(struct papr_scm_priv *p,
|
||||||
|
|
Loading…
Reference in New Issue