diff mbox series

[v1] scsi: ufs: core: fix racing issue during ufshcd_mcq_abort

Message ID 20231113112935.16343-1-hy50.seo@samsung.com (mailing list archive)
State Superseded
Headers show
Series [v1] scsi: ufs: core: fix racing issue during ufshcd_mcq_abort | expand

Commit Message

SEO HOYOUNG Nov. 13, 2023, 11:29 a.m. UTC
If cq complete irq raise during abort processing,
the command has already been complete.
So could not get utag to erase cmd like below log.
Because the cmd that was handling abort has already been completed

ufshcd_try_to_abort_task: cmd pending in the device. tag = 25
Unable to handle kernel NULL pointer dereference at virtual address
0000000000000194
Mem abort info:
ESR = 0x0000000096000006
EC = 0x25: DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
FSC = 0x06: level 2 translation fault
Data abort info:
ISV = 0, ISS = 0x00000006
CM = 0, WnR = 0

pc : blk_mq_unique_tag+0x8/0x14
lr : ufshcd_mcq_sq_cleanup+0x6c/0x1b8
Call trace:
blk_mq_unique_tag+0x8/0x14
ufshcd_clear_cmd+0x34/0x118
ufshcd_try_to_abort_task+0x1c4/0x4b0
ufshcd_err_handler+0x8d0/0xd24
process_one_work+0x1e4/0x43c
worker_thread+0x25c/0x430
kthread+0x104/0x1d4
ret_from_fork+0x10/0x20

Signed-off-by: SEO HOYOUNG <hy50.seo@samsung.com>
---
 drivers/ufs/core/ufshcd.c | 4 ++++
 1 file changed, 4 insertions(+)

Comments

kernel test robot Nov. 13, 2023, 3:37 p.m. UTC | #1
Hi SEO,

kernel test robot noticed the following build errors:

[auto build test ERROR on jejb-scsi/for-next]
[also build test ERROR on mkp-scsi/for-next linus/master v6.7-rc1 next-20231113]
[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/SEO-HOYOUNG/scsi-ufs-core-fix-racing-issue-during-ufshcd_mcq_abort/20231113-194433
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next
patch link:    https://lore.kernel.org/r/20231113112935.16343-1-hy50.seo%40samsung.com
patch subject: [PATCH v1] scsi: ufs: core: fix racing issue during ufshcd_mcq_abort
config: arc-randconfig-001-20231113 (https://download.01.org/0day-ci/archive/20231113/202311132304.bqVcJ27s-lkp@intel.com/config)
compiler: arceb-elf-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231113/202311132304.bqVcJ27s-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202311132304.bqVcJ27s-lkp@intel.com/

All errors (new ones prefixed by >>):

   drivers/ufs/core/ufshcd.c: In function 'ufshcd_try_to_abort_task':
>> drivers/ufs/core/ufshcd.c:7571:34: error: 'cmd' undeclared (first use in this function)
    7571 |         if (!ufshcd_cmd_inflight(cmd) ||
         |                                  ^~~
   drivers/ufs/core/ufshcd.c:7571:34: note: each undeclared identifier is reported only once for each function it appears in


vim +/cmd +7571 drivers/ufs/core/ufshcd.c

  7484	
  7485	/**
  7486	 * ufshcd_try_to_abort_task - abort a specific task
  7487	 * @hba: Pointer to adapter instance
  7488	 * @tag: Task tag/index to be aborted
  7489	 *
  7490	 * Abort the pending command in device by sending UFS_ABORT_TASK task management
  7491	 * command, and in host controller by clearing the door-bell register. There can
  7492	 * be race between controller sending the command to the device while abort is
  7493	 * issued. To avoid that, first issue UFS_QUERY_TASK to check if the command is
  7494	 * really issued and then try to abort it.
  7495	 *
  7496	 * Return: zero on success, non-zero on failure.
  7497	 */
  7498	int ufshcd_try_to_abort_task(struct ufs_hba *hba, int tag)
  7499	{
  7500		struct ufshcd_lrb *lrbp = &hba->lrb[tag];
  7501		int err = 0;
  7502		int poll_cnt;
  7503		u8 resp = 0xF;
  7504		u32 reg;
  7505	
  7506		for (poll_cnt = 100; poll_cnt; poll_cnt--) {
  7507			err = ufshcd_issue_tm_cmd(hba, lrbp->lun, lrbp->task_tag,
  7508					UFS_QUERY_TASK, &resp);
  7509			if (!err && resp == UPIU_TASK_MANAGEMENT_FUNC_SUCCEEDED) {
  7510				/* cmd pending in the device */
  7511				dev_err(hba->dev, "%s: cmd pending in the device. tag = %d\n",
  7512					__func__, tag);
  7513				break;
  7514			} else if (!err && resp == UPIU_TASK_MANAGEMENT_FUNC_COMPL) {
  7515				/*
  7516				 * cmd not pending in the device, check if it is
  7517				 * in transition.
  7518				 */
  7519				dev_err(hba->dev, "%s: cmd at tag %d not pending in the device.\n",
  7520					__func__, tag);
  7521				if (is_mcq_enabled(hba)) {
  7522					/* MCQ mode */
  7523					if (ufshcd_cmd_inflight(lrbp->cmd)) {
  7524						/* sleep for max. 200us same delay as in SDB mode */
  7525						usleep_range(100, 200);
  7526						continue;
  7527					}
  7528					/* command completed already */
  7529					dev_err(hba->dev, "%s: cmd at tag=%d is cleared.\n",
  7530						__func__, tag);
  7531					goto out;
  7532				}
  7533	
  7534				/* Single Doorbell Mode */
  7535				reg = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL);
  7536				if (reg & (1 << tag)) {
  7537					/* sleep for max. 200us to stabilize */
  7538					usleep_range(100, 200);
  7539					continue;
  7540				}
  7541				/* command completed already */
  7542				dev_err(hba->dev, "%s: cmd at tag %d successfully cleared from DB.\n",
  7543					__func__, tag);
  7544				goto out;
  7545			} else {
  7546				dev_err(hba->dev,
  7547					"%s: no response from device. tag = %d, err %d\n",
  7548					__func__, tag, err);
  7549				if (!err)
  7550					err = resp; /* service response error */
  7551				goto out;
  7552			}
  7553		}
  7554	
  7555		if (!poll_cnt) {
  7556			err = -EBUSY;
  7557			goto out;
  7558		}
  7559	
  7560		err = ufshcd_issue_tm_cmd(hba, lrbp->lun, lrbp->task_tag,
  7561				UFS_ABORT_TASK, &resp);
  7562		if (err || resp != UPIU_TASK_MANAGEMENT_FUNC_COMPL) {
  7563			if (!err) {
  7564				err = resp; /* service response error */
  7565				dev_err(hba->dev, "%s: issued. tag = %d, err %d\n",
  7566					__func__, tag, err);
  7567			}
  7568			goto out;
  7569		}
  7570	
> 7571		if (!ufshcd_cmd_inflight(cmd) ||
  7572		    test_bit(SCMD_STATE_COMPLETE, &cmd->state))
  7573			goto out;
  7574	
  7575		err = ufshcd_clear_cmd(hba, tag);
  7576		if (err)
  7577			dev_err(hba->dev, "%s: Failed clearing cmd at tag %d, err %d\n",
  7578				__func__, tag, err);
  7579	
  7580	out:
  7581		return err;
  7582	}
  7583
diff mbox series

Patch

diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 9a730a794b66..1a58869b91fc 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -7574,6 +7574,10 @@  int ufshcd_try_to_abort_task(struct ufs_hba *hba, int tag)
 		goto out;
 	}
 
+	if (!ufshcd_cmd_inflight(cmd) ||
+	    test_bit(SCMD_STATE_COMPLETE, &cmd->state))
+		goto out;
+
 	err = ufshcd_clear_cmd(hba, tag);
 	if (err)
 		dev_err(hba->dev, "%s: Failed clearing cmd at tag %d, err %d\n",