Patch "scsi: ufs: core: mcq: Fix the incorrect OCS value for the device command" has been added to the 6.4-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    scsi: ufs: core: mcq: Fix the incorrect OCS value for the device command

to the 6.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     scsi-ufs-core-mcq-fix-the-incorrect-ocs-value-for-th.patch
and it can be found in the queue-6.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit d83a8d22264f18cf4f71ecf4336edf9991493fbf
Author: Stanley Chu <stanley.chu@xxxxxxxxxxxx>
Date:   Sat Jun 10 10:15:51 2023 +0800

    scsi: ufs: core: mcq: Fix the incorrect OCS value for the device command
    
    [ Upstream commit 0fef6bb730c490fcdc4347dbd21646d3ffe62cf5 ]
    
    In MCQ mode, when a device command uses a hardware queue shared with other
    commands, a race condition may occur in the following scenario:
    
     1. A device command is completed in CQx with CQE entry "e".
    
     2. The interrupt handler copies the "cqe" pointer to "hba->dev_cmd.cqe"
        and completes "hba->dev_cmd.complete".
    
     3. The "ufshcd_wait_for_dev_cmd()" function is awakened and retrieves the
        OCS value from "hba->dev_cmd.cqe".
    
    However, there is a possibility that the CQE entry "e" will be overwritten
    by newly completed commands in CQx, resulting in an incorrect OCS value
    being received by "ufshcd_wait_for_dev_cmd()".
    
    To avoid this race condition, the OCS value should be immediately copied to
    the struct "lrb" of the device command. Then "ufshcd_wait_for_dev_cmd()"
    can retrieve the OCS value from the struct "lrb".
    
    Fixes: 57b1c0ef89ac ("scsi: ufs: core: mcq: Add support to allocate multiple queues")
    Suggested-by: Can Guo <quic_cang@xxxxxxxxxxx>
    Signed-off-by: Stanley Chu <stanley.chu@xxxxxxxxxxxx>
    Link: https://lore.kernel.org/r/20230610021553.1213-2-powen.kao@xxxxxxxxxxxx
    Tested-by: Po-Wen Kao <powen.kao@xxxxxxxxxxxx>
    Reviewed-by: Bart Van Assche <bvanassche@xxxxxxx>
    Signed-off-by: Martin K. Petersen <martin.petersen@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 41f383b588865..6d8ef80d9cbc4 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -3097,7 +3097,7 @@ static int ufshcd_wait_for_dev_cmd(struct ufs_hba *hba,
 		 * not trigger any race conditions.
 		 */
 		hba->dev_cmd.complete = NULL;
-		err = ufshcd_get_tr_ocs(lrbp, hba->dev_cmd.cqe);
+		err = ufshcd_get_tr_ocs(lrbp, NULL);
 		if (!err)
 			err = ufshcd_dev_cmd_completion(hba, lrbp);
 	} else {
@@ -3184,7 +3184,6 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba,
 		goto out;
 
 	hba->dev_cmd.complete = &wait;
-	hba->dev_cmd.cqe = NULL;
 
 	ufshcd_add_query_upiu_trace(hba, UFS_QUERY_SEND, lrbp->ucd_req_ptr);
 
@@ -5435,6 +5434,7 @@ void ufshcd_compl_one_cqe(struct ufs_hba *hba, int task_tag,
 {
 	struct ufshcd_lrb *lrbp;
 	struct scsi_cmnd *cmd;
+	enum utp_ocs ocs;
 
 	lrbp = &hba->lrb[task_tag];
 	lrbp->compl_time_stamp = ktime_get();
@@ -5450,7 +5450,11 @@ void ufshcd_compl_one_cqe(struct ufs_hba *hba, int task_tag,
 	} else if (lrbp->command_type == UTP_CMD_TYPE_DEV_MANAGE ||
 		   lrbp->command_type == UTP_CMD_TYPE_UFS_STORAGE) {
 		if (hba->dev_cmd.complete) {
-			hba->dev_cmd.cqe = cqe;
+			if (cqe) {
+				ocs = le32_to_cpu(cqe->status) & MASK_OCS;
+				lrbp->utr_descriptor_ptr->header.dword_2 =
+					cpu_to_le32(ocs);
+			}
 			complete(hba->dev_cmd.complete);
 			ufshcd_clk_scaling_update_busy(hba);
 		}
diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h
index df1d04f7a5424..8eecbb3766158 100644
--- a/include/ufs/ufshcd.h
+++ b/include/ufs/ufshcd.h
@@ -225,7 +225,6 @@ struct ufs_dev_cmd {
 	struct mutex lock;
 	struct completion *complete;
 	struct ufs_query query;
-	struct cq_entry *cqe;
 };
 
 /**



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux