Commit 7df0b260 authored by Javed Hasan's avatar Javed Hasan Committed by Martin K. Petersen
Browse files

scsi: qedf: Add synchronization between I/O completions and abort



Avoid race condition between I/O completion and abort processing by
protecting the cmd_type with the rport lock.

Signed-off-by: default avatarJaved Hasan <jhasan@marvell.com>
Signed-off-by: default avatarSaurav Kashyap <skashyap@marvell.com>
Link: https://lore.kernel.org/r/20230901060646.27885-1-skashyap@marvell.com


Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 5c584fe6
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -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);
+6 −1
Original line number Diff line number Diff line
@@ -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;