lkml.org 
[lkml]   [2019]   [Aug]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 5.2 37/76] powerpc/papr_scm: Force a scm-unbind if initial scm-bind fails
    Date
    From: Vaibhav Jain <vaibhav@linux.ibm.com>

    [ Upstream commit 3a855b7ac7d5021674aa3e1cc9d3bfd6b604e9c0 ]

    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 <vaibhav@linux.ibm.com>
    Reviewed-by: Oliver O'Halloran <oohall@gmail.com>
    Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
    Link: https://lore.kernel.org/r/20190629160610.23402-4-vaibhav@linux.ibm.com
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    arch/powerpc/platforms/pseries/papr_scm.c | 15 ++++++++++++++-
    1 file changed, 14 insertions(+), 1 deletion(-)

    diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c
    index 96c53b23e58f9..dad9825e40874 100644
    --- a/arch/powerpc/platforms/pseries/papr_scm.c
    +++ b/arch/powerpc/platforms/pseries/papr_scm.c
    @@ -42,8 +42,9 @@ struct papr_scm_priv {
    static int drc_pmem_bind(struct papr_scm_priv *p)
    {
    unsigned long ret[PLPAR_HCALL_BUFSIZE];
    - uint64_t rc, token;
    uint64_t saved = 0;
    + uint64_t token;
    + int64_t rc;

    /*
    * When the hypervisor cannot map all the requested memory in a single
    @@ -63,6 +64,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;
    }
    @@ -316,6 +321,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 says drc memory still bound then 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)
    goto err;

    --
    2.20.1
    \
     
     \ /
      Last update: 2019-08-02 15:22    [W:3.586 / U:0.012 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site