scsi: qedf: Add synchronization between I/O completions and abort
[ Upstream commit 7df0b2605489bef3f4223ad66f1f9bb8d50d4cd2 ] 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: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
655e9d209c
commit
843348f9e4
@ -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);
|
||||
|
@ -2807,6 +2807,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;
|
||||
@ -2840,11 +2842,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;
|
||||
|
Loading…
Reference in New Issue
Block a user