From patchwork Wed Jun 23 07:35:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Can Guo X-Patchwork-Id: 466187 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, 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 2E9A5C4743C for ; Wed, 23 Jun 2021 07:37:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 16BF3611AC for ; Wed, 23 Jun 2021 07:37:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230409AbhFWHjX (ORCPT ); Wed, 23 Jun 2021 03:39:23 -0400 Received: from labrats.qualcomm.com ([199.106.110.90]:1345 "EHLO labrats.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230422AbhFWHjG (ORCPT ); Wed, 23 Jun 2021 03:39:06 -0400 IronPort-SDR: ctEM4QSLoXvC/Zv1StDrWtEWkPnvsFBmb/9zZU6Xl2S0Nhnd3UEOOWuXBcVa6AhbfQo+pe/vzj Al/wPoQBIE70ChFg8ySnnXGcexOBTRCzGsClzqdyy9LX6AEJK4S/ZxFeQP29iBnFC9rx9B1r6B 6a/ZW8AzdjERiATCscvEUvRO7/XvWET9hbI44xzweRILO4B56VuTGIOeIhmW4QowbAKzqZerbP CZhBIukh7BIUvyAMUhoB72LfISMlm1hZDGKYToYlqGEkbWYxXqTpC126SmRoSZvzNiPRKx29SW Jis= X-IronPort-AV: E=Sophos;i="5.83,293,1616482800"; d="scan'208";a="29780818" Received: from unknown (HELO ironmsg03-sd.qualcomm.com) ([10.53.140.143]) by labrats.qualcomm.com with ESMTP; 23 Jun 2021 00:36:47 -0700 X-QCInternal: smtphost Received: from stor-presley.qualcomm.com ([192.168.140.85]) by ironmsg03-sd.qualcomm.com with ESMTP; 23 Jun 2021 00:36:46 -0700 Received: by stor-presley.qualcomm.com (Postfix, from userid 359480) id A374A21BC1; Wed, 23 Jun 2021 00:36:46 -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: Andy Gross , Bjorn Andersson , Alim Akhtar , Avri Altman , "James E.J. Bottomley" , "Martin K. Petersen" , Stanley Chu , Bean Huo , Jaegeuk Kim , Adrian Hunter , Kiwoong Kim , Satya Tangirala , Bart Van Assche , linux-arm-msm@vger.kernel.org (open list:ARM/QUALCOMM SUPPORT), linux-kernel@vger.kernel.org (open list) Subject: [PATCH v4 01/10] scsi: ufs: Rename flags pm_op_in_progress and is_sys_suspended Date: Wed, 23 Jun 2021 00:35:00 -0700 Message-Id: <1624433711-9339-2-git-send-email-cang@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1624433711-9339-1-git-send-email-cang@codeaurora.org> References: <1624433711-9339-1-git-send-email-cang@codeaurora.org> Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Rename pm_op_in_progress and is_sys_suspended to wlu_pm_op_in_progress and is_wlu_sys_suspended accordingly. Signed-off-by: Can Guo --- drivers/scsi/ufs/ufs-qcom.c | 2 +- drivers/scsi/ufs/ufshcd.c | 30 +++++++++++++++--------------- drivers/scsi/ufs/ufshcd.h | 6 ++++-- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c index 9b1d18d..fbe21e0 100644 --- a/drivers/scsi/ufs/ufs-qcom.c +++ b/drivers/scsi/ufs/ufs-qcom.c @@ -641,7 +641,7 @@ static int ufs_qcom_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) if (err) return err; - hba->is_sys_suspended = false; + hba->is_wlu_sys_suspended = false; return 0; } diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 25fe18a..c40ba1d 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -549,8 +549,8 @@ 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", - hba->pm_op_in_progress, hba->is_sys_suspended); + dev_err(hba->dev, "wlu_pm_op_in_progress=%d, is_wlu_sys_suspended=%d\n", + hba->wlu_pm_op_in_progress, hba->is_wlu_sys_suspended); dev_err(hba->dev, "Auto BKOPS=%d, Host self-block=%d\n", hba->auto_bkops_enabled, hba->host->host_self_blocked); dev_err(hba->dev, "Clk gate=%d\n", hba->clk_gating.state); @@ -1999,7 +1999,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->wlu_pm_op_in_progress) { spin_unlock_irqrestore(hba->host->host_lock, flags); return; } @@ -2734,7 +2734,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->wlu_pm_op_in_progress) { hba->force_reset = true; set_host_byte(cmd, DID_BAD_TARGET); cmd->scsi_done(cmd); @@ -2767,7 +2767,7 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) (hba->clk_gating.state != CLKS_ON)); if (unlikely(test_bit(tag, &hba->outstanding_reqs))) { - if (hba->pm_op_in_progress) + if (hba->wlu_pm_op_in_progress) set_host_byte(cmd, DID_BAD_TARGET); else err = SCSI_MLQUEUE_HOST_BUSY; @@ -5116,7 +5116,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->wlu_pm_op_in_progress && !ufshcd_eh_in_progress(hba) && ufshcd_is_exception_event(lrbp->ucd_rsp_ptr)) /* Flushed in suspend */ @@ -5916,7 +5916,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_wlu_sys_suspended) { enum ufs_pm_op pm_op; /* @@ -5933,7 +5933,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_wlu_sys_suspended ? UFS_SYSTEM_PM : UFS_RUNTIME_PM; ufshcd_vops_resume(hba, pm_op); } else { ufshcd_hold(hba, false); @@ -5976,7 +5976,7 @@ static void ufshcd_recover_pm_error(struct ufs_hba *hba) struct request_queue *q; int ret; - hba->is_sys_suspended = false; + hba->is_wlu_sys_suspended = false; /* * Set RPM status of wlun device to RPM_ACTIVE, * this also clears its runtime error. @@ -8784,7 +8784,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->wlu_pm_op_in_progress = true; if (pm_op != UFS_SHUTDOWN_PM) { pm_lvl = pm_op == UFS_RUNTIME_PM ? hba->rpm_lvl : hba->spm_lvl; @@ -8919,7 +8919,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->wlu_pm_op_in_progress = false; return ret; } @@ -8928,7 +8928,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->wlu_pm_op_in_progress = true; /* * Call vendor specific resume callback. As these callbacks may access @@ -9006,7 +9006,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->wlu_pm_op_in_progress = false; return ret; } @@ -9072,7 +9072,7 @@ static int ufshcd_wl_suspend(struct device *dev) out: if (!ret) - hba->is_sys_suspended = true; + hba->is_wlu_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); @@ -9100,7 +9100,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_wlu_sys_suspended = false; up(&hba->host_sem); return ret; } diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index c98d540..93aeeb3 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -752,7 +752,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; + /* A flag to tell whether __ufshcd_wl_suspend/resume() is in progress */ + bool wlu_pm_op_in_progress; /* Auto-Hibernate Idle Timer register value */ u32 ahit; @@ -838,7 +839,8 @@ struct ufs_hba { struct devfreq *devfreq; struct ufs_clk_scaling clk_scaling; - bool is_sys_suspended; + /* A flag to tell whether the UFS device W-LU is system suspended */ + bool is_wlu_sys_suspended; enum bkops_status urgent_bkops_lvl; bool is_urgent_bkops_lvl_checked; From patchwork Wed Jun 23 07:35:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Can Guo X-Patchwork-Id: 466186 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, 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 A2C34C49EA4 for ; Wed, 23 Jun 2021 07:37:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8EDAA6128A for ; Wed, 23 Jun 2021 07:37:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231182AbhFWHja (ORCPT ); Wed, 23 Jun 2021 03:39:30 -0400 Received: from labrats.qualcomm.com ([199.106.110.90]:9285 "EHLO labrats.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231207AbhFWHjQ (ORCPT ); Wed, 23 Jun 2021 03:39:16 -0400 IronPort-SDR: ujXVmqoYARV0Q8xtWsocShnrvWMWpL4um30/LKnCvTJwnfur+9R3D6qcZrrNk8fUkOP4gIW+PM oeldCWf5v9ug+TZcJv4RgGOKbyoCZtB1qGu9E4TnDCijfZ7QvdxrZdO6dY1kOks/bbTsP1dBQg TgBX6x0EjCLQXD+jQBem1YWUELC4RS9Xa4li6+IhjJvhKMgeVqmCbKQZrDV90kCJS4bzP38uMO 8Ac8Q5yQ8UD8J/7H+djzDuOXw1qiPe8vijHCMAI3ZLgtF8e4/nUOCjMdQ2dKlaXsNNsHAwb538 TkI= X-IronPort-AV: E=Sophos;i="5.83,293,1616482800"; d="scan'208";a="47902944" Received: from unknown (HELO ironmsg01-sd.qualcomm.com) ([10.53.140.141]) by labrats.qualcomm.com with ESMTP; 23 Jun 2021 00:36:59 -0700 X-QCInternal: smtphost Received: from wsp769891wss.qualcomm.com (HELO stor-presley.qualcomm.com) ([192.168.140.85]) by ironmsg01-sd.qualcomm.com with ESMTP; 23 Jun 2021 00:36:56 -0700 Received: by stor-presley.qualcomm.com (Postfix, from userid 359480) id 95B3521BC1; Wed, 23 Jun 2021 00:36:52 -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 , Satya Tangirala , Kiwoong Kim , Bart Van Assche , linux-kernel@vger.kernel.org (open list) Subject: [PATCH v4 02/10] scsi: ufs: Add flags pm_op_in_progress and is_sys_suspended Date: Wed, 23 Jun 2021 00:35:01 -0700 Message-Id: <1624433711-9339-3-git-send-email-cang@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1624433711-9339-1-git-send-email-cang@codeaurora.org> References: <1624433711-9339-1-git-send-email-cang@codeaurora.org> Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Add flags pm_op_in_progress and is_sys_suspended to track the status of hba runtime and system suspend/resume operations. Signed-off-by: Can Guo --- drivers/scsi/ufs/ufshcd.c | 12 +++++++++++- drivers/scsi/ufs/ufshcd.h | 4 ++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index c40ba1d..abe5f2d 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -551,6 +551,8 @@ static void ufshcd_print_host_state(struct ufs_hba *hba) hba->curr_dev_pwr_mode, hba->uic_link_state); dev_err(hba->dev, "wlu_pm_op_in_progress=%d, is_wlu_sys_suspended=%d\n", hba->wlu_pm_op_in_progress, hba->is_wlu_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); dev_err(hba->dev, "Clk gate=%d\n", hba->clk_gating.state); @@ -9141,6 +9143,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. @@ -9160,6 +9164,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; } @@ -9179,6 +9184,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) @@ -9198,6 +9204,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; } @@ -9222,6 +9229,8 @@ 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); @@ -9247,7 +9256,8 @@ int ufshcd_system_resume(struct ufs_hba *hba) trace_ufshcd_system_resume(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 = false; return ret; } EXPORT_SYMBOL(ufshcd_system_resume); diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 93aeeb3..1e7fe73 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -754,6 +754,8 @@ struct ufs_hba { struct device_attribute spm_lvl_attr; /* A flag to tell whether __ufshcd_wl_suspend/resume() is in progress */ bool wlu_pm_op_in_progress; + /* A flag to tell whether ufshcd_suspend/resume() is in progress */ + bool pm_op_in_progress; /* Auto-Hibernate Idle Timer register value */ u32 ahit; @@ -841,6 +843,8 @@ struct ufs_hba { struct ufs_clk_scaling clk_scaling; /* A flag to tell whether the UFS device W-LU is system suspended */ bool is_wlu_sys_suspended; + /* A flag to tell whether hba is system suspended */ + bool is_sys_suspended; enum bkops_status urgent_bkops_lvl; bool is_urgent_bkops_lvl_checked; From patchwork Wed Jun 23 07:35:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Can Guo X-Patchwork-Id: 466660 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, 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 E5DD5C48BE5 for ; Wed, 23 Jun 2021 07:37:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CA213611AC for ; Wed, 23 Jun 2021 07:37:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231167AbhFWHj3 (ORCPT ); Wed, 23 Jun 2021 03:39:29 -0400 Received: from labrats.qualcomm.com ([199.106.110.90]:1336 "EHLO labrats.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230498AbhFWHjO (ORCPT ); Wed, 23 Jun 2021 03:39:14 -0400 IronPort-SDR: yr2W6pfUiVo9FEI9d2LqouW+cLcrY70qPmPHgWIsWYCxe8stBc0y0UEH0UdHQ9eMYvjAx1jeEg hUifsXn6Gy99tgmRx4fe/etgVmLeo1v7cGtp5nWmvJ/WzWJ7YFtOcRCWEwddak0/d7ecz51koE c44gT3jo8joKPPubAlY1tT4HY4azvE71aYYDfLoTO5VIT/aQioZ28vbww213WQcp0b2+lgYDEa 0k4iCBGetTg2A66hQhptH2yswW89leyNmPh9c0OLmaAKnOnWKEqPIiDNGWNtd2sIIaRQHBBch0 MVk= X-IronPort-AV: E=Sophos;i="5.83,293,1616482800"; d="scan'208";a="29780819" Received: from unknown (HELO ironmsg03-sd.qualcomm.com) ([10.53.140.143]) by labrats.qualcomm.com with ESMTP; 23 Jun 2021 00:36:56 -0700 X-QCInternal: smtphost Received: from stor-presley.qualcomm.com ([192.168.140.85]) by ironmsg03-sd.qualcomm.com with ESMTP; 23 Jun 2021 00:36:56 -0700 Received: by stor-presley.qualcomm.com (Postfix, from userid 359480) id 1B06421BE2; Wed, 23 Jun 2021 00:36:56 -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 v4 03/10] scsi: ufs: Update the return value of supplier pm ops Date: Wed, 23 Jun 2021 00:35:02 -0700 Message-Id: <1624433711-9339-4-git-send-email-cang@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1624433711-9339-1-git-send-email-cang@codeaurora.org> References: <1624433711-9339-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 abe5f2d..ee70522 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -8922,7 +8922,7 @@ static int __ufshcd_wl_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) ufshcd_release(hba); } hba->wlu_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) @@ -9009,7 +9009,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->wlu_pm_op_in_progress = false; - return ret; + return ret <= 0 ? ret : -EINVAL; } static int ufshcd_wl_runtime_suspend(struct device *dev) From patchwork Wed Jun 23 07:35:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Can Guo X-Patchwork-Id: 466659 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, 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 97E22C4743C for ; Wed, 23 Jun 2021 07:37:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 83892611AC for ; Wed, 23 Jun 2021 07:37:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231235AbhFWHjj (ORCPT ); Wed, 23 Jun 2021 03:39:39 -0400 Received: from labrats.qualcomm.com ([199.106.110.90]:1666 "EHLO labrats.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230363AbhFWHjT (ORCPT ); Wed, 23 Jun 2021 03:39:19 -0400 IronPort-SDR: M6TRVFwkS6FOV6qff0MiXiwDGxCYMI6QeciZCr6r/nzZ2LyTUwFjjCx3z1aAc6lUN5EWFiOAkr UvDV+CraFZoTQtSQGA0V/Y1lNfw5xGqKJmZZlvoyaRBRvyP0GEJbG7qJBxN8mcc5k/cbaKrlWW UKmvewxRIrOe5VBdFzKwaPH9XcI+SYro7bzENHa5m7H5c4f6445KoggB6WUTLU5vdnnJlbqslb NpKk/0r3FEwCPcCePzBHHj5if3THNiYv26deN8EN6OVzF6d7Sr4Z1JHCYQA2Ggyf/qjHDCV+Ru p3g= X-IronPort-AV: E=Sophos;i="5.83,293,1616482800"; d="scan'208";a="29780820" Received: from unknown (HELO ironmsg03-sd.qualcomm.com) ([10.53.140.143]) by labrats.qualcomm.com with ESMTP; 23 Jun 2021 00:37:00 -0700 X-QCInternal: smtphost Received: from stor-presley.qualcomm.com ([192.168.140.85]) by ironmsg03-sd.qualcomm.com with ESMTP; 23 Jun 2021 00:36:59 -0700 Received: by stor-presley.qualcomm.com (Postfix, from userid 359480) id BC2E921BC1; Wed, 23 Jun 2021 00:36: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 v4 04/10] scsi: ufs: Enable IRQ after enabling clocks in error handling preparation Date: Wed, 23 Jun 2021 00:35:03 -0700 Message-Id: <1624433711-9339-5-git-send-email-cang@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1624433711-9339-1-git-send-email-cang@codeaurora.org> References: <1624433711-9339-1-git-send-email-cang@codeaurora.org> Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org In error handling preparation, enable IRQ after enabling clocks in case unclocked register access happens. Fixes: c72e79c0ad2bd ("scsi: ufs: Recover HBA runtime PM error in error handler") Signed-off-by: Can Guo --- drivers/scsi/ufs/ufshcd.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index ee70522..5f837c4 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -5927,13 +5927,14 @@ static void ufshcd_err_handling_prepare(struct ufs_hba *hba) * 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)) + if (!ufshcd_is_clkgating_allowed(hba)) { ufshcd_setup_clocks(hba, true); + ufshcd_enable_irq(hba); + } ufshcd_release(hba); pm_op = hba->is_wlu_sys_suspended ? UFS_SYSTEM_PM : UFS_RUNTIME_PM; ufshcd_vops_resume(hba, pm_op); From patchwork Wed Jun 23 07:35:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Can Guo X-Patchwork-Id: 466185 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, 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 F351FC48BE5 for ; Wed, 23 Jun 2021 07:37:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DC5B46128A for ; Wed, 23 Jun 2021 07:37:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230392AbhFWHjk (ORCPT ); Wed, 23 Jun 2021 03:39:40 -0400 Received: from labrats.qualcomm.com ([199.106.110.90]:9757 "EHLO labrats.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230513AbhFWHjV (ORCPT ); Wed, 23 Jun 2021 03:39:21 -0400 IronPort-SDR: lt5cE9eBpnslfYbr9VZrYOHwKXrlwitl/+pnUlcMX4dqbvrn9AwzaPptbQX17blGahA1tXlgpb zS102jxZ0DmJ/7C2NjO3idjeoxbwWotrMRltdgAaQmxq6vFrwtqmJspYpZefEaBf9C1VWLugHL xAmCBOdq2+WtbVsj6L+pNz+iikdBLq50D7mvKy1rXK66FuQrsOiNxS8akmlhxkAiwOlr1UF9Bd 39SW/tD8RZpjZstHEj1Pze9KhGUmMC+BtaF1FusNEJntmFZzL6hEVgLrxDBS8kQVdz9So6m561 jo0= X-IronPort-AV: E=Sophos;i="5.83,293,1616482800"; d="scan'208";a="47902945" Received: from unknown (HELO ironmsg-SD-alpha.qualcomm.com) ([10.53.140.30]) by labrats.qualcomm.com with ESMTP; 23 Jun 2021 00:37:04 -0700 X-QCInternal: smtphost Received: from wsp769891wss.qualcomm.com (HELO stor-presley.qualcomm.com) ([192.168.140.85]) by ironmsg-SD-alpha.qualcomm.com with ESMTP; 23 Jun 2021 00:37:03 -0700 Received: by stor-presley.qualcomm.com (Postfix, from userid 359480) id B4AF621BC1; Wed, 23 Jun 2021 00:37:03 -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 05/10] scsi: ufs: Complete the cmd before returning in queuecommand Date: Wed, 23 Jun 2021 00:35:04 -0700 Message-Id: <1624433711-9339-6-git-send-email-cang@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1624433711-9339-1-git-send-email-cang@codeaurora.org> References: <1624433711-9339-1-git-send-email-cang@codeaurora.org> Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Commit 7a7e66c65d4148fc3f23b058405bc9f102414fcb ("scsi: ufs: Fix a race condition between ufshcd_abort() and eh_work()") forgot to complete the cmd, which takes an occupied lrb, before returning in queuecommand. This change adds the missing codes. Fixes: 7a7e66c65d414 ("scsi: ufs: Fix a race condition between ufshcd_abort() and eh_work()") Signed-off-by: Can Guo diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 5f837c4..7fbc63e 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -2758,6 +2758,16 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) goto out; } + if (unlikely(test_bit(tag, &hba->outstanding_reqs))) { + if (hba->wlu_pm_op_in_progress) { + set_host_byte(cmd, DID_BAD_TARGET); + cmd->scsi_done(cmd); + } else { + err = SCSI_MLQUEUE_HOST_BUSY; + } + goto out; + } + hba->req_abort_count = 0; err = ufshcd_hold(hba, true); @@ -2768,15 +2778,6 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) WARN_ON(ufshcd_is_clkgating_allowed(hba) && (hba->clk_gating.state != CLKS_ON)); - if (unlikely(test_bit(tag, &hba->outstanding_reqs))) { - if (hba->wlu_pm_op_in_progress) - set_host_byte(cmd, DID_BAD_TARGET); - else - err = SCSI_MLQUEUE_HOST_BUSY; - ufshcd_release(hba); - goto out; - } - lrbp = &hba->lrb[tag]; WARN_ON(lrbp->cmd); lrbp->cmd = cmd; From patchwork Wed Jun 23 07:35:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Can Guo X-Patchwork-Id: 466184 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, 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 1D79EC48BE5 for ; Wed, 23 Jun 2021 07:37:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 09265611AC for ; Wed, 23 Jun 2021 07:37:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231135AbhFWHjt (ORCPT ); Wed, 23 Jun 2021 03:39:49 -0400 Received: from labrats.qualcomm.com ([199.106.110.90]:46767 "EHLO labrats.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230456AbhFWHj2 (ORCPT ); Wed, 23 Jun 2021 03:39:28 -0400 IronPort-SDR: 25XuRK9IuinLb2dsg5AberW6mEs7JsWq12WmHo8WbPHrPsfIqaKD1csCoNQXS/6rGGWELoxUwI XT9K7hFfQ7mrv6fJu9fjhGlFEwxsuAPBjM5MefxfKDZ0xEJyLuSo7t7E0rWTZ1wcmpMKnHab8O zLI6tc9mfmSf1hoXIAP8AKpsOS4xd06RTb8Puf1oPbuJFYvwu44TR7CRG5C2xWAU5GakerhxQO WbB8prvB5zjowXhoJ0r7SYxQZD6fJyfNw/Q95bGApc+1joMrEd3rgZltTEI864q5YPq+r8nzn8 UV8= X-IronPort-AV: E=Sophos;i="5.83,293,1616482800"; d="scan'208";a="29780821" Received: from unknown (HELO ironmsg04-sd.qualcomm.com) ([10.53.140.144]) by labrats.qualcomm.com with ESMTP; 23 Jun 2021 00:37:11 -0700 X-QCInternal: smtphost Received: from stor-presley.qualcomm.com ([192.168.140.85]) by ironmsg04-sd.qualcomm.com with ESMTP; 23 Jun 2021 00:37:10 -0700 Received: by stor-presley.qualcomm.com (Postfix, from userid 359480) id D312D21BC1; Wed, 23 Jun 2021 00:37:10 -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 v4 06/10] scsi: ufs: Remove host_sem used in suspend/resume Date: Wed, 23 Jun 2021 00:35:06 -0700 Message-Id: <1624433711-9339-8-git-send-email-cang@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1624433711-9339-1-git-send-email-cang@codeaurora.org> References: <1624433711-9339-1-git-send-email-cang@codeaurora.org> Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org To protect system suspend/resume from being disturbed by error handling, instead of using host_sem, let error handler call lock_system_sleep() and unlock_system_sleep() which achieve the same purpose. Remove the host_sem used in suspend/resume paths to make the code more readable. Suggested-by: Bart Van Assche Signed-off-by: Can Guo --- drivers/scsi/ufs/ufshcd.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 3695dd2..a09e4a2 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -5907,6 +5907,11 @@ static void ufshcd_clk_scaling_suspend(struct ufs_hba *hba, bool suspend) static void ufshcd_err_handling_prepare(struct ufs_hba *hba) { + /* + * It is not safe to perform error handling while suspend or resume is + * in progress. Hence the lock_system_sleep() call. + */ + lock_system_sleep(); ufshcd_rpm_get_sync(hba); if (pm_runtime_status_suspended(&hba->sdev_ufs_device->sdev_gendev) || hba->is_wlu_sys_suspended) { @@ -5951,6 +5956,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); + unlock_system_sleep(); } static inline bool ufshcd_err_handling_should_stop(struct ufs_hba *hba) @@ -9053,16 +9059,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) @@ -9095,7 +9098,6 @@ static int ufshcd_wl_resume(struct device *dev) hba->curr_dev_pwr_mode, hba->uic_link_state); if (!ret) hba->is_wlu_sys_suspended = false; - up(&hba->host_sem); return ret; } #endif From patchwork Wed Jun 23 07:35:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Can Guo X-Patchwork-Id: 466657 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, 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 9BCDFC48BE5 for ; Wed, 23 Jun 2021 07:37:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 85B316128A for ; Wed, 23 Jun 2021 07:37:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231215AbhFWHj7 (ORCPT ); Wed, 23 Jun 2021 03:39:59 -0400 Received: from labrats.qualcomm.com ([199.106.110.90]:1336 "EHLO labrats.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231216AbhFWHjf (ORCPT ); Wed, 23 Jun 2021 03:39:35 -0400 IronPort-SDR: 1sK+7NVO8ocyv0fC1vFZySpl1OO5BRLl07oXIDVFZIgtxyYRDyH9hbJ3F27UJmlOH2plpvEjJh +BcCoy3W4RplFAQjcaLzkMSISraDymnL5/puVdCOvFbPduUlEOUb0ad+XIx7cHZuqNK1prNlhe slAEnvuDBsiiwPXfLKRYGnR1xyPzZwmMdls0/D2SlxO6j3GvwAzby0tlWw/GGGZPVCmHvVSOup QpXHPKveQxOBilp5AKd+R8qdsU9XTiWz2Hq5jGfaALk8+Gn6cTrZsItdapLyyBUmpOUhBmustr yLA= X-IronPort-AV: E=Sophos;i="5.83,293,1616482800"; d="scan'208";a="29780822" Received: from unknown (HELO ironmsg03-sd.qualcomm.com) ([10.53.140.143]) by labrats.qualcomm.com with ESMTP; 23 Jun 2021 00:37:16 -0700 X-QCInternal: smtphost Received: from stor-presley.qualcomm.com ([192.168.140.85]) by ironmsg03-sd.qualcomm.com with ESMTP; 23 Jun 2021 00:37:14 -0700 Received: by stor-presley.qualcomm.com (Postfix, from userid 359480) id 8541C21BC1; Wed, 23 Jun 2021 00:37:14 -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 v4 07/10] scsi: ufs: Simplify error handling preparation Date: Wed, 23 Jun 2021 00:35:07 -0700 Message-Id: <1624433711-9339-9-git-send-email-cang@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1624433711-9339-1-git-send-email-cang@codeaurora.org> References: <1624433711-9339-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 | 56 +++++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index a09e4a2..379c6a0 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -2727,8 +2727,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 @@ -5905,34 +5905,31 @@ 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) { /* * It is not safe to perform error handling while suspend or resume is * in progress. Hence the lock_system_sleep() call. */ lock_system_sleep(); + /* + * Exclusively call pm_runtime_get_sync(hba->dev) once, in case + * following ufshcd_rpm_get_sync() fails. + */ + pm_runtime_get_sync(hba->dev); + if (pm_runtime_suspended(hba->dev) || hba->is_sys_suspended) { + pm_runtime_put(hba->dev); + unlock_system_sleep(); + return -EINVAL; + } + + ufshcd_set_eh_in_progress(hba); 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_wlu_sys_suspended) { - enum ufs_pm_op pm_op; + enum ufs_pm_op pm_op = hba->is_wlu_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_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_enable_irq(hba); - } - ufshcd_release(hba); - pm_op = hba->is_wlu_sys_suspended ? UFS_SYSTEM_PM : UFS_RUNTIME_PM; ufshcd_vops_resume(hba, pm_op); } else { ufshcd_hold(hba, false); @@ -5946,16 +5943,19 @@ 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) { + ufshcd_clear_eh_in_progress(hba); ufshcd_scsi_unblock_requests(hba); ufshcd_release(hba); if (ufshcd_is_clkscaling_supported(hba)) ufshcd_clk_scaling_suspend(hba, false); ufshcd_clear_ua_wluns(hba); ufshcd_rpm_put(hba); + pm_runtime_put(hba->dev); unlock_system_sleep(); } @@ -6048,9 +6048,13 @@ 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; + } /* Complete requests that have door-bell cleared by h/w */ ufshcd_complete_requests(hba); spin_lock_irqsave(hba->host->host_lock, flags); @@ -6194,7 +6198,6 @@ static void ufshcd_err_handler(struct work_struct *work) dev_err_ratelimited(hba->dev, "%s: exit: saved_err 0x%x saved_uic_err 0x%x", __func__, hba->saved_err, hba->saved_uic_err); } - ufshcd_clear_eh_in_progress(hba); spin_unlock_irqrestore(hba->host->host_lock, flags); ufshcd_err_handling_unprepare(hba); up(&hba->host_sem); @@ -8995,6 +8998,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: @@ -9004,8 +9010,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->wlu_pm_op_in_progress = false; return ret <= 0 ? ret : -EINVAL; } From patchwork Wed Jun 23 07:35:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Can Guo X-Patchwork-Id: 466656 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, 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 33558C48BE5 for ; Wed, 23 Jun 2021 07:37:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1E6846128A for ; Wed, 23 Jun 2021 07:37:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231132AbhFWHkD (ORCPT ); Wed, 23 Jun 2021 03:40:03 -0400 Received: from labrats.qualcomm.com ([199.106.110.90]:1666 "EHLO labrats.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230239AbhFWHjj (ORCPT ); Wed, 23 Jun 2021 03:39:39 -0400 IronPort-SDR: gxr3rinUnZwqhDdvoPSRL3vJPIPKMfWgnZxn3KTf+6ceJ/uPEtNRQLo7c4+cgAZ/VJjjaCaRZK 4hetoaFwvUTjqYQthpw+igVHNe96ts1DoJEhPg5EKnryoN/4a4bDpdiSPcw7v5kjXuFmsLxGY0 5buz/q0xuKhWTdo+4fghNnlusBHXVxAit8gexCVBTmNum1dop7bBPRBTz8mhJV1LLV605VrkWS rrsbuJ/ne/ptgMtLuEH4friErVigXmi8xJROLWfzbldzPwshRd7RfChmoub1RjD+nBjiNiWTUc BwA= X-IronPort-AV: E=Sophos;i="5.83,293,1616482800"; d="scan'208";a="29780823" Received: from unknown (HELO ironmsg04-sd.qualcomm.com) ([10.53.140.144]) by labrats.qualcomm.com with ESMTP; 23 Jun 2021 00:37:18 -0700 X-QCInternal: smtphost Received: from stor-presley.qualcomm.com ([192.168.140.85]) by ironmsg04-sd.qualcomm.com with ESMTP; 23 Jun 2021 00:37:18 -0700 Received: by stor-presley.qualcomm.com (Postfix, from userid 359480) id 1ABA121BC1; Wed, 23 Jun 2021 00:37:18 -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 v4 08/10] scsi: ufs: Update ufshcd_recover_pm_error() Date: Wed, 23 Jun 2021 00:35:08 -0700 Message-Id: <1624433711-9339-10-git-send-email-cang@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1624433711-9339-1-git-send-email-cang@codeaurora.org> References: <1624433711-9339-1-git-send-email-cang@codeaurora.org> Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org After error handler performs a successful reset and restore, all the LUs become active, forcibly set the runtime PM status of the scsi devices (and their request queues) underneath hba to ACTIVE to reflect the change. By doing so, dev->power.runtime_error (if any) can also be cleared, such that runtime PM can get back to work on them, otherwise the device(s) may be left either runtime active or runtime suspended permanently. Signed-off-by: Can Guo --- drivers/scsi/ufs/ufshcd.c | 49 ++++++++++++++++++++--------------------------- 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 379c6a0..d739401 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -243,6 +243,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, @@ -5946,13 +5947,15 @@ 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_clear_eh_in_progress(hba); 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); @@ -5972,34 +5975,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_wlu_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 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) @@ -6033,7 +6028,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; @@ -6185,8 +6180,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); } @@ -6199,7 +6192,7 @@ static void ufshcd_err_handler(struct work_struct *work) __func__, hba->saved_err, hba->saved_uic_err); } spin_unlock_irqrestore(hba->host->host_lock, flags); - ufshcd_err_handling_unprepare(hba); + ufshcd_err_handling_unprepare(hba, err); up(&hba->host_sem); } From patchwork Wed Jun 23 07:35:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Can Guo X-Patchwork-Id: 466183 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, 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 5D9F9C4743C for ; Wed, 23 Jun 2021 07:37:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4810F6128A for ; Wed, 23 Jun 2021 07:37:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231138AbhFWHkC (ORCPT ); Wed, 23 Jun 2021 03:40:02 -0400 Received: from labrats.qualcomm.com ([199.106.110.90]:7940 "EHLO labrats.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230321AbhFWHji (ORCPT ); Wed, 23 Jun 2021 03:39:38 -0400 IronPort-SDR: jy8uAwflVNG+L5mclM1eGNhOAaQWdfjN3TOGMex+azcwwvAn9JAsMofy2Ux3pLL4Mj36hUrrzd g3BuEs135RWNFD2He1jBrohucf1Ny+ym3HB98pyP1K+BuupL130U16erqRxGIrUCjfPqFWZvU9 mprPr07lNKsFH0LXVWqyAYxb5sYct8pKlqyh0wmv6Czb9S0GP4NzVtCoykep2j83FPhgj0Zh/2 kdGxrcXKbJgTQKBHCuLWzq8klqn9CqZgZByn3bbVrvey313zYe0WOQo3YVnj+E41HVoKhYj6+m AE0= X-IronPort-AV: E=Sophos;i="5.83,293,1616482800"; d="scan'208";a="47902947" Received: from unknown (HELO ironmsg01-sd.qualcomm.com) ([10.53.140.141]) by labrats.qualcomm.com with ESMTP; 23 Jun 2021 00:37:21 -0700 X-QCInternal: smtphost Received: from wsp769891wss.qualcomm.com (HELO stor-presley.qualcomm.com) ([192.168.140.85]) by ironmsg01-sd.qualcomm.com with ESMTP; 23 Jun 2021 00:37:21 -0700 Received: by stor-presley.qualcomm.com (Postfix, from userid 359480) id 86AB321BC1; Wed, 23 Jun 2021 00:37:21 -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 v4 09/10] scsi: ufs: Update the fast abort path in ufshcd_abort() for PM requests Date: Wed, 23 Jun 2021 00:35:09 -0700 Message-Id: <1624433711-9339-11-git-send-email-cang@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1624433711-9339-1-git-send-email-cang@codeaurora.org> References: <1624433711-9339-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 either runtime active or runtime suspended 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. In this situation, we can leverage error handling to 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 | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index d739401..59fc521 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -2737,7 +2737,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->wlu_pm_op_in_progress) { + if (cmd->request->rq_flags & RQF_PM) { hba->force_reset = true; set_host_byte(cmd, DID_BAD_TARGET); cmd->scsi_done(cmd); @@ -6981,11 +6981,14 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) int err = 0; struct ufshcd_lrb *lrbp; u32 reg; + bool need_eh = false; host = cmd->device->host; hba = shost_priv(host); tag = cmd->request->tag; lrbp = &hba->lrb[tag]; + + dev_info(hba->dev, "%s: Device abort task at tag %d\n", __func__, tag); if (!ufshcd_valid_tag(hba, tag)) { dev_err(hba->dev, "%s: invalid command tag %d: cmd=0x%p, cmd->request=0x%p", @@ -7003,9 +7006,6 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) goto out; } - /* Print Transfer Request of aborted task */ - dev_info(hba->dev, "%s: Device abort task at tag %d\n", __func__, tag); - /* * Print detailed info about aborted request. * As more than one request might get aborted at the same time, @@ -7033,21 +7033,21 @@ 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 re-set it in outstanding_reqs, - * 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); __ufshcd_transfer_req_compl(hba, (1UL << tag)); set_bit(tag, &hba->outstanding_reqs); - spin_lock_irqsave(host->host_lock, flags); - hba->force_reset = true; - ufshcd_schedule_eh_work(hba); - spin_unlock_irqrestore(host->host_lock, flags); + need_eh = true; goto out; } @@ -7061,6 +7061,12 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) cleanup: __ufshcd_transfer_req_compl(hba, (1UL << tag)); out: + if (cmd->request->rq_flags & RQF_PM || need_eh) { + spin_lock_irqsave(host->host_lock, flags); + hba->force_reset = true; + ufshcd_schedule_eh_work(hba); + spin_unlock_irqrestore(host->host_lock, flags); + } err = SUCCESS; } else { dev_err(hba->dev, "%s: failed with err %d\n", __func__, err); From patchwork Wed Jun 23 07:35:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Can Guo X-Patchwork-Id: 466182 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, 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 96F3BC48BE5 for ; Wed, 23 Jun 2021 07:38:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7F2156128C for ; Wed, 23 Jun 2021 07:38:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230234AbhFWHkh (ORCPT ); Wed, 23 Jun 2021 03:40:37 -0400 Received: from labrats.qualcomm.com ([199.106.110.90]:9904 "EHLO labrats.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231167AbhFWHkU (ORCPT ); Wed, 23 Jun 2021 03:40:20 -0400 IronPort-SDR: HCqlLkAUDzo+w2SllAiVZfl9uFgPjdvuEQ1oV7HYgdb+t6c0PVR2MHqsCM+2f1HcZerwZUVxPu aYGHNGUloh5F0zHDnCMXKL7ZO/hKvXIYWW6bPWFCaJgcqEmlHqAlSpsWZT/AVlbOpw5ldQp8uK hk6MXdRLEJz9foxpI8OU+9dws1W2l12GzOhBzGIqDhX1YC8ItBZCkmKUqA+EmHSP8VCiTqVxfW CT21MFqlDLD/iEOCZvduYT7GHIUoP0S1CDwNgcmYW7hIxsBT9KASFtu5T6ECoXSF7z/rRejhVc kMo= X-IronPort-AV: E=Sophos;i="5.83,293,1616482800"; d="scan'208";a="47902948" Received: from unknown (HELO ironmsg02-sd.qualcomm.com) ([10.53.140.142]) by labrats.qualcomm.com with ESMTP; 23 Jun 2021 00:38:03 -0700 X-QCInternal: smtphost Received: from stor-presley.qualcomm.com ([192.168.140.85]) by ironmsg02-sd.qualcomm.com with ESMTP; 23 Jun 2021 00:38:02 -0700 Received: by stor-presley.qualcomm.com (Postfix, from userid 359480) id 335C121BC1; Wed, 23 Jun 2021 00:38:02 -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" , Adrian Hunter , Bean Huo , Stanley Chu , Keoseong Park , "Gustavo A. R. Silva" , Jaegeuk Kim , Kiwoong Kim , Satya Tangirala , Bart Van Assche , linux-kernel@vger.kernel.org (open list) Subject: [PATCH v4 10/10] scsi: ufs: Apply more limitations to user access Date: Wed, 23 Jun 2021 00:35:10 -0700 Message-Id: <1624433711-9339-12-git-send-email-cang@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1624433711-9339-1-git-send-email-cang@codeaurora.org> References: <1624433711-9339-1-git-send-email-cang@codeaurora.org> Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org Do not let user access HW if hba resume fails or hba is not in good state, otherwise it may lead to various stability issues. Signed-off-by: Can Guo --- drivers/scsi/ufs/ufs-debugfs.c | 27 ++--------- drivers/scsi/ufs/ufs-sysfs.c | 105 ++++++++++++++--------------------------- drivers/scsi/ufs/ufs_bsg.c | 16 +++---- drivers/scsi/ufs/ufshcd.c | 63 +++++++++++++++---------- drivers/scsi/ufs/ufshcd.h | 17 ++++++- 5 files changed, 101 insertions(+), 127 deletions(-) diff --git a/drivers/scsi/ufs/ufs-debugfs.c b/drivers/scsi/ufs/ufs-debugfs.c index 4e1ff20..42c1c8b 100644 --- a/drivers/scsi/ufs/ufs-debugfs.c +++ b/drivers/scsi/ufs/ufs-debugfs.c @@ -52,25 +52,6 @@ static int ee_usr_mask_get(void *data, u64 *val) return 0; } -static int ufs_debugfs_get_user_access(struct ufs_hba *hba) -__acquires(&hba->host_sem) -{ - down(&hba->host_sem); - if (!ufshcd_is_user_access_allowed(hba)) { - up(&hba->host_sem); - return -EBUSY; - } - ufshcd_rpm_get_sync(hba); - return 0; -} - -static void ufs_debugfs_put_user_access(struct ufs_hba *hba) -__releases(&hba->host_sem) -{ - ufshcd_rpm_put_sync(hba); - up(&hba->host_sem); -} - static int ee_usr_mask_set(void *data, u64 val) { struct ufs_hba *hba = data; @@ -78,11 +59,11 @@ static int ee_usr_mask_set(void *data, u64 val) if (val & ~(u64)MASK_EE_STATUS) return -EINVAL; - err = ufs_debugfs_get_user_access(hba); + err = ufshcd_get_user_access(hba); if (err) return err; err = ufshcd_update_ee_usr_mask(hba, val, MASK_EE_STATUS); - ufs_debugfs_put_user_access(hba); + ufshcd_put_user_access(hba); return err; } @@ -120,10 +101,10 @@ static void ufs_debugfs_restart_ee(struct work_struct *work) struct ufs_hba *hba = container_of(work, struct ufs_hba, debugfs_ee_work.work); if (!hba->ee_usr_mask || pm_runtime_suspended(hba->dev) || - ufs_debugfs_get_user_access(hba)) + ufshcd_get_user_access(hba)) return; ufshcd_write_ee_control(hba); - ufs_debugfs_put_user_access(hba); + ufshcd_put_user_access(hba); } void ufs_debugfs_hba_init(struct ufs_hba *hba) diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c index 52bd807..b8732b9 100644 --- a/drivers/scsi/ufs/ufs-sysfs.c +++ b/drivers/scsi/ufs/ufs-sysfs.c @@ -160,22 +160,14 @@ static ssize_t auto_hibern8_show(struct device *dev, if (!ufshcd_is_auto_hibern8_supported(hba)) return -EOPNOTSUPP; - down(&hba->host_sem); - if (!ufshcd_is_user_access_allowed(hba)) { - ret = -EBUSY; - goto out; - } - - pm_runtime_get_sync(hba->dev); + ret = ufshcd_get_user_access(hba); + if (ret) + return ret; ufshcd_hold(hba, false); ahit = ufshcd_readl(hba, REG_AUTO_HIBERNATE_IDLE_TIMER); ufshcd_release(hba); - pm_runtime_put_sync(hba->dev); - ret = sysfs_emit(buf, "%d\n", ufshcd_ahit_to_us(ahit)); - -out: - up(&hba->host_sem); + ufshcd_put_user_access(hba); return ret; } @@ -202,7 +194,7 @@ static ssize_t auto_hibern8_store(struct device *dev, goto out; } - ufshcd_auto_hibern8_update(hba, ufshcd_us_to_ahit(timer)); + ret = ufshcd_auto_hibern8_update(hba, ufshcd_us_to_ahit(timer)); out: up(&hba->host_sem); @@ -239,17 +231,11 @@ static ssize_t wb_on_store(struct device *dev, struct device_attribute *attr, if (wb_enable != 0 && wb_enable != 1) return -EINVAL; - down(&hba->host_sem); - if (!ufshcd_is_user_access_allowed(hba)) { - res = -EBUSY; - goto out; - } - - ufshcd_rpm_get_sync(hba); + res = ufshcd_get_user_access(hba); + if (res) + return res; res = ufshcd_wb_toggle(hba, wb_enable); - ufshcd_rpm_put_sync(hba); -out: - up(&hba->host_sem); + ufshcd_put_user_access(hba); return res < 0 ? res : count; } @@ -527,16 +513,11 @@ static ssize_t ufs_sysfs_read_desc_param(struct ufs_hba *hba, if (param_size > 8) return -EINVAL; - down(&hba->host_sem); - if (!ufshcd_is_user_access_allowed(hba)) { - ret = -EBUSY; - goto out; - } - - ufshcd_rpm_get_sync(hba); + ret = ufshcd_get_user_access(hba); + if (ret) + return ret; ret = ufshcd_read_desc_param(hba, desc_id, desc_index, param_offset, desc_buf, param_size); - ufshcd_rpm_put_sync(hba); if (ret) { ret = -EINVAL; goto out; @@ -561,7 +542,7 @@ static ssize_t ufs_sysfs_read_desc_param(struct ufs_hba *hba, } out: - up(&hba->host_sem); + ufshcd_put_user_access(hba); return ret; } @@ -904,23 +885,20 @@ static ssize_t _name##_show(struct device *dev, \ int desc_len = QUERY_DESC_MAX_SIZE; \ u8 *desc_buf; \ \ - down(&hba->host_sem); \ - if (!ufshcd_is_user_access_allowed(hba)) { \ - up(&hba->host_sem); \ - return -EBUSY; \ - } \ + ret = ufshcd_get_user_access(hba); \ + if (ret) \ + return ret; \ desc_buf = kzalloc(QUERY_DESC_MAX_SIZE, GFP_ATOMIC); \ if (!desc_buf) { \ - up(&hba->host_sem); \ - return -ENOMEM; \ + ret = -ENOMEM; \ + goto out; \ } \ - ufshcd_rpm_get_sync(hba); \ ret = ufshcd_query_descriptor_retry(hba, \ UPIU_QUERY_OPCODE_READ_DESC, QUERY_DESC_IDN_DEVICE, \ 0, 0, desc_buf, &desc_len); \ if (ret) { \ ret = -EINVAL; \ - goto out; \ + goto out_free; \ } \ index = desc_buf[DEVICE_DESC_PARAM##_pname]; \ kfree(desc_buf); \ @@ -928,12 +906,12 @@ static ssize_t _name##_show(struct device *dev, \ ret = ufshcd_read_string_desc(hba, index, &desc_buf, \ SD_ASCII_STD); \ if (ret < 0) \ - goto out; \ + goto out_free; \ ret = sysfs_emit(buf, "%s\n", desc_buf); \ -out: \ - ufshcd_rpm_put_sync(hba); \ +out_free: \ kfree(desc_buf); \ - up(&hba->host_sem); \ +out: \ + ufshcd_put_user_access(hba); \ return ret; \ } \ static DEVICE_ATTR_RO(_name) @@ -973,24 +951,20 @@ static ssize_t _name##_show(struct device *dev, \ int ret; \ struct ufs_hba *hba = dev_get_drvdata(dev); \ \ - down(&hba->host_sem); \ - if (!ufshcd_is_user_access_allowed(hba)) { \ - up(&hba->host_sem); \ - return -EBUSY; \ - } \ + ret = ufshcd_get_user_access(hba); \ + if (ret) \ + return ret; \ if (ufshcd_is_wb_flags(QUERY_FLAG_IDN##_uname)) \ index = ufshcd_wb_get_query_index(hba); \ - ufshcd_rpm_get_sync(hba); \ ret = ufshcd_query_flag(hba, UPIU_QUERY_OPCODE_READ_FLAG, \ QUERY_FLAG_IDN##_uname, index, &flag); \ - ufshcd_rpm_put_sync(hba); \ if (ret) { \ ret = -EINVAL; \ goto out; \ } \ ret = sysfs_emit(buf, "%s\n", flag ? "true" : "false"); \ out: \ - up(&hba->host_sem); \ + ufshcd_put_user_access(hba); \ return ret; \ } \ static DEVICE_ATTR_RO(_name) @@ -1042,24 +1016,20 @@ static ssize_t _name##_show(struct device *dev, \ int ret; \ u8 index = 0; \ \ - down(&hba->host_sem); \ - if (!ufshcd_is_user_access_allowed(hba)) { \ - up(&hba->host_sem); \ - return -EBUSY; \ - } \ + ret = ufshcd_get_user_access(hba); \ + if (ret) \ + return ret; \ if (ufshcd_is_wb_attrs(QUERY_ATTR_IDN##_uname)) \ index = ufshcd_wb_get_query_index(hba); \ - ufshcd_rpm_get_sync(hba); \ ret = ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_READ_ATTR, \ QUERY_ATTR_IDN##_uname, index, 0, &value); \ - ufshcd_rpm_put_sync(hba); \ if (ret) { \ ret = -EINVAL; \ goto out; \ } \ ret = sysfs_emit(buf, "0x%08X\n", value); \ out: \ - up(&hba->host_sem); \ + ufshcd_put_user_access(hba); \ return ret; \ } \ static DEVICE_ATTR_RO(_name) @@ -1195,16 +1165,11 @@ static ssize_t dyn_cap_needed_attribute_show(struct device *dev, u8 lun = ufshcd_scsi_to_upiu_lun(sdev->lun); int ret; - down(&hba->host_sem); - if (!ufshcd_is_user_access_allowed(hba)) { - ret = -EBUSY; - goto out; - } - - ufshcd_rpm_get_sync(hba); + ret = ufshcd_get_user_access(hba); + if (ret) + return ret; ret = ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_READ_ATTR, QUERY_ATTR_IDN_DYN_CAP_NEEDED, lun, 0, &value); - ufshcd_rpm_put_sync(hba); if (ret) { ret = -EINVAL; goto out; @@ -1213,7 +1178,7 @@ static ssize_t dyn_cap_needed_attribute_show(struct device *dev, ret = sysfs_emit(buf, "0x%08X\n", value); out: - up(&hba->host_sem); + ufshcd_put_user_access(hba); return ret; } static DEVICE_ATTR_RO(dyn_cap_needed_attribute); diff --git a/drivers/scsi/ufs/ufs_bsg.c b/drivers/scsi/ufs/ufs_bsg.c index 39bf204..c5b3eb8 100644 --- a/drivers/scsi/ufs/ufs_bsg.c +++ b/drivers/scsi/ufs/ufs_bsg.c @@ -97,7 +97,9 @@ static int ufs_bsg_request(struct bsg_job *job) bsg_reply->reply_payload_rcv_len = 0; - ufshcd_rpm_get_sync(hba); + ret = ufshcd_get_user_access(hba); + if (ret) + goto out; msgcode = bsg_request->msgcode; switch (msgcode) { @@ -105,10 +107,8 @@ static int ufs_bsg_request(struct bsg_job *job) desc_op = bsg_request->upiu_req.qr.opcode; ret = ufs_bsg_alloc_desc_buffer(hba, job, &desc_buff, &desc_len, desc_op); - if (ret) { - ufshcd_rpm_put_sync(hba); - goto out; - } + if (ret) + goto out_put_access; fallthrough; case UPIU_TRANSACTION_NOP_OUT: @@ -138,10 +138,8 @@ static int ufs_bsg_request(struct bsg_job *job) break; } - ufshcd_rpm_put_sync(hba); - if (!desc_buff) - goto out; + goto out_put_access; if (desc_op == UPIU_QUERY_OPCODE_READ_DESC && desc_len) bsg_reply->reply_payload_rcv_len = @@ -151,6 +149,8 @@ static int ufs_bsg_request(struct bsg_job *job) kfree(desc_buff); +out_put_access: + ufshcd_put_user_access(hba); out: bsg_reply->result = ret; job->reply_len = sizeof(struct ufs_bsg_reply); diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 59fc521..8bab3ea 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -128,15 +128,6 @@ enum { UFSHCD_CAN_QUEUE = 32, }; -/* UFSHCD states */ -enum { - UFSHCD_STATE_RESET, - UFSHCD_STATE_ERROR, - UFSHCD_STATE_OPERATIONAL, - UFSHCD_STATE_EH_SCHEDULED_FATAL, - UFSHCD_STATE_EH_SCHEDULED_NON_FATAL, -}; - /* UFSHCD error handling flags */ enum { UFSHCD_EH_IN_PROGRESS = (1 << 0), @@ -254,6 +245,31 @@ static inline void ufshcd_wb_toggle_flush(struct ufs_hba *hba, bool enable); static void ufshcd_hba_vreg_set_lpm(struct ufs_hba *hba); static void ufshcd_hba_vreg_set_hpm(struct ufs_hba *hba); +int ufshcd_get_user_access(struct ufs_hba *hba) +__acquires(&hba->host_sem) +{ + down(&hba->host_sem); + if (!ufshcd_is_user_access_allowed(hba)) { + up(&hba->host_sem); + return -EBUSY; + } + if (ufshcd_rpm_get_sync(hba)) { + ufshcd_rpm_put_sync(hba); + up(&hba->host_sem); + return -EBUSY; + } + return 0; +} +EXPORT_SYMBOL_GPL(ufshcd_get_user_access); + +void ufshcd_put_user_access(struct ufs_hba *hba) +__releases(&hba->host_sem) +{ + ufshcd_rpm_put_sync(hba); + up(&hba->host_sem); +} +EXPORT_SYMBOL_GPL(ufshcd_put_user_access); + static inline bool ufshcd_valid_tag(struct ufs_hba *hba, int tag) { return tag >= 0 && tag < hba->nutrs; @@ -1553,19 +1569,14 @@ static ssize_t ufshcd_clkscale_enable_store(struct device *dev, if (kstrtou32(buf, 0, &value)) return -EINVAL; - down(&hba->host_sem); - if (!ufshcd_is_user_access_allowed(hba)) { - err = -EBUSY; - goto out; - } + err = ufshcd_get_user_access(hba); + if (err) + return err; + ufshcd_hold(hba, false); value = !!value; if (value == hba->clk_scaling.is_enabled) goto out; - - ufshcd_rpm_get_sync(hba); - ufshcd_hold(hba, false); - hba->clk_scaling.is_enabled = value; if (value) { @@ -1578,10 +1589,9 @@ static ssize_t ufshcd_clkscale_enable_store(struct device *dev, __func__, err); } - ufshcd_release(hba); - ufshcd_rpm_put_sync(hba); out: - up(&hba->host_sem); + ufshcd_release(hba); + ufshcd_put_user_access(hba); return err ? err : count; } @@ -4170,13 +4180,13 @@ int ufshcd_uic_hibern8_exit(struct ufs_hba *hba) } EXPORT_SYMBOL_GPL(ufshcd_uic_hibern8_exit); -void ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit) +int ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit) { unsigned long flags; bool update = false; if (!ufshcd_is_auto_hibern8_supported(hba)) - return; + return 0; spin_lock_irqsave(hba->host->host_lock, flags); if (hba->ahit != ahit) { @@ -4187,12 +4197,17 @@ void ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit) if (update && !pm_runtime_suspended(&hba->sdev_ufs_device->sdev_gendev)) { - ufshcd_rpm_get_sync(hba); + if (ufshcd_rpm_get_sync(hba)) { + ufshcd_rpm_put_sync(hba); + return -EBUSY; + } ufshcd_hold(hba, false); ufshcd_auto_hibern8_enable(hba); ufshcd_release(hba); ufshcd_rpm_put_sync(hba); } + + return 0; } EXPORT_SYMBOL_GPL(ufshcd_auto_hibern8_update); diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 1e7fe73..3fc080d 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -101,6 +101,15 @@ struct uic_command { struct completion done; }; +/* UFSHCD states */ +enum { + UFSHCD_STATE_RESET, + UFSHCD_STATE_ERROR, + UFSHCD_STATE_OPERATIONAL, + UFSHCD_STATE_EH_SCHEDULED_FATAL, + UFSHCD_STATE_EH_SCHEDULED_NON_FATAL, +}; + /* Used to differentiate the power management options */ enum ufs_pm_op { UFS_RUNTIME_PM, @@ -935,7 +944,9 @@ static inline bool ufshcd_is_wb_allowed(struct ufs_hba *hba) static inline bool ufshcd_is_user_access_allowed(struct ufs_hba *hba) { - return !hba->shutting_down; + return !hba->shutting_down && !hba->is_sys_suspended && + !hba->is_wlu_sys_suspended && + hba->ufshcd_state == UFSHCD_STATE_OPERATIONAL; } #define ufshcd_writel(hba, val, reg) \ @@ -1108,7 +1119,7 @@ int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode, enum flag_idn idn, u8 index, bool *flag_res); void ufshcd_auto_hibern8_enable(struct ufs_hba *hba); -void ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit); +int ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit); void ufshcd_fixup_dev_quirks(struct ufs_hba *hba, struct ufs_dev_fix *fixups); #define SD_ASCII_STD true #define SD_RAW false @@ -1135,6 +1146,8 @@ int ufshcd_exec_raw_upiu_cmd(struct ufs_hba *hba, int ufshcd_wb_toggle(struct ufs_hba *hba, bool enable); int ufshcd_suspend_prepare(struct device *dev); void ufshcd_resume_complete(struct device *dev); +int ufshcd_get_user_access(struct ufs_hba *hba); +void ufshcd_put_user_access(struct ufs_hba *hba); /* Wrapper functions for safely calling variant operations */ static inline const char *ufshcd_get_var_name(struct ufs_hba *hba)