Skip to content

Commit 3682212

Browse files
Mason Zhangmartinkpetersen
authored andcommitted
scsi: ufs: core: Fix device management cmd timeout flow
In the UFS error handling flow, the host will send a device management cmd (NOP OUT) to the device for link recovery. If this cmd times out and clearing the doorbell fails, ufshcd_wait_for_dev_cmd() will do nothing and return. hba->dev_cmd.complete struct is not set to NULL. When this happens, if cmd has been completed by device, then we will call complete() in __ufshcd_transfer_req_compl(). Because the complete struct is allocated on the stack, the following crash will occur: ipanic_die+0x24/0x38 [mrdump] die+0x344/0x748 arm64_notify_die+0x44/0x104 do_debug_exception+0x104/0x1e0 el1_dbg+0x38/0x54 el1_sync_handler+0x40/0x88 el1_sync+0x8c/0x140 queued_spin_lock_slowpath+0x2e4/0x3c0 __ufshcd_transfer_req_compl+0x3b0/0x1164 ufshcd_trc_handler+0x15c/0x308 ufshcd_host_reset_and_restore+0x54/0x260 ufshcd_reset_and_restore+0x28c/0x57c ufshcd_err_handler+0xeb8/0x1b6c process_one_work+0x288/0x964 worker_thread+0x4bc/0xc7c kthread+0x15c/0x264 ret_from_fork+0x10/0x30 Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mason Zhang <[email protected]> Reviewed-by: Bart Van Assche <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 32fe452 commit 3682212

File tree

1 file changed

+16
-0
lines changed

1 file changed

+16
-0
lines changed

drivers/ufs/core/ufshcd.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3109,6 +3109,22 @@ static int ufshcd_wait_for_dev_cmd(struct ufs_hba *hba,
31093109
} else {
31103110
dev_err(hba->dev, "%s: failed to clear tag %d\n",
31113111
__func__, lrbp->task_tag);
3112+
3113+
spin_lock_irqsave(&hba->outstanding_lock, flags);
3114+
pending = test_bit(lrbp->task_tag,
3115+
&hba->outstanding_reqs);
3116+
if (pending)
3117+
hba->dev_cmd.complete = NULL;
3118+
spin_unlock_irqrestore(&hba->outstanding_lock, flags);
3119+
3120+
if (!pending) {
3121+
/*
3122+
* The completion handler ran while we tried to
3123+
* clear the command.
3124+
*/
3125+
time_left = 1;
3126+
goto retry;
3127+
}
31123128
}
31133129
}
31143130

0 commit comments

Comments
 (0)