Commit 0d7fc080 authored by Vaibhav Jain's avatar Vaibhav Jain Committed by Michael Ellerman

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: default avatarOliver O'Halloran <oohall@gmail.com>
Signed-off-by: default avatarVaibhav Jain <vaibhav@linux.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20190629160610.23402-3-vaibhav@linux.ibm.com
parent 6d140e75
...@@ -11,6 +11,7 @@ ...@@ -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) ...@@ -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,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment