diff mbox series

[v2] ufs: core: wlun resume SSU(Acitve) fail recovery

Message ID 20221223084158.10069-1-peter.wang@mediatek.com
State New
Headers show
Series [v2] ufs: core: wlun resume SSU(Acitve) fail recovery | expand

Commit Message

Peter Wang (王信友) Dec. 23, 2022, 8:41 a.m. UTC
From: Peter Wang <peter.wang@mediatek.com>

When wlun resume SSU(Active) timeout, scsi try eh_host_reset_handler.
But ufshcd_eh_host_reset_handler hang at wait flush_work(&hba->eh_work).
And ufshcd_err_handler hang at wait rpm resume.
Do link recovery only in this case. Below is IO hang stack dump.

<ffffffdd78e02b34> schedule+0x110/0x204
<ffffffdd78e0be60> schedule_timeout+0x98/0x138
<ffffffdd78e040e8> wait_for_common_io+0x130/0x2d0
<ffffffdd77d6a000> blk_execute_rq+0x10c/0x16c
<ffffffdd78126d90> __scsi_execute+0xfc/0x278
<ffffffdd7813891c> ufshcd_set_dev_pwr_mode+0x1c8/0x40c
<ffffffdd78137d1c> __ufshcd_wl_resume+0xf0/0x5cc
<ffffffdd78137ae0> ufshcd_wl_runtime_resume+0x40/0x18c
<ffffffdd78136108> scsi_runtime_resume+0x88/0x104
<ffffffdd7809a4f8> __rpm_callback+0x1a0/0xaec
<ffffffdd7809b624> rpm_resume+0x7e0/0xcd0
<ffffffdd7809a788> __rpm_callback+0x430/0xaec
<ffffffdd7809b644> rpm_resume+0x800/0xcd0
<ffffffdd780a0778> pm_runtime_work+0x148/0x198

<ffffffdd78e02b34> schedule+0x110/0x204
<ffffffdd78e0be10> schedule_timeout+0x48/0x138
<ffffffdd78e03d9c> wait_for_common+0x144/0x2dc
<ffffffdd7758bba4> __flush_work+0x3d0/0x508
<ffffffdd7815572c> ufshcd_eh_host_reset_handler+0x134/0x3a8
<ffffffdd781216f4> scsi_try_host_reset+0x54/0x204
<ffffffdd78120594> scsi_eh_ready_devs+0xb30/0xd48
<ffffffdd7812373c> scsi_error_handler+0x260/0x874

<ffffffdd78e02b34> schedule+0x110/0x204
<ffffffdd7809af64> rpm_resume+0x120/0xcd0
<ffffffdd7809fde8> __pm_runtime_resume+0xa0/0x17c
<ffffffdd7815193c> ufshcd_err_handling_prepare+0x40/0x430
<ffffffdd7814cce8> ufshcd_err_handler+0x1c4/0xd4c

Signed-off-by: Peter Wang <peter.wang@mediatek.com>
---
 drivers/ufs/core/ufshcd.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

Comments

kernel test robot Dec. 27, 2022, 5:59 p.m. UTC | #1
Hi,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on jejb-scsi/for-next]
[also build test ERROR on mkp-scsi/for-next linus/master v6.2-rc1 next-20221226]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/peter-wang-mediatek-com/ufs-core-wlun-resume-SSU-Acitve-fail-recovery/20221223-164240
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next
patch link:    https://lore.kernel.org/r/20221223084158.10069-1-peter.wang%40mediatek.com
patch subject: [PATCH v2] ufs: core: wlun resume SSU(Acitve) fail recovery
config: nios2-allyesconfig
compiler: nios2-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/cd4c2e13ebc910bc510ad403cc21cf899e5cb771
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review peter-wang-mediatek-com/ufs-core-wlun-resume-SSU-Acitve-fail-recovery/20221223-164240
        git checkout cd4c2e13ebc910bc510ad403cc21cf899e5cb771
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=nios2 olddefconfig
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=nios2 SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   drivers/ufs/core/ufshcd.c: In function 'ufshcd_eh_host_reset_handler':
>> drivers/ufs/core/ufshcd.c:7377:23: error: 'struct dev_pm_info' has no member named 'runtime_status'
    7377 |         if (dev->power.runtime_status == RPM_RESUMING) {
         |                       ^
   In file included from include/linux/device.h:15,
                    from include/linux/async.h:14,
                    from drivers/ufs/core/ufshcd.c:12:
   drivers/ufs/core/ufshcd.c:7381:43: error: 'struct dev_pm_info' has no member named 'runtime_status'
    7381 |                                 dev->power.runtime_status,
         |                                           ^
   include/linux/dev_printk.h:110:37: note: in definition of macro 'dev_printk_index_wrap'
     110 |                 _p_func(dev, fmt, ##__VA_ARGS__);                       \
         |                                     ^~~~~~~~~~~
   drivers/ufs/core/ufshcd.c:7380:25: note: in expansion of macro 'dev_err'
    7380 |                         dev_err(hba->dev, "WL Device PM: status:%d, err:%d\n",
         |                         ^~~~~~~
>> drivers/ufs/core/ufshcd.c:7382:43: error: 'struct dev_pm_info' has no member named 'runtime_error'
    7382 |                                 dev->power.runtime_error);
         |                                           ^
   include/linux/dev_printk.h:110:37: note: in definition of macro 'dev_printk_index_wrap'
     110 |                 _p_func(dev, fmt, ##__VA_ARGS__);                       \
         |                                     ^~~~~~~~~~~
   drivers/ufs/core/ufshcd.c:7380:25: note: in expansion of macro 'dev_err'
    7380 |                         dev_err(hba->dev, "WL Device PM: status:%d, err:%d\n",
         |                         ^~~~~~~


vim +7377 drivers/ufs/core/ufshcd.c

  7354	
  7355	/**
  7356	 * ufshcd_eh_host_reset_handler - host reset handler registered to scsi layer
  7357	 * @cmd: SCSI command pointer
  7358	 *
  7359	 * Returns SUCCESS/FAILED
  7360	 */
  7361	static int ufshcd_eh_host_reset_handler(struct scsi_cmnd *cmd)
  7362	{
  7363		int err = SUCCESS;
  7364		unsigned long flags;
  7365		struct ufs_hba *hba;
  7366		struct device *dev;
  7367	
  7368		hba = shost_priv(cmd->device->host);
  7369	
  7370		/*
  7371		 * If __ufshcd_wl_suspend get fail and runtime_status = RPM_RESUMING,
  7372		 * do link recovery only. Because schedule eh work will get dead lock
  7373		 * in ufshcd_rpm_get_sync to wait wlun resume, but wlun resume get
  7374		 * error and wait eh work finish.
  7375		 */
  7376		dev = &hba->ufs_device_wlun->sdev_gendev;
> 7377		if (dev->power.runtime_status == RPM_RESUMING) {
  7378			err = ufshcd_link_recovery(hba);
  7379			if (err) {
  7380				dev_err(hba->dev, "WL Device PM: status:%d, err:%d\n",
> 7381					dev->power.runtime_status,
> 7382					dev->power.runtime_error);
  7383			}
  7384			return err;
  7385		}
  7386	
  7387		spin_lock_irqsave(hba->host->host_lock, flags);
  7388		hba->force_reset = true;
  7389		ufshcd_schedule_eh_work(hba);
  7390		dev_err(hba->dev, "%s: reset in progress - 1\n", __func__);
  7391		spin_unlock_irqrestore(hba->host->host_lock, flags);
  7392	
  7393		flush_work(&hba->eh_work);
  7394	
  7395		spin_lock_irqsave(hba->host->host_lock, flags);
  7396		if (hba->ufshcd_state == UFSHCD_STATE_ERROR)
  7397			err = FAILED;
  7398		spin_unlock_irqrestore(hba->host->host_lock, flags);
  7399	
  7400		return err;
  7401	}
  7402
diff mbox series

Patch

diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index e18c9f4463ec..de20cf587fa1 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -7363,9 +7363,27 @@  static int ufshcd_eh_host_reset_handler(struct scsi_cmnd *cmd)
 	int err = SUCCESS;
 	unsigned long flags;
 	struct ufs_hba *hba;
+	struct device *dev;
 
 	hba = shost_priv(cmd->device->host);
 
+	/*
+	 * If __ufshcd_wl_suspend get fail and runtime_status = RPM_RESUMING,
+	 * do link recovery only. Because schedule eh work will get dead lock
+	 * in ufshcd_rpm_get_sync to wait wlun resume, but wlun resume get
+	 * error and wait eh work finish.
+	 */
+	dev = &hba->ufs_device_wlun->sdev_gendev;
+	if (dev->power.runtime_status == RPM_RESUMING) {
+		err = ufshcd_link_recovery(hba);
+		if (err) {
+			dev_err(hba->dev, "WL Device PM: status:%d, err:%d\n",
+				dev->power.runtime_status,
+				dev->power.runtime_error);
+		}
+		return err;
+	}
+
 	spin_lock_irqsave(hba->host->host_lock, flags);
 	hba->force_reset = true;
 	ufshcd_schedule_eh_work(hba);