From 96a8c322bc50883926415d453cbe7fca09bbc68b Mon Sep 17 00:00:00 2001
From: Thomas Abraham <tabraham@suse.com>
Date: Sep 29 2023 15:08:50 +0000
Subject: scsi: qedf: Add synchronization between I/O completions and

abort (bsc#1210658).

---

diff --git a/patches.suse/scsi-qedf-Add-synchronization-between-I-O-completion.patch b/patches.suse/scsi-qedf-Add-synchronization-between-I-O-completion.patch
new file mode 100644
index 0000000..bc18474
--- /dev/null
+++ b/patches.suse/scsi-qedf-Add-synchronization-between-I-O-completion.patch
@@ -0,0 +1,99 @@
+From 7df0b2605489bef3f4223ad66f1f9bb8d50d4cd2 Mon Sep 17 00:00:00 2001
+From: Javed Hasan <jhasan@marvell.com>
+Date: Fri, 1 Sep 2023 11:36:46 +0530
+Subject: [PATCH] scsi: qedf: Add synchronization between I/O completions and
+ abort
+References: bsc#1210658
+Git-commit: 7df0b2605489bef3f4223ad66f1f9bb8d50d4cd2
+Patch-mainline: v6.6-rc2
+
+Avoid race condition between I/O completion and abort processing by
+protecting the cmd_type with the rport lock.
+
+Signed-off-by: Javed Hasan <jhasan@marvell.com>
+Signed-off-by: Saurav Kashyap <skashyap@marvell.com>
+Link: https://lore.kernel.org/r/20230901060646.27885-1-skashyap@marvell.com
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Thomas Abraham <tabraham@suse.com>
+---
+ drivers/scsi/qedf/qedf_io.c   | 10 ++++++++--
+ drivers/scsi/qedf/qedf_main.c |  7 ++++++-
+ 2 files changed, 14 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/scsi/qedf/qedf_io.c b/drivers/scsi/qedf/qedf_io.c
+index 4750ec5789a8..10fe3383855c 100644
+--- a/drivers/scsi/qedf/qedf_io.c
++++ b/drivers/scsi/qedf/qedf_io.c
+@@ -1904,6 +1904,7 @@ int qedf_initiate_abts(struct qedf_ioreq *io_req, bool return_scsi_cmd_on_abts)
+ 		goto drop_rdata_kref;
+ 	}
+ 
++	spin_lock_irqsave(&fcport->rport_lock, flags);
+ 	if (!test_bit(QEDF_CMD_OUTSTANDING, &io_req->flags) ||
+ 	    test_bit(QEDF_CMD_IN_CLEANUP, &io_req->flags) ||
+ 	    test_bit(QEDF_CMD_IN_ABORT, &io_req->flags)) {
+@@ -1911,17 +1912,20 @@ int qedf_initiate_abts(struct qedf_ioreq *io_req, bool return_scsi_cmd_on_abts)
+ 			 "io_req xid=0x%x sc_cmd=%p already in cleanup or abort processing or already completed.\n",
+ 			 io_req->xid, io_req->sc_cmd);
+ 		rc = 1;
++		spin_unlock_irqrestore(&fcport->rport_lock, flags);
+ 		goto drop_rdata_kref;
+ 	}
+ 
++	/* Set the command type to abort */
++	io_req->cmd_type = QEDF_ABTS;
++	spin_unlock_irqrestore(&fcport->rport_lock, flags);
++
+ 	kref_get(&io_req->refcount);
+ 
+ 	xid = io_req->xid;
+ 	qedf->control_requests++;
+ 	qedf->packet_aborts++;
+ 
+-	/* Set the command type to abort */
+-	io_req->cmd_type = QEDF_ABTS;
+ 	io_req->return_scsi_cmd_on_abts = return_scsi_cmd_on_abts;
+ 
+ 	set_bit(QEDF_CMD_IN_ABORT, &io_req->flags);
+@@ -2210,7 +2214,9 @@ int qedf_initiate_cleanup(struct qedf_ioreq *io_req,
+ 		  refcount, fcport, fcport->rdata->ids.port_id);
+ 
+ 	/* Cleanup cmds re-use the same TID as the original I/O */
++	spin_lock_irqsave(&fcport->rport_lock, flags);
+ 	io_req->cmd_type = QEDF_CLEANUP;
++	spin_unlock_irqrestore(&fcport->rport_lock, flags);
+ 	io_req->return_scsi_cmd_on_abts = return_scsi_cmd_on_abts;
+ 
+ 	init_completion(&io_req->cleanup_done);
+diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c
+index 7825765c936c..91f3f1d7098e 100644
+--- a/drivers/scsi/qedf/qedf_main.c
++++ b/drivers/scsi/qedf/qedf_main.c
+@@ -2805,6 +2805,8 @@ void qedf_process_cqe(struct qedf_ctx *qedf, struct fcoe_cqe *cqe)
+ 	struct qedf_ioreq *io_req;
+ 	struct qedf_rport *fcport;
+ 	u32 comp_type;
++	u8 io_comp_type;
++	unsigned long flags;
+ 
+ 	comp_type = (cqe->cqe_data >> FCOE_CQE_CQE_TYPE_SHIFT) &
+ 	    FCOE_CQE_CQE_TYPE_MASK;
+@@ -2838,11 +2840,14 @@ void qedf_process_cqe(struct qedf_ctx *qedf, struct fcoe_cqe *cqe)
+ 		return;
+ 	}
+ 
++	spin_lock_irqsave(&fcport->rport_lock, flags);
++	io_comp_type = io_req->cmd_type;
++	spin_unlock_irqrestore(&fcport->rport_lock, flags);
+ 
+ 	switch (comp_type) {
+ 	case FCOE_GOOD_COMPLETION_CQE_TYPE:
+ 		atomic_inc(&fcport->free_sqes);
+-		switch (io_req->cmd_type) {
++		switch (io_comp_type) {
+ 		case QEDF_SCSI_CMD:
+ 			qedf_scsi_completion(qedf, cqe, io_req);
+ 			break;
+-- 
+2.35.3
+
diff --git a/series.conf b/series.conf
index da04dbf..a1a4109 100644
--- a/series.conf
+++ b/series.conf
@@ -22342,6 +22342,7 @@
 	patches.suse/ata-libata-disallow-dev-initiated-LPM-transitions-to.patch
 	patches.suse/scsi-qla2xxx-Use-raw_smp_processor_id-instead-of-smp.patch
 	patches.suse/scsi-qla2xxx-Fix-NULL-vs-IS_ERR-bug-for-debugfs_crea.patch
+	patches.suse/scsi-qedf-Add-synchronization-between-I-O-completion.patch
 	patches.suse/scsi-lpfc-Fix-the-NULL-vs-IS_ERR-bug-for-debugfs_cre.patch
 	patches.suse/scsi-lpfc-Early-return-after-marking-final-NLP_DROPP.patch
 	patches.suse/scsi-lpfc-Prevent-use-after-free-during-rmmod-with-m.patch