In SDB mode, a command that times out during a power management operation can be released twice: 1. The command times out while its normal completion is running. 2. The completion path clears BIT(rq->tag) in hba->outstanding_reqs and releases the command. It has not called scsi_done() yet, so SCMD_STATE_COMPLETE is still clear. 3. ufshcd_eh_timed_out() recovers the link, sees SCMD_STATE_COMPLETE clear, clears BIT(rq->tag) in hba->outstanding_reqs without checking whether it was still set, and releases the same command a second time. Return SCSI_EH_DONE when ufshcd_clear_outstanding_reqs() returns 0, as another path has already claimed the command. Fixes: 01d5e237b339 ("scsi: ufs: core: Handle PM commands timeout before SCSI EH") Cc: stable@vger.kernel.org Reviewed-by: Peter Wang Signed-off-by: Stanley Jhu --- drivers/ufs/core/ufshcd.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 68b53f89f8c6..ff5977f7da68 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -9660,12 +9660,10 @@ static enum scsi_timeout_action ufshcd_eh_timed_out(struct scsi_cmnd *scmd) */ if (!test_bit(SCMD_STATE_COMPLETE, &scmd->state)) { if (!hba->mcq_enabled) { - unsigned long flags; struct request *rq = scsi_cmd_to_rq(scmd); - spin_lock_irqsave(&hba->outstanding_lock, flags); - __clear_bit(rq->tag, &hba->outstanding_reqs); - spin_unlock_irqrestore(&hba->outstanding_lock, flags); + if (!ufshcd_clear_outstanding_reqs(hba, BIT(rq->tag))) + return SCSI_EH_DONE; } if (ufshcd_is_scsi_cmd(scmd)) { -- 2.56.0.218.g1ec904b173-goog