Presently an error is returned in response to hcall H_SCM_BIND_MEM when a
new kernel boots on lpar via kexec. This prevents papr_scm from registering
drc memory regions with nvdimm. The error reported is of the form below:
"papr_scm ibm,persistent-memory:ibm,pmemory@44100002: bind err: -68"
On investigation it was revealed that phyp returns this error as previous
kernel did not completely release bindings for drc scm-memory blocks and
hence phyp rejected request for re-binding these block to lpar with error
H_OVERLAP. Also support for a new H_SCM_UNBIND_ALL is recently added which
is better suited for releasing all the bound scm-memory block from an lpar.
So leveraging new hcall H_SCM_UNBIND_ALL, we can workaround H_OVERLAP issue
during kexec by forcing an unbind of all drm scm-memory blocks and issuing
H_SCM_BIND_MEM to re-bind the drc scm-memory blocks to lpar. This sequence
will also be needed when a new kernel boot on lpar after previous kernel
panicked and it never got an opportunity to call H_SCM_UNBIND_MEM/ALL.
Hence this patch-set implements following changes to papr_scm module:
* Update hvcall.h to include opcodes for new hcall H_SCM_UNBIND_ALL.
* Update it to use H_SCM_UNBIND_ALL instead of H_SCM_UNBIND_MEM
* In case hcall H_SCM_BIND_MEM fails with error H_OVERLAP, force
H_SCM_UNBIND_ALL and retry the bind operation again.
With the patch-set applied re-bind of drc scm-memory to lpar succeeds after
a kexec to new kernel as illustrated below:
# Old kernel
$ sudo ndctl list -R
[
{
"dev":"region0",
<snip>
....
}
]
# kexec to new kernel
$ sudo kexec --initrd=... vmlinux
...
...
I'm in purgatory
...
papr_scm ibm,persistent-memory:ibm,pmemory@44100002: Un-binding and retrying
...
# New kernel
$ sudo ndctl list -R
[
{
"dev":"region0",
<snip>
....
}
]
---
Change-log:
v2:
* Addressed review comments from Oliver on v1 patchset.
Vaibhav Jain (3):
powerpc/pseries: Update SCM hcall op-codes in hvcall.h
powerpc/papr_scm: Update drc_pmem_unbind() to use H_SCM_UNBIND_ALL
powerpc/papr_scm: Force a scm-unbind if initial scm-bind fails
arch/powerpc/include/asm/hvcall.h | 9 +++--
arch/powerpc/platforms/pseries/papr_scm.c | 44 ++++++++++++++++++-----
2 files changed, 43 insertions(+), 10 deletions(-)
--
2.21.0
Update the hvcalls.h to include op-codes for new hcalls introduce to
manage SCM memory. Also update existing hcall definitions to reflect
current papr specification for SCM.
Signed-off-by: Vaibhav Jain <redacted>
---
Change-log:
v2:
* None new patch in this series.
---
arch/powerpc/include/asm/hvcall.h | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
On Tue, Jun 25, 2019 at 10:27 PM Vaibhav Jain [off-list ref] wrote:
quoted hunk
Update the hvcalls.h to include op-codes for new hcalls introduce to
manage SCM memory. Also update existing hcall definitions to reflect
current papr specification for SCM.
Signed-off-by: Vaibhav Jain <redacted>
---
Change-log:
v2:
* None new patch in this series.
---
arch/powerpc/include/asm/hvcall.h | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
The new hcall named H_SCM_UNBIND_ALL has been introduce that can
unbind all the memory drc memory-blocks assigned to an lpar. This is
more efficient than using H_SCM_UNBIND_MEM as currently we don't
support partial unbind of drc memory-blocks.
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.
Signed-off-by: Vaibhav Jain <redacted>
---
Change-log:
v2:
* Added a dev_dbg when unbind operation succeeds [Oliver]
* Changed type of variable 'rc' to int64_t [Oliver]
* Removed the code that was logging a warning in case bind operation
takes >1-seconds [Oliver]
* Spinned off changes to hvcall.h as a separate patch. [Oliver]
---
arch/powerpc/platforms/pseries/papr_scm.c | 29 +++++++++++++++++------
1 file changed, 22 insertions(+), 7 deletions(-)
@@ -77,22 +78,36 @@ static int drc_pmem_bind(struct papr_scm_priv *p)staticintdrc_pmem_unbind(structpapr_scm_priv*p){unsignedlongret[PLPAR_HCALL_BUFSIZE];-uint64_trc,token;+uint64_ttoken;+int64_trc;-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{-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];-cond_resched();++/* Check if we are stalled for some time */+if(H_IS_LONG_BUSY(rc)){+msleep(get_longbusy_msecs(rc));+rc=H_BUSY;+}elseif(rc==H_BUSY){+cond_resched();+}+}while(rc==H_BUSY);if(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;+returnrc==H_SUCCESS?0:-ENXIO;}staticintpapr_scm_meta_get(structpapr_scm_priv*p,
On Tue, Jun 25, 2019 at 10:27 PM Vaibhav Jain [off-list ref] wrote:
The new hcall named H_SCM_UNBIND_ALL has been introduce that can
unbind all the memory drc memory-blocks assigned to an lpar.
This is a little muddy. For normal memory each block has a DRC so you
can add/remove individual blocks by configuring or deconfiguring the
DRC for that block. For storage class memory the DRC refers to the SCM
volume as a whole rather than an individual block so a "memory DRC"
isn't really what you're taking about here.
This is probably being a little pedantic, but I find the whole DRC
system confusing enough as-is so it's good to be clear about these
things.
more efficient than using H_SCM_UNBIND_MEM as currently we don't
support partial unbind of drc memory-blocks.
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.
Signed-off-by: Vaibhav Jain <redacted>
---
Change-log:
v2:
* Added a dev_dbg when unbind operation succeeds [Oliver]
* Changed type of variable 'rc' to int64_t [Oliver]
* Removed the code that was logging a warning in case bind operation
takes >1-seconds [Oliver]
* Spinned off changes to hvcall.h as a separate patch. [Oliver]
Looks good otherwise, when you respin feel free to add:
Reviewed-by: Oliver O'Halloran <oohall@gmail.com>
In some cases initial bind of scm memory for an lpar can fail if
previously it wasn't released using a scm-unbind hcall. This situation
can arise due to panic of the previous kernel or forced lpar
fadump. In such cases the H_SCM_BIND_MEM return a H_OVERLAP error.
To mitigate such cases the patch updates papr_scm_probe() to force a
call to drc_pmem_unbind() in case the initial bind of scm memory fails
with EBUSY error. In case scm-bind operation again fails after the
forced scm-unbind then we follow the existing error path. We also
update drc_pmem_bind() to handle the H_OVERLAP error returned by phyp
and indicate it as a EBUSY error back to the caller.
Suggested-by: "Oliver O'Halloran" <oohall@gmail.com>
Signed-off-by: Vaibhav Jain <redacted>
---
Change-log:
v2:
* Moved the retry code from drc_pmem_bind() to papr_scm_probe()
[Oliver]
* Changed the type of variable 'rc' in drc_pmem_bind() to
int64_t. [Oliver]
---
arch/powerpc/platforms/pseries/papr_scm.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
@@ -64,6 +65,10 @@ static int drc_pmem_bind(struct papr_scm_priv *p)}while(rc==H_BUSY);if(rc){+/* H_OVERLAP needs a separate error path */+if(rc==H_OVERLAP)+return-EBUSY;+dev_err(&p->pdev->dev,"bind err: %lld\n",rc);return-ENXIO;}
@@ -331,6 +336,14 @@ static int papr_scm_probe(struct platform_device *pdev)/* request the hypervisor to bind this region to somewhere in memory */rc=drc_pmem_bind(p);++/* If phyp reports drc memory still bound the force unbound and retry */+if(rc==-EBUSY){+dev_warn(&pdev->dev,"Retrying bind after unbinding\n");+drc_pmem_unbind(p);+rc=drc_pmem_bind(p);+}+if(rc)gotoerr;
On Tue, Jun 25, 2019 at 10:27 PM Vaibhav Jain [off-list ref] wrote:
quoted hunk
In some cases initial bind of scm memory for an lpar can fail if
previously it wasn't released using a scm-unbind hcall. This situation
can arise due to panic of the previous kernel or forced lpar
fadump. In such cases the H_SCM_BIND_MEM return a H_OVERLAP error.
To mitigate such cases the patch updates papr_scm_probe() to force a
call to drc_pmem_unbind() in case the initial bind of scm memory fails
with EBUSY error. In case scm-bind operation again fails after the
forced scm-unbind then we follow the existing error path. We also
update drc_pmem_bind() to handle the H_OVERLAP error returned by phyp
and indicate it as a EBUSY error back to the caller.
Suggested-by: "Oliver O'Halloran" <oohall@gmail.com>
Signed-off-by: Vaibhav Jain <redacted>
---
Change-log:
v2:
* Moved the retry code from drc_pmem_bind() to papr_scm_probe()
[Oliver]
* Changed the type of variable 'rc' in drc_pmem_bind() to
int64_t. [Oliver]
---
arch/powerpc/platforms/pseries/papr_scm.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
@@ -64,6 +65,10 @@ static int drc_pmem_bind(struct papr_scm_priv *p)}while(rc==H_BUSY);if(rc){+/* H_OVERLAP needs a separate error path */+if(rc==H_OVERLAP)+return-EBUSY;+dev_err(&p->pdev->dev,"bind err: %lld\n",rc);return-ENXIO;}
@@ -331,6 +336,14 @@ static int papr_scm_probe(struct platform_device *pdev)/* request the hypervisor to bind this region to somewhere in memory */rc=drc_pmem_bind(p);++/* If phyp reports drc memory still bound the force unbound and retry */
"the force" should be "then force"?
+ if (rc == -EBUSY) {
+ dev_warn(&pdev->dev, "Retrying bind after unbinding\n");
Looks good otherwise,
Reviewed-by: Oliver O'Halloran <oohall@gmail.com>