From patchwork Thu May 13 05:55:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Can Guo X-Patchwork-Id: 12255171 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D416DC433B4 for ; Thu, 13 May 2021 05:55:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A289161206 for ; Thu, 13 May 2021 05:55:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231229AbhEMF4s (ORCPT ); Thu, 13 May 2021 01:56:48 -0400 Received: from labrats.qualcomm.com ([199.106.110.90]:2361 "EHLO labrats.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229935AbhEMF4r (ORCPT ); Thu, 13 May 2021 01:56:47 -0400 IronPort-SDR: oXL6WAk3Hr8JkojSEw0UcSvp1qieH02IoJuFmUbgmN5xj6h2KHnSouo7LyX2ZYRdo2PWmPMBFS Exb1N7CTfQ3FBKnag1W6HppRCRHIxNlTGE01o3ukVymsox3ziZLXD8AWO3Q8w74fU35wRCg8Im 8XbH6O4aXfcdxTSlE2MplBaKS8nkCa11t7ds9JTj0vKazClgL57RvFagAu2NLetmt5qD46bh35 d9LE3iOk1Ycgf9YlMta777BgwloT4w7XvklKKbjY6Z5I39ol8bOJA6nmtWWwLuDFBAFgyS+iHX 9Ik= X-IronPort-AV: E=Sophos;i="5.82,296,1613462400"; d="scan'208";a="47866513" Received: from unknown (HELO ironmsg03-sd.qualcomm.com) ([10.53.140.143]) by labrats.qualcomm.com with ESMTP; 12 May 2021 22:55:39 -0700 X-QCInternal: smtphost Received: from stor-presley.qualcomm.com ([192.168.140.85]) by ironmsg03-sd.qualcomm.com with ESMTP; 12 May 2021 22:55:37 -0700 Received: by stor-presley.qualcomm.com (Postfix, from userid 359480) id 45E2E21A85; Wed, 12 May 2021 22:55:38 -0700 (PDT) From: Can Guo To: asutoshd@codeaurora.org, nguyenb@codeaurora.org, hongwus@codeaurora.org, ziqichen@codeaurora.org, linux-scsi@vger.kernel.org, kernel-team@android.com, cang@codeaurora.org Cc: Alim Akhtar , Avri Altman , "James E.J. Bottomley" , "Martin K. Petersen" , Stanley Chu , Bean Huo , Jaegeuk Kim , Adrian Hunter , Kiwoong Kim , Satya Tangirala , linux-kernel@vger.kernel.org (open list) Subject: [PATCH v1 1/6] scsi: ufs: Differentiate status between hba pm ops and wl pm ops Date: Wed, 12 May 2021 22:55:13 -0700 Message-Id: <1620885319-15151-2-git-send-email-cang@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1620885319-15151-1-git-send-email-cang@codeaurora.org> References: <1620885319-15151-1-git-send-email-cang@codeaurora.org> Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Put pm_op_in_progress and is_sys_suspend flags back to ufshcd hba pm ops, add two new flags, namely wl_pm_op_in_progress and is_wl_sys_suspended, to track the UFS device W-LU pm ops. This helps us differentiate the status of hba and wl pm ops when we need to do troubleshooting. Signed-off-by: Can Guo --- drivers/scsi/ufs/ufshcd.c | 42 ++++++++++++++++++++++++++++-------------- drivers/scsi/ufs/ufshcd.h | 4 +++- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index ab707a2..c69602b 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -543,7 +543,9 @@ static void ufshcd_print_host_state(struct ufs_hba *hba) hba->saved_err, hba->saved_uic_err); dev_err(hba->dev, "Device power mode=%d, UIC link state=%d\n", hba->curr_dev_pwr_mode, hba->uic_link_state); - dev_err(hba->dev, "PM in progress=%d, sys. suspended=%d\n", + dev_err(hba->dev, "wl_pm_op_in_progress=%d, is_wl_sys_suspended=%d\n", + hba->wl_pm_op_in_progress, hba->is_wl_sys_suspended); + dev_err(hba->dev, "pm_op_in_progress=%d, is_sys_suspended=%d\n", hba->pm_op_in_progress, hba->is_sys_suspended); dev_err(hba->dev, "Auto BKOPS=%d, Host self-block=%d\n", hba->auto_bkops_enabled, hba->host->host_self_blocked); @@ -1991,7 +1993,7 @@ static void ufshcd_clk_scaling_start_busy(struct ufs_hba *hba) if (!hba->clk_scaling.active_reqs++) queue_resume_work = true; - if (!hba->clk_scaling.is_enabled || hba->pm_op_in_progress) + if (!hba->clk_scaling.is_enabled || hba->wl_pm_op_in_progress) return; if (queue_resume_work) @@ -2640,7 +2642,7 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) lrbp = &hba->lrb[tag]; if (unlikely(lrbp->in_use)) { - if (hba->pm_op_in_progress) + if (hba->wl_pm_op_in_progress) set_host_byte(cmd, DID_BAD_TARGET); else err = SCSI_MLQUEUE_HOST_BUSY; @@ -2687,7 +2689,7 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) * err handler blocked for too long. So, just fail the scsi cmd * sent from PM ops, err handler can recover PM error anyways. */ - if (hba->pm_op_in_progress) { + if (hba->wl_pm_op_in_progress) { hba->force_reset = true; set_host_byte(cmd, DID_BAD_TARGET); goto out_compl_cmd; @@ -5036,7 +5038,7 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) * solution could be to abort the system suspend if * UFS device needs urgent BKOPs. */ - if (!hba->pm_op_in_progress && + if (!hba->wl_pm_op_in_progress && !ufshcd_eh_in_progress(hba) && ufshcd_is_exception_event(lrbp->ucd_rsp_ptr)) /* Flushed in suspend */ @@ -5799,7 +5801,7 @@ static void ufshcd_err_handling_prepare(struct ufs_hba *hba) { ufshcd_rpm_get_sync(hba); if (pm_runtime_status_suspended(&hba->sdev_ufs_device->sdev_gendev) || - hba->is_sys_suspended) { + hba->is_wl_sys_suspended) { enum ufs_pm_op pm_op; /* @@ -5816,7 +5818,7 @@ static void ufshcd_err_handling_prepare(struct ufs_hba *hba) if (!ufshcd_is_clkgating_allowed(hba)) ufshcd_setup_clocks(hba, true); ufshcd_release(hba); - pm_op = hba->is_sys_suspended ? UFS_SYSTEM_PM : UFS_RUNTIME_PM; + pm_op = hba->is_wl_sys_suspended ? UFS_SYSTEM_PM : UFS_RUNTIME_PM; ufshcd_vops_resume(hba, pm_op); } else { ufshcd_hold(hba, false); @@ -5859,7 +5861,7 @@ static void ufshcd_recover_pm_error(struct ufs_hba *hba) struct request_queue *q; int ret; - hba->is_sys_suspended = false; + hba->is_wl_sys_suspended = false; /* * Set RPM status of wlun device to RPM_ACTIVE, * this also clears its runtime error. @@ -8709,7 +8711,7 @@ static int __ufshcd_wl_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) enum ufs_dev_pwr_mode req_dev_pwr_mode; enum uic_link_state req_link_state; - hba->pm_op_in_progress = true; + hba->wl_pm_op_in_progress = true; if (!ufshcd_is_shutdown_pm(pm_op)) { pm_lvl = ufshcd_is_runtime_pm(pm_op) ? hba->rpm_lvl : hba->spm_lvl; @@ -8844,7 +8846,7 @@ static int __ufshcd_wl_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) hba->clk_gating.is_suspended = false; ufshcd_release(hba); } - hba->pm_op_in_progress = false; + hba->wl_pm_op_in_progress = false; return ret; } @@ -8853,7 +8855,7 @@ static int __ufshcd_wl_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) int ret; enum uic_link_state old_link_state = hba->uic_link_state; - hba->pm_op_in_progress = true; + hba->wl_pm_op_in_progress = true; /* * Call vendor specific resume callback. As these callbacks may access @@ -8931,7 +8933,7 @@ static int __ufshcd_wl_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) ufshcd_update_evt_hist(hba, UFS_EVT_WL_RES_ERR, (u32)ret); hba->clk_gating.is_suspended = false; ufshcd_release(hba); - hba->pm_op_in_progress = false; + hba->wl_pm_op_in_progress = false; return ret; } @@ -8997,7 +8999,7 @@ static int ufshcd_wl_suspend(struct device *dev) out: if (!ret) - hba->is_sys_suspended = true; + hba->is_wl_sys_suspended = true; trace_ufshcd_wl_suspend(dev_name(dev), ret, ktime_to_us(ktime_sub(ktime_get(), start)), hba->curr_dev_pwr_mode, hba->uic_link_state); @@ -9025,7 +9027,7 @@ static int ufshcd_wl_resume(struct device *dev) ktime_to_us(ktime_sub(ktime_get(), start)), hba->curr_dev_pwr_mode, hba->uic_link_state); if (!ret) - hba->is_sys_suspended = false; + hba->is_wl_sys_suspended = false; up(&hba->host_sem); return ret; } @@ -9067,6 +9069,8 @@ static int ufshcd_suspend(struct ufs_hba *hba) if (!hba->is_powered) return 0; + + hba->pm_op_in_progress = true; /* * Disable the host irq as host controller as there won't be any * host controller transaction expected till resume. @@ -9086,6 +9090,7 @@ static int ufshcd_suspend(struct ufs_hba *hba) ufshcd_vreg_set_lpm(hba); /* Put the host controller in low power mode if possible */ ufshcd_hba_vreg_set_lpm(hba); + hba->pm_op_in_progress = false; return ret; } @@ -9106,6 +9111,7 @@ static int ufshcd_resume(struct ufs_hba *hba) if (!hba->is_powered) return 0; + hba->pm_op_in_progress = true; ufshcd_hba_vreg_set_hpm(hba); ret = ufshcd_vreg_set_hpm(hba); if (ret) @@ -9125,6 +9131,7 @@ static int ufshcd_resume(struct ufs_hba *hba) out: if (ret) ufshcd_update_evt_hist(hba, UFS_EVT_RESUME_ERR, (u32)ret); + hba->pm_op_in_progress = false; return ret; } @@ -9150,6 +9157,10 @@ int ufshcd_system_suspend(struct ufs_hba *hba) trace_ufshcd_system_suspend(dev_name(hba->dev), ret, ktime_to_us(ktime_sub(ktime_get(), start)), hba->curr_dev_pwr_mode, hba->uic_link_state); + + if (!ret) + hba->is_sys_suspended = true; + return ret; } EXPORT_SYMBOL(ufshcd_system_suspend); @@ -9176,6 +9187,9 @@ int ufshcd_system_resume(struct ufs_hba *hba) ktime_to_us(ktime_sub(ktime_get(), start)), hba->curr_dev_pwr_mode, hba->uic_link_state); + if (!ret) + hba->is_sys_suspended = false; + return ret; } EXPORT_SYMBOL(ufshcd_system_resume); diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index b8b4fe2..201dc49 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -739,7 +739,8 @@ struct ufs_hba { enum ufs_pm_level spm_lvl; struct device_attribute rpm_lvl_attr; struct device_attribute spm_lvl_attr; - int pm_op_in_progress; + bool pm_op_in_progress; + bool wl_pm_op_in_progress; /* Auto-Hibernate Idle Timer register value */ u32 ahit; @@ -826,6 +827,7 @@ struct ufs_hba { struct devfreq *devfreq; struct ufs_clk_scaling clk_scaling; bool is_sys_suspended; + bool is_wl_sys_suspended; enum bkops_status urgent_bkops_lvl; bool is_urgent_bkops_lvl_checked; From patchwork Thu May 13 05:55:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Can Guo X-Patchwork-Id: 12255175 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 703C0C433B4 for ; Thu, 13 May 2021 05:55:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3DAB161422 for ; Thu, 13 May 2021 05:55:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231265AbhEMF5B (ORCPT ); Thu, 13 May 2021 01:57:01 -0400 Received: from labrats.qualcomm.com ([199.106.110.90]:35000 "EHLO labrats.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231250AbhEMF5A (ORCPT ); Thu, 13 May 2021 01:57:00 -0400 IronPort-SDR: 5sPPrIy/BC4+TLYPPFESN2mZiu4m77vCObLWUq2yfYNLnr9YlfBcZXf9h6fxQOI7Hf6xJsoep+ tC8Aho9d/Lvywzv96T0SenodRdz+aOYfTLPXe/UkaA+1aYYRL53siRIr402whGqMvrKgVwfEa/ p7LqUoau2+TJ/Ce0jWMU6Eck7uVw3vVNO2vWyyPJ/7s0DctOgYIN/OGbUYwa0xI1vJNFx8dXqp 8dQNse9GhvT4UxluQ9EtS/ya/MHuniiQHt60bZW8rU08ekzMJUQpABJ/K34rA7VH/2gowiEQjj gpk= X-IronPort-AV: E=Sophos;i="5.82,296,1613462400"; d="scan'208";a="29767596" Received: from unknown (HELO ironmsg05-sd.qualcomm.com) ([10.53.140.145]) by labrats.qualcomm.com with ESMTP; 12 May 2021 22:55:50 -0700 X-QCInternal: smtphost Received: from wsp769891wss.qualcomm.com (HELO stor-presley.qualcomm.com) ([192.168.140.85]) by ironmsg05-sd.qualcomm.com with ESMTP; 12 May 2021 22:55:50 -0700 Received: by stor-presley.qualcomm.com (Postfix, from userid 359480) id 3432921A85; Wed, 12 May 2021 22:55:50 -0700 (PDT) From: Can Guo To: asutoshd@codeaurora.org, nguyenb@codeaurora.org, hongwus@codeaurora.org, ziqichen@codeaurora.org, linux-scsi@vger.kernel.org, kernel-team@android.com, cang@codeaurora.org Cc: Alim Akhtar , Avri Altman , "James E.J. Bottomley" , "Martin K. Petersen" , Stanley Chu , Bean Huo , Jaegeuk Kim , linux-kernel@vger.kernel.org (open list) Subject: [PATCH v1 2/6] scsi: ufs: Update the return value of supplier pm ops Date: Wed, 12 May 2021 22:55:15 -0700 Message-Id: <1620885319-15151-4-git-send-email-cang@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1620885319-15151-1-git-send-email-cang@codeaurora.org> References: <1620885319-15151-1-git-send-email-cang@codeaurora.org> Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org rpm_get_suppliers() is returning an error only if the error is negative. However, ufshcd_wl_resume() may return a positive error code, e.g., when hibern8 or SSU cmd fails. Make the positive return value a negative error code so that consumers are aware of any resume failure from their supplier. Make the same change to ufshcd_wl_suspend() just to keep symmetry. Signed-off-by: Can Guo --- drivers/scsi/ufs/ufshcd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index c69602b..41205d1 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -8847,7 +8847,7 @@ static int __ufshcd_wl_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) ufshcd_release(hba); } hba->wl_pm_op_in_progress = false; - return ret; + return ret <= 0 ? ret : -EINVAL; } static int __ufshcd_wl_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) @@ -8934,7 +8934,7 @@ static int __ufshcd_wl_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) hba->clk_gating.is_suspended = false; ufshcd_release(hba); hba->wl_pm_op_in_progress = false; - return ret; + return ret <= 0 ? ret : -EINVAL; } static int ufshcd_wl_runtime_suspend(struct device *dev) From patchwork Thu May 13 05:55:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Can Guo X-Patchwork-Id: 12255177 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A35AFC43460 for ; Thu, 13 May 2021 05:55:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6D66F61433 for ; Thu, 13 May 2021 05:55:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231272AbhEMF5G (ORCPT ); Thu, 13 May 2021 01:57:06 -0400 Received: from labrats.qualcomm.com ([199.106.110.90]:35000 "EHLO labrats.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231229AbhEMF5E (ORCPT ); Thu, 13 May 2021 01:57:04 -0400 IronPort-SDR: 0qucRsQ9JMu/8N07KJUtOmT4vuBkOjGUyH61vOJz2/9Xzb4elAVOpfQJ+cIMNERT4EEEG7vsTy oArcgRFwlew73PZc5b0KcvUJlu/iCwC857gWQibqhdQgYOS8XSJKRmDbcWw5oLhn/hRnxQ3qUt n9jdTjdYts9Bh9bMpaq29eK+Q+WRRz0+U/lC9QKj1RzxAlQ0dIwzLLJqTtqxna9jeY2k8hxpXM qp6Y42Zcy1/V/8OVmyQVlH2FKGCyGqU6NS2l//ZY4Dd3HwGXSl1adukGZvNI4YcRJoxLT3CR2i uHM= X-IronPort-AV: E=Sophos;i="5.82,296,1613462400"; d="scan'208";a="29767597" Received: from unknown (HELO ironmsg05-sd.qualcomm.com) ([10.53.140.145]) by labrats.qualcomm.com with ESMTP; 12 May 2021 22:55:55 -0700 X-QCInternal: smtphost Received: from wsp769891wss.qualcomm.com (HELO stor-presley.qualcomm.com) ([192.168.140.85]) by ironmsg05-sd.qualcomm.com with ESMTP; 12 May 2021 22:55:54 -0700 Received: by stor-presley.qualcomm.com (Postfix, from userid 359480) id BFB1221A85; Wed, 12 May 2021 22:55:54 -0700 (PDT) From: Can Guo To: asutoshd@codeaurora.org, nguyenb@codeaurora.org, hongwus@codeaurora.org, ziqichen@codeaurora.org, linux-scsi@vger.kernel.org, kernel-team@android.com, cang@codeaurora.org Cc: Alim Akhtar , Avri Altman , "James E.J. Bottomley" , "Martin K. Petersen" , Stanley Chu , Bean Huo , Jaegeuk Kim , linux-kernel@vger.kernel.org (open list) Subject: [PATCH v1 3/6] scsi: ufs: Simplify error handling preparation Date: Wed, 12 May 2021 22:55:16 -0700 Message-Id: <1620885319-15151-5-git-send-email-cang@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1620885319-15151-1-git-send-email-cang@codeaurora.org> References: <1620885319-15151-1-git-send-email-cang@codeaurora.org> Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Commit cb7e6f05fce67c965194ac04467e1ba7bc70b069 ("scsi: ufs: core: Enable power management for wlun") moves UFS operations out of ufshcd_resume(), so in error handling preparation, if ufshcd hba has failed to resume, there is no point to re-enable IRQ/clk/pwr. Signed-off-by: Can Guo --- drivers/scsi/ufs/ufshcd.c | 61 ++++++++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 24 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 41205d1..0edc69f 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -2680,8 +2680,8 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) break; case UFSHCD_STATE_EH_SCHEDULED_FATAL: /* - * pm_runtime_get_sync() is used at error handling preparation - * stage. If a scsi cmd, e.g. the SSU cmd, is sent from hba's + * ufshcd_rpm_get_sync() is used at error handling preparation + * stage. If a scsi cmd, e.g., the SSU cmd, is sent from the * PM ops, it can never be finished if we let SCSI layer keep * retrying it, which gets err handler stuck forever. Neither * can we let the scsi cmd pass through, because UFS is in bad @@ -5797,28 +5797,33 @@ static void ufshcd_clk_scaling_suspend(struct ufs_hba *hba, bool suspend) } } -static void ufshcd_err_handling_prepare(struct ufs_hba *hba) +static int ufshcd_err_handling_prepare(struct ufs_hba *hba) { + unsigned long flags; + + /* + * Exclusively call pm_runtime_get_sync(hba->dev) once, in case + * following ufshcd_rpm_get_sync() fails. + */ + pm_runtime_get_sync(hba->dev); + /* + * IRQ, clocks and powers are supposed to be ON by now, unless error + * happened to ufshcd_resume(), which is out of our control. + */ + if (pm_runtime_suspended(hba->dev) || hba->is_sys_suspended) { + spin_lock_irqsave(hba->host->host_lock, flags); + hba->ufshcd_state = UFSHCD_STATE_ERROR; + spin_unlock_irqrestore(hba->host->host_lock, flags); + pm_runtime_put(hba->dev); + return -EINVAL; + } + ufshcd_rpm_get_sync(hba); - if (pm_runtime_status_suspended(&hba->sdev_ufs_device->sdev_gendev) || + if (pm_runtime_suspended(&hba->sdev_ufs_device->sdev_gendev) || hba->is_wl_sys_suspended) { - enum ufs_pm_op pm_op; + enum ufs_pm_op pm_op = hba->is_wl_sys_suspended ? + UFS_SYSTEM_PM : UFS_RUNTIME_PM; - /* - * Don't assume anything of resume, if - * resume fails, irq and clocks can be OFF, and powers - * can be OFF or in LPM. - */ - ufshcd_setup_hba_vreg(hba, true); - ufshcd_enable_irq(hba); - ufshcd_setup_vreg(hba, true); - ufshcd_config_vreg_hpm(hba, hba->vreg_info.vccq); - ufshcd_config_vreg_hpm(hba, hba->vreg_info.vccq2); - ufshcd_hold(hba, false); - if (!ufshcd_is_clkgating_allowed(hba)) - ufshcd_setup_clocks(hba, true); - ufshcd_release(hba); - pm_op = hba->is_wl_sys_suspended ? UFS_SYSTEM_PM : UFS_RUNTIME_PM; ufshcd_vops_resume(hba, pm_op); } else { ufshcd_hold(hba, false); @@ -5832,6 +5837,7 @@ static void ufshcd_err_handling_prepare(struct ufs_hba *hba) down_write(&hba->clk_scaling_lock); up_write(&hba->clk_scaling_lock); cancel_work_sync(&hba->eeh_work); + return 0; } static void ufshcd_err_handling_unprepare(struct ufs_hba *hba) @@ -5842,6 +5848,7 @@ static void ufshcd_err_handling_unprepare(struct ufs_hba *hba) ufshcd_clk_scaling_suspend(hba, false); ufshcd_clear_ua_wluns(hba); ufshcd_rpm_put(hba); + pm_runtime_put(hba->dev); } static inline bool ufshcd_err_handling_should_stop(struct ufs_hba *hba) @@ -5933,10 +5940,15 @@ static void ufshcd_err_handler(struct work_struct *work) up(&hba->host_sem); return; } - ufshcd_set_eh_in_progress(hba); spin_unlock_irqrestore(hba->host->host_lock, flags); - ufshcd_err_handling_prepare(hba); + if (ufshcd_err_handling_prepare(hba)) { + dev_err(hba->dev, "%s: error handling preparation failed\n", + __func__); + up(&hba->host_sem); + return; + } spin_lock_irqsave(hba->host->host_lock, flags); + ufshcd_set_eh_in_progress(hba); if (hba->ufshcd_state != UFSHCD_STATE_ERROR) hba->ufshcd_state = UFSHCD_STATE_RESET; @@ -8922,6 +8934,9 @@ static int __ufshcd_wl_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) /* Enable Auto-Hibernate if configured */ ufshcd_auto_hibern8_enable(hba); + + hba->clk_gating.is_suspended = false; + ufshcd_release(hba); goto out; set_old_link_state: @@ -8931,8 +8946,6 @@ static int __ufshcd_wl_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) out: if (ret) ufshcd_update_evt_hist(hba, UFS_EVT_WL_RES_ERR, (u32)ret); - hba->clk_gating.is_suspended = false; - ufshcd_release(hba); hba->wl_pm_op_in_progress = false; return ret <= 0 ? ret : -EINVAL; } From patchwork Thu May 13 05:55:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Can Guo X-Patchwork-Id: 12255179 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B5AB9C433ED for ; Thu, 13 May 2021 05:56:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 83EAC61422 for ; Thu, 13 May 2021 05:56:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231302AbhEMF5L (ORCPT ); Thu, 13 May 2021 01:57:11 -0400 Received: from labrats.qualcomm.com ([199.106.110.90]:35000 "EHLO labrats.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231229AbhEMF5J (ORCPT ); Thu, 13 May 2021 01:57:09 -0400 IronPort-SDR: 0Mx5liXdtgTZgt1WpgO3cnI9nTNgeuhaHXL18FtucScz4zFIEXgo4OOic00NZyP2gNihKhn2sM PqKhvoZd7WpW1ovaF2+6AMCcylEJDi5nDxmvOEcHpJHSzWL97Gt1g4H8DX7dkrDyKinX+CtFDN PuH2CAoGAlmUQwekPUAjqiDNh8GGUro6v24EEf+rs0ACPwC8yegI8GwNh5XZE+sZxOtKjuVqPD t1wMSwlc256c/tQYn69/gmJmuo3q6zv0w6WPobTTn+pY/NXt74SYjX88jF4gMaYPGq7YuQ/BLK 1kc= X-IronPort-AV: E=Sophos;i="5.82,296,1613462400"; d="scan'208";a="29767598" Received: from unknown (HELO ironmsg05-sd.qualcomm.com) ([10.53.140.145]) by labrats.qualcomm.com with ESMTP; 12 May 2021 22:55:59 -0700 X-QCInternal: smtphost Received: from wsp769891wss.qualcomm.com (HELO stor-presley.qualcomm.com) ([192.168.140.85]) by ironmsg05-sd.qualcomm.com with ESMTP; 12 May 2021 22:55:59 -0700 Received: by stor-presley.qualcomm.com (Postfix, from userid 359480) id 8EB6E21A85; Wed, 12 May 2021 22:55:59 -0700 (PDT) From: Can Guo To: asutoshd@codeaurora.org, nguyenb@codeaurora.org, hongwus@codeaurora.org, ziqichen@codeaurora.org, linux-scsi@vger.kernel.org, kernel-team@android.com, cang@codeaurora.org Cc: Alim Akhtar , Avri Altman , "James E.J. Bottomley" , "Martin K. Petersen" , Stanley Chu , Bean Huo , Jaegeuk Kim , linux-kernel@vger.kernel.org (open list) Subject: [PATCH v1 4/6] scsi: ufs: Update ufshcd_recover_pm_error() Date: Wed, 12 May 2021 22:55:17 -0700 Message-Id: <1620885319-15151-6-git-send-email-cang@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1620885319-15151-1-git-send-email-cang@codeaurora.org> References: <1620885319-15151-1-git-send-email-cang@codeaurora.org> Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Commit cb7e6f05fce67c965194ac04467e1ba7bc70b069 ("scsi: ufs: core: Enable power management for wlun") makes UFS device W-LU scsi device the supplier and the others as consumers. If the supplier's runtime pm ops fails or has failed, not only supplier has the error saved to dev->power.runtime_error, the error may (most likely) be saved by one or more consumers, see also rpm_get_suppliers(). Update ufshcd_recover_pm_error() accordingly to clear the runtime_error of the supplier and its consumers to get runtime PM back to work on them. Signed-off-by: Can Guo --- drivers/scsi/ufs/ufshcd.c | 50 ++++++++++++++++++++--------------------------- 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 0edc69f..631c5f8 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -242,6 +242,7 @@ static irqreturn_t ufshcd_intr(int irq, void *__hba); static int ufshcd_change_power_mode(struct ufs_hba *hba, struct ufs_pa_layer_attr *pwr_mode); static void ufshcd_schedule_eh_work(struct ufs_hba *hba); +static void ufshcd_recover_pm_error(struct ufs_hba *hba); static int ufshcd_setup_hba_vreg(struct ufs_hba *hba, bool on); static int ufshcd_setup_vreg(struct ufs_hba *hba, bool on); static inline int ufshcd_config_vreg_hpm(struct ufs_hba *hba, @@ -5840,12 +5841,14 @@ static int ufshcd_err_handling_prepare(struct ufs_hba *hba) return 0; } -static void ufshcd_err_handling_unprepare(struct ufs_hba *hba) +static void ufshcd_err_handling_unprepare(struct ufs_hba *hba, int reset_err) { ufshcd_scsi_unblock_requests(hba); ufshcd_release(hba); if (ufshcd_is_clkscaling_supported(hba)) ufshcd_clk_scaling_suspend(hba, false); + if (!reset_err) + ufshcd_recover_pm_error(hba); ufshcd_clear_ua_wluns(hba); ufshcd_rpm_put(hba); pm_runtime_put(hba->dev); @@ -5864,34 +5867,26 @@ static inline bool ufshcd_err_handling_should_stop(struct ufs_hba *hba) static void ufshcd_recover_pm_error(struct ufs_hba *hba) { struct Scsi_Host *shost = hba->host; - struct scsi_device *sdev; - struct request_queue *q; + struct scsi_device *sdev = hba->sdev_ufs_device; + struct scsi_target *starget = sdev->sdev_target; int ret; hba->is_wl_sys_suspended = false; - /* - * Set RPM status of wlun device to RPM_ACTIVE, - * this also clears its runtime error. - */ - ret = pm_runtime_set_active(&hba->sdev_ufs_device->sdev_gendev); - /* hba device might have a runtime error otherwise */ - if (ret) - ret = pm_runtime_set_active(hba->dev); - /* - * If wlun device had runtime error, we also need to resume those - * consumer scsi devices in case any of them has failed to be - * resumed due to supplier runtime resume failure. This is to unblock - * blk_queue_enter in case there are bios waiting inside it. - */ - if (!ret) { - shost_for_each_device(sdev, shost) { - q = sdev->request_queue; - if (q->dev && (q->rpm_status == RPM_SUSPENDED || - q->rpm_status == RPM_SUSPENDING)) - pm_request_resume(q->dev); - } + /* Resume parent/target to clear path for pm_runtime_set_active() */ + pm_runtime_get_sync(&starget->dev); + shost_for_each_device(sdev, shost) { + struct device *dev = &sdev->sdev_gendev; + + pm_runtime_get_sync(dev); + /* Clear saved dev->power.runtime_error */ + ret = pm_runtime_set_active(dev); + if (!ret) + /* runtime_error cleared, kick blk_queue_enter() */ + blk_set_runtime_active(sdev->request_queue); + pm_runtime_put(dev); } + pm_runtime_put(&starget->dev); } #else static inline void ufshcd_recover_pm_error(struct ufs_hba *hba) @@ -5925,7 +5920,7 @@ static void ufshcd_err_handler(struct work_struct *work) unsigned long flags; bool err_xfer = false; bool err_tm = false; - int err = 0, pmc_err; + int err = -1, pmc_err; int tag; bool needs_reset = false, needs_restore = false; @@ -6094,8 +6089,6 @@ static void ufshcd_err_handler(struct work_struct *work) if (err) dev_err(hba->dev, "%s: reset and restore failed with err %d\n", __func__, err); - else - ufshcd_recover_pm_error(hba); spin_lock_irqsave(hba->host->host_lock, flags); } @@ -6109,7 +6102,7 @@ static void ufshcd_err_handler(struct work_struct *work) } ufshcd_clear_eh_in_progress(hba); spin_unlock_irqrestore(hba->host->host_lock, flags); - ufshcd_err_handling_unprepare(hba); + ufshcd_err_handling_unprepare(hba, err); up(&hba->host_sem); } @@ -6983,7 +6976,6 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) hba->force_reset = true; ufshcd_schedule_eh_work(hba); } - spin_unlock_irqrestore(host->host_lock, flags); goto out; } From patchwork Thu May 13 05:55:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Can Guo X-Patchwork-Id: 12255181 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 29F8CC433ED for ; Thu, 13 May 2021 05:56:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id ECD4F61422 for ; Thu, 13 May 2021 05:56:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231229AbhEMF50 (ORCPT ); Thu, 13 May 2021 01:57:26 -0400 Received: from labrats.qualcomm.com ([199.106.110.90]:1857 "EHLO labrats.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231300AbhEMF5P (ORCPT ); Thu, 13 May 2021 01:57:15 -0400 IronPort-SDR: qGa9atKjyh3b9cwt1JCzVEqal8nauOC4iq9VUNBptPpTf61wXm+kHSN9wfyJg2YETEgl8quRCl p6tLT1pNaddJonuBHL1Ad3SWCSQ71Z7VzqCg30CSQV32Rdbsd7fbXuIYvuAn0vgTtO+HXZNxoO j/uKPM3RgmxmZLCgV8j8C5E/bRdwle20Jcbcr64lXWqJ/HkLK9K8N4qzbBLstQMm54TbPXaN93 eFS1jKGclkzVhi/jB2QMx0qSBb8rrxEMdtVoVmUsu64JJ7xVNTLra6+eFwNK49cNWtVZgYpJzh PjI= X-IronPort-AV: E=Sophos;i="5.82,296,1613462400"; d="scan'208";a="47866514" Received: from unknown (HELO ironmsg04-sd.qualcomm.com) ([10.53.140.144]) by labrats.qualcomm.com with ESMTP; 12 May 2021 22:56:05 -0700 X-QCInternal: smtphost Received: from wsp769891wss.qualcomm.com (HELO stor-presley.qualcomm.com) ([192.168.140.85]) by ironmsg04-sd.qualcomm.com with ESMTP; 12 May 2021 22:56:04 -0700 Received: by stor-presley.qualcomm.com (Postfix, from userid 359480) id 1B6CE21A85; Wed, 12 May 2021 22:56:04 -0700 (PDT) From: Can Guo To: asutoshd@codeaurora.org, nguyenb@codeaurora.org, hongwus@codeaurora.org, ziqichen@codeaurora.org, linux-scsi@vger.kernel.org, kernel-team@android.com, cang@codeaurora.org Cc: Alim Akhtar , Avri Altman , "James E.J. Bottomley" , "Martin K. Petersen" , Stanley Chu , Bean Huo , Jaegeuk Kim , linux-kernel@vger.kernel.org (open list) Subject: [PATCH v1 5/6] scsi: ufs: Let host_sem cover the entire system suspend/resume Date: Wed, 12 May 2021 22:55:18 -0700 Message-Id: <1620885319-15151-7-git-send-email-cang@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1620885319-15151-1-git-send-email-cang@codeaurora.org> References: <1620885319-15151-1-git-send-email-cang@codeaurora.org> Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org UFS error handling now is doing more than just re-probing, but also sending scsi cmds, e.g., for clearing UACs, and recovering runtime PM error, which may change runtime status of scsi devices. To protect system suspend/resume from being disturbed by error handling, move the host_sem from wl pm ops to ufshcd_suspend_prepare() and ufshcd_resume_complete(). Signed-off-by: Can Guo --- drivers/scsi/ufs/ufshcd.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 631c5f8..a6313cf40 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -8991,16 +8991,13 @@ static int ufshcd_wl_suspend(struct device *dev) ktime_t start = ktime_get(); hba = shost_priv(sdev->host); - down(&hba->host_sem); if (pm_runtime_suspended(dev)) goto out; ret = __ufshcd_wl_suspend(hba, UFS_SYSTEM_PM); - if (ret) { + if (ret) dev_err(&sdev->sdev_gendev, "%s failed: %d\n", __func__, ret); - up(&hba->host_sem); - } out: if (!ret) @@ -9033,7 +9030,6 @@ static int ufshcd_wl_resume(struct device *dev) hba->curr_dev_pwr_mode, hba->uic_link_state); if (!ret) hba->is_wl_sys_suspended = false; - up(&hba->host_sem); return ret; } #endif @@ -9600,6 +9596,7 @@ void ufshcd_resume_complete(struct device *dev) ufshcd_rpmb_rpm_put(hba); hba->rpmb_complete_put = false; } + up(&hba->host_sem); } EXPORT_SYMBOL_GPL(ufshcd_resume_complete); @@ -9626,6 +9623,7 @@ int ufshcd_suspend_prepare(struct device *dev) ufshcd_rpmb_rpm_get_sync(hba); hba->rpmb_complete_put = true; } + down(&hba->host_sem); return 0; } EXPORT_SYMBOL_GPL(ufshcd_suspend_prepare); From patchwork Thu May 13 05:55:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Can Guo X-Patchwork-Id: 12255183 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 09574C433ED for ; Thu, 13 May 2021 05:56:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C5DBF61206 for ; Thu, 13 May 2021 05:56:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231296AbhEMF5a (ORCPT ); Thu, 13 May 2021 01:57:30 -0400 Received: from labrats.qualcomm.com ([199.106.110.90]:2036 "EHLO labrats.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231314AbhEMF5U (ORCPT ); Thu, 13 May 2021 01:57:20 -0400 IronPort-SDR: vYRvV5bYodqEndZ0KnOncADjjEaqKW8MZVVQHICXZm2bporKLx9zafZM5qgc7xVsotN5n8GGce AR568biYIE8SX43rC4nzRcNKmV7w44soGZz/+yj+oLv9AVlEAyH38k/sM2rNqvUdtgZGckuHj+ ZMxCra7TN1oz3aJ/RG8AG5xD04jcAOlh+K3gzsz1iaj7ITQcWeo9iuVYSgPyn75GvzTNERSTDM 85fPbkUD6ZoAQ8LCKFK8wXbZAtzHVnsMtoKJfQU/rqNJeHNcH6UacO9rtEx0wUJ+lHRUTwADYU xrs= X-IronPort-AV: E=Sophos;i="5.82,296,1613462400"; d="scan'208";a="29767599" Received: from unknown (HELO ironmsg01-sd.qualcomm.com) ([10.53.140.141]) by labrats.qualcomm.com with ESMTP; 12 May 2021 22:56:08 -0700 X-QCInternal: smtphost Received: from stor-presley.qualcomm.com ([192.168.140.85]) by ironmsg01-sd.qualcomm.com with ESMTP; 12 May 2021 22:56:08 -0700 Received: by stor-presley.qualcomm.com (Postfix, from userid 359480) id 3E7C321A85; Wed, 12 May 2021 22:56:08 -0700 (PDT) From: Can Guo To: asutoshd@codeaurora.org, nguyenb@codeaurora.org, hongwus@codeaurora.org, ziqichen@codeaurora.org, linux-scsi@vger.kernel.org, kernel-team@android.com, cang@codeaurora.org Cc: Alim Akhtar , Avri Altman , "James E.J. Bottomley" , "Martin K. Petersen" , Stanley Chu , Bean Huo , Jaegeuk Kim , linux-kernel@vger.kernel.org (open list) Subject: [PATCH v1 6/6] scsi: ufs: Update the fast abort path in ufshcd_abort() for PM requests Date: Wed, 12 May 2021 22:55:19 -0700 Message-Id: <1620885319-15151-8-git-send-email-cang@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1620885319-15151-1-git-send-email-cang@codeaurora.org> References: <1620885319-15151-1-git-send-email-cang@codeaurora.org> Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org If PM requests fail during runtime suspend/resume, RPM framework saves the error to dev->power.runtime_error. Before the runtime_error gets cleared, runtime PM on this specific device won't work again, leaving the device in either suspended or active state permanently. When task abort happens to a PM request sent during runtime suspend/resume, even if it can be successfully aborted, RPM framework anyways saves the (TIMEOUT) error. But we want more and we can do better - let error handling recover and clear the runtime_error. So, let PM requests take the fast abort path in ufshcd_abort(). Signed-off-by: Can Guo --- drivers/scsi/ufs/ufshcd.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index a6313cf40..2a814e2 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -2643,7 +2643,7 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) lrbp = &hba->lrb[tag]; if (unlikely(lrbp->in_use)) { - if (hba->wl_pm_op_in_progress) + if (cmd->request->rq_flags & RQF_PM) set_host_byte(cmd, DID_BAD_TARGET); else err = SCSI_MLQUEUE_HOST_BUSY; @@ -2690,7 +2690,7 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) * err handler blocked for too long. So, just fail the scsi cmd * sent from PM ops, err handler can recover PM error anyways. */ - if (hba->wl_pm_op_in_progress) { + if (cmd->request->rq_flags & RQF_PM) { hba->force_reset = true; set_host_byte(cmd, DID_BAD_TARGET); goto out_compl_cmd; @@ -6959,14 +6959,17 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) } /* - * Task abort to the device W-LUN is illegal. When this command - * will fail, due to spec violation, scsi err handling next step - * will be to send LU reset which, again, is a spec violation. - * To avoid these unnecessary/illegal steps, first we clean up - * the lrb taken by this cmd and mark the lrb as in_use, then - * queue the eh_work and bail. + * This fast path guarantees the cmd always gets aborted successfully, + * meanwhile it invokes the error handler. It allows contexts, which + * are blocked by this cmd, to fail fast. It serves multiple purposes: + * #1 To avoid unnecessary/illagal abort attempts to the W-LU. + * #2 To avoid live lock between eh_work and specific contexts, i.e., + * suspend/resume and eh_work itself. + * #3 To let eh_work recover runtime PM error in case abort happens + * to cmds sent from runtime suspend/resume ops. */ - if (lrbp->lun == UFS_UPIU_UFS_DEVICE_WLUN) { + if (lrbp->lun == UFS_UPIU_UFS_DEVICE_WLUN || + (cmd->request->rq_flags & RQF_PM)) { ufshcd_update_evt_hist(hba, UFS_EVT_ABORT, lrbp->lun); spin_lock_irqsave(host->host_lock, flags); if (lrbp->cmd) {