Two fixes for task management request implementation
v5 cover Two fixes for task management request implementation
These fixes are based on Jaegeuk's change - https://git.kernel.org/mkp/scsi/c/eeb1b55b6e25
Change since v4:
- Incorporated Daejun's comments
Change since v3:
- Deleted the 2nd change
- Incorporated Bart's comments
Change since v2:
- Split one change into 3 changes
Change since v1:
- Typo fixed
Can Guo (2):
scsi: ufs: Fix task management request completion timeout
scsi: ufs: Fix wrong Task Tag used in task management request UPIUs
drivers/scsi/ufs/ufshcd.c | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-)
Signature · 1 line
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project.
PATCH v5 1/2 scsi: ufs: Fix task management request completion timeout
ufshcd_tmc_handler() calls blk_mq_tagset_busy_iter(fn = ufshcd_compl_tm()), but since blk_mq_tagset_busy_iter() only iterates over all reserved tags and requests which are not in IDLE state, ufshcd_compl_tm() never gets a chance to run. Thus, TMR always ends up with completion timeout. Fix it by calling blk_mq_start_request() in __ufshcd_issue_tm_cmd().
--- drivers/scsi/ufs/ufshcd.c | 1 + 1 file changed, 1 insertion(+)
drivers/scsi/ufs/ufshcd.c +1 -0
@@ -6464,6 +6464,7 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba,spin_lock_irqsave (host->host_lock, flags); task_tag = hba->nutrs + free_slot; +blk_mq_start_request (req); treq->req_header.dword_0 |=cpu_to_be32 (task_tag);
Signature · 1 line
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project.
Re: [PATCH v5 1/2] scsi: ufs: Fix task management request completion timeout
Quoted 5 lines · Can Guo
ufshcd_tmc_handler()callsblk_mq_tagset_busy_iter(fn = ufshcd_compl_tm()), but sinceblk_mq_tagset_busy_iter()only iterates over all reserved tags and requests which are not in IDLE state,ufshcd_compl_tm()never gets a chance to run. Thus, TMR always ends up with completion timeout. Fix it by callingblk_mq_start_request()in__ufshcd_issue_tm_cmd().
PATCH v5 2/2 scsi: ufs: Fix wrong Task Tag used in task management request UPIUs
In reply to Can GuoIn __ufshcd_issue_tm_cmd(), it is not right to use hba->nutrs + req->tag as the Task Tag in one TMR UPIU. Directly use req->tag as the Task Tag.
--- drivers/scsi/ufs/ufshcd.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-)
drivers/scsi/ufs/ufshcd.c +13 -17
@@ -6446,38 +6446,34 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba,DECLARE_COMPLETION_ONSTACK (wait);struct request *req;unsigned long flags; -int free_slot, task_tag, err; +int task_tag, err;/* -* Get free slot, sleep if slots are unavailable. -* Even though we use wait_event() which sleeps indefinitely, -* the maximum wait time is bounded by %TM_CMD_TIMEOUT. +* blk_get_request() is used here only to get a free tag. */ req =blk_get_request (q,REQ_OP_DRV_OUT ,0 );if (IS_ERR (req))return PTR_ERR (req); req->end_io_data = &wait; - free_slot = req->tag; -WARN_ON_ONCE (free_slot <0 || free_slot >= hba->nutmrs);ufshcd_hold (hba, false);spin_lock_irqsave (host->host_lock, flags); - task_tag = hba->nutrs + free_slot;blk_mq_start_request (req); + task_tag = req->tag; treq->req_header.dword_0 |=cpu_to_be32 (task_tag); -memcpy (hba->utmrdl_base_addr + free_slot, treq,sizeof (*treq)); -ufshcd_vops_setup_task_mgmt (hba, free_slot, tm_function); +memcpy (hba->utmrdl_base_addr + task_tag, treq,sizeof (*treq)); +ufshcd_vops_setup_task_mgmt (hba, task_tag, tm_function);/* send command to the controller */ -__set_bit (free_slot, &hba->outstanding_tasks); +__set_bit (task_tag, &hba->outstanding_tasks);/* Make sure descriptors are ready before ringing the task doorbell */ wmb (); -ufshcd_writel (hba,1 << free_slot,REG_UTP_TASK_REQ_DOOR_BELL ); +ufshcd_writel (hba,1 << task_tag,REG_UTP_TASK_REQ_DOOR_BELL );/* Make sure that doorbell is committed immediately */ wmb ();
@@ -6497,24 +6493,24 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba,ufshcd_add_tm_upiu_trace (hba, task_tag,UFS_TM_ERR );dev_err (hba->dev,"%s: task management cmd 0x%.2x timed-out\n" , __func__, tm_function); -if (ufshcd_clear_tm_cmd (hba, free_slot)) -dev_WARN (hba->dev,"%s: unable clear tm cmd (slot %d) after timeout\n" , - __func__, free_slot); +if (ufshcd_clear_tm_cmd (hba, task_tag)) +dev_WARN (hba->dev,"%s: unable to clear tm cmd (slot %d) after timeout\n" , + __func__, task_tag); err = -ETIMEDOUT ; }else { err =0 ; -memcpy (treq, hba->utmrdl_base_addr + free_slot,sizeof (*treq)); +memcpy (treq, hba->utmrdl_base_addr + task_tag,sizeof (*treq));ufshcd_add_tm_upiu_trace (hba, task_tag,UFS_TM_COMP ); }spin_lock_irqsave (hba->host->host_lock, flags); -__clear_bit (free_slot, &hba->outstanding_tasks); +__clear_bit (task_tag, &hba->outstanding_tasks);spin_unlock_irqrestore (hba->host->host_lock, flags); +ufshcd_release (hba);blk_put_request (req); -ufshcd_release (hba);return err; }
Signature · 1 line
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project.
Martin K. Petersen
AppliedQuoted 10 lines · Can Guo
These fixes are based on Jaegeuk's change - https://git.kernel.org/mkp/scsi/c/eeb1b55b6e25
Change since v4:
- Incorporated Daejun's commentsChange since v3:
- Deleted the 2nd change
- Incorporated Bart's comments[...]
Applied to 5.12/scsi-fixes, thanks!
[1/2] scsi: ufs: Fix task management request completion timeout
https://git.kernel.org/mkp/scsi/c/1235fc569e0b [2/2] scsi: ufs: Fix wrong Task Tag used in task management request UPIUs https://git.kernel.org/mkp/scsi/c/4b42d557a8ad
Signature · 1 line
Martin K. Petersen Oracle Linux Engineering