lkml.org 
[lkml]   [2020]   [Feb]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.14 088/237] scsi: ufs: Complete pending requests in host reset and restore path
    Date
    From: Can Guo <cang@codeaurora.org>

    [ Upstream commit 2df74b6985b51e77756e2e8faa16c45ca3ba53c5 ]

    In UFS host reset and restore path, before probe, we stop and start the
    host controller once. After host controller is stopped, the pending
    requests, if any, are cleared from the doorbell, but no completion IRQ
    would be raised due to the hba is stopped. These pending requests shall be
    completed along with the first NOP_OUT command (as it is the first command
    which can raise a transfer completion IRQ) sent during probe. Since the
    OCSs of these pending requests are not SUCCESS (because they are not yet
    literally finished), their UPIUs shall be dumped. When there are multiple
    pending requests, the UPIU dump can be overwhelming and may lead to
    stability issues because it is in atomic context. Therefore, before probe,
    complete these pending requests right after host controller is stopped and
    silence the UPIU dump from them.

    Link: https://lore.kernel.org/r/1574751214-8321-5-git-send-email-cang@qti.qualcomm.com
    Reviewed-by: Alim Akhtar <alim.akhtar@samsung.com>
    Reviewed-by: Bean Huo <beanhuo@micron.com>
    Tested-by: Bean Huo <beanhuo@micron.com>
    Signed-off-by: Can Guo <cang@codeaurora.org>
    Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/scsi/ufs/ufshcd.c | 24 ++++++++++--------------
    drivers/scsi/ufs/ufshcd.h | 2 ++
    2 files changed, 12 insertions(+), 14 deletions(-)

    diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
    index ce40de334f112..c350453246952 100644
    --- a/drivers/scsi/ufs/ufshcd.c
    +++ b/drivers/scsi/ufs/ufshcd.c
    @@ -4580,7 +4580,7 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
    break;
    } /* end of switch */

    - if (host_byte(result) != DID_OK)
    + if ((host_byte(result) != DID_OK) && !hba->silence_err_logs)
    ufshcd_print_trs(hba, 1 << lrbp->task_tag, true);
    return result;
    }
    @@ -5109,8 +5109,8 @@ static void ufshcd_err_handler(struct work_struct *work)

    /*
    * if host reset is required then skip clearing the pending
    - * transfers forcefully because they will automatically get
    - * cleared after link startup.
    + * transfers forcefully because they will get cleared during
    + * host reset and restore
    */
    if (needs_reset)
    goto skip_pending_xfer_clear;
    @@ -5749,9 +5749,15 @@ static int ufshcd_host_reset_and_restore(struct ufs_hba *hba)
    int err;
    unsigned long flags;

    - /* Reset the host controller */
    + /*
    + * Stop the host controller and complete the requests
    + * cleared by h/w
    + */
    spin_lock_irqsave(hba->host->host_lock, flags);
    ufshcd_hba_stop(hba, false);
    + hba->silence_err_logs = true;
    + ufshcd_complete_requests(hba);
    + hba->silence_err_logs = false;
    spin_unlock_irqrestore(hba->host->host_lock, flags);

    /* scale up clocks to max frequency before full reinitialization */
    @@ -5785,22 +5791,12 @@ out:
    static int ufshcd_reset_and_restore(struct ufs_hba *hba)
    {
    int err = 0;
    - unsigned long flags;
    int retries = MAX_HOST_RESET_RETRIES;

    do {
    err = ufshcd_host_reset_and_restore(hba);
    } while (err && --retries);

    - /*
    - * After reset the door-bell might be cleared, complete
    - * outstanding requests in s/w here.
    - */
    - spin_lock_irqsave(hba->host->host_lock, flags);
    - ufshcd_transfer_req_compl(hba);
    - ufshcd_tmc_handler(hba);
    - spin_unlock_irqrestore(hba->host->host_lock, flags);
    -
    return err;
    }

    diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
    index cdc8bd05f7dfc..4aac4d86f57b3 100644
    --- a/drivers/scsi/ufs/ufshcd.h
    +++ b/drivers/scsi/ufs/ufshcd.h
    @@ -485,6 +485,7 @@ struct ufs_stats {
    * @uic_error: UFS interconnect layer error status
    * @saved_err: sticky error mask
    * @saved_uic_err: sticky UIC error mask
    + * @silence_err_logs: flag to silence error logs
    * @dev_cmd: ufs device management command information
    * @last_dme_cmd_tstamp: time stamp of the last completed DME command
    * @auto_bkops_enabled: to track whether bkops is enabled in device
    @@ -621,6 +622,7 @@ struct ufs_hba {
    u32 saved_err;
    u32 saved_uic_err;
    struct ufs_stats ufs_stats;
    + bool silence_err_logs;

    /* Device management request data */
    struct ufs_dev_cmd dev_cmd;
    --
    2.20.1


    \
     
     \ /
      Last update: 2020-02-27 14:56    [W:2.233 / U:0.012 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site