Commit a5181c89 authored by Alice Chao's avatar Alice Chao Committed by Martin K. Petersen
Browse files

scsi: ufs: core: Fix race between force complete and ISR



While error handler force complete command (Thread A) and completion IRQ
raising (Thread B) of the same command, it may cause race condition.

Below is racing step (from 1 to 6):
	ufshcd_mcq_compl_pending_transfer (Thread A)
1	if (cmd && !test_bit(SCMD_STATE_COMPLETE, &cmd->state)) {
5		spin_lock_irqsave(&hwq->cq_lock, flags);	// wait lock release
		set_host_byte(cmd, DID_REQUEUE);
6		ufshcd_release_scsi_cmd(hba, lrbp);	// access null pointer
		scsi_done(cmd);
		spin_unlock_irqrestore(&hwq->cq_lock, flags);
	}

	ufshcd_mcq_poll_cqe_lock (Thread B)
2	spin_lock_irqsave(&hwq->cq_lock, flags);
	 ufshcd_mcq_poll_cqe_nolock()
	  ufshcd_compl_one_cqe()
3	   ufshcd_release_scsi_cmd()	// lrbp->cmd = NULL;
4	spin_unlock_irqrestore(&hwq->cq_lock, flags);

Signed-off-by: default avatarAlice Chao <alice.chao@mediatek.com>
Link: https://lore.kernel.org/r/20231024084324.12197-1-alice.chao@mediatek.com


Reviewed-by: default avatarBart Van Assche <bvanassche@acm.org>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent f2d79aa1
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -5615,13 +5615,13 @@ static void ufshcd_mcq_compl_pending_transfer(struct ufs_hba *hba,
			 * For those cmds of which the cqes are not present
			 * in the cq, complete them explicitly.
			 */
			if (cmd && !test_bit(SCMD_STATE_COMPLETE, &cmd->state)) {
			spin_lock_irqsave(&hwq->cq_lock, flags);
			if (cmd && !test_bit(SCMD_STATE_COMPLETE, &cmd->state)) {
				set_host_byte(cmd, DID_REQUEUE);
				ufshcd_release_scsi_cmd(hba, lrbp);
				scsi_done(cmd);
				spin_unlock_irqrestore(&hwq->cq_lock, flags);
			}
			spin_unlock_irqrestore(&hwq->cq_lock, flags);
		} else {
			ufshcd_mcq_poll_cqe_lock(hba, hwq);
		}