diff options
author | Chad Dupuis <chad.dupuis@cavium.com> | 2018-04-25 06:09:03 -0700 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2018-05-08 00:57:11 -0400 |
commit | f3690a89f918031a5eed17da78af51c329efe93a (patch) | |
tree | ea976faae5dcab27e73c177653f73c291d1509e6 /drivers/scsi/qedf/qedf_main.c | |
parent | 4f4616ceebaf045c59e8a6aa01f08826d18d5c63 (diff) |
scsi: qedf: Add more defensive checks for concurrent error conditions
During an uplink toggle test all error handling is done via timeout and
firmware error conditions which can occur concurrently:
- SCSI layer timeouts
- Error detect CQEs
- Firmware detected underruns
- ABTS timeouts
All these concurrent events require more defensive checks in the driver
including:
- Check both internally and externally generated aborts to make sure the
xid is not already been aborted in another context or in cleanup.
- Check back pointers in qedf_cmd_timeout to verify the context of the
io_req, fcport and qedf_ctx
- Check rport state in host reset handler to not reset the whole host
if the rport is already uploaded or in the process of relogin
- Check to state for an fcport before initiating a middle path ELS
request
Signed-off-by: Chad Dupuis <chad.dupuis@cavium.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/qedf/qedf_main.c')
-rw-r--r-- | drivers/scsi/qedf/qedf_main.c | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c index 5f9ae6e9897e..7e88c7a41a01 100644 --- a/drivers/scsi/qedf/qedf_main.c +++ b/drivers/scsi/qedf/qedf_main.c @@ -643,16 +643,6 @@ static int qedf_eh_abort(struct scsi_cmnd *sc_cmd) goto out; } - 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)) { - QEDF_ERR(&(qedf->dbg_ctx), "io_req xid=0x%x already in " - "cleanup or abort processing or already " - "completed.\n", io_req->xid); - rc = SUCCESS; - goto out; - } - QEDF_ERR(&(qedf->dbg_ctx), "Aborting io_req sc_cmd=%p xid=0x%x " "fp_idx=%d.\n", sc_cmd, io_req->xid, io_req->fp_idx); @@ -748,6 +738,22 @@ static int qedf_eh_host_reset(struct scsi_cmnd *sc_cmd) { struct fc_lport *lport; struct qedf_ctx *qedf; + struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device)); + struct fc_rport_libfc_priv *rp = rport->dd_data; + struct qedf_rport *fcport = (struct qedf_rport *)&rp[1]; + int rval; + + rval = fc_remote_port_chkready(rport); + + if (rval) { + QEDF_ERR(NULL, "device_reset rport not ready\n"); + return FAILED; + } + + if (fcport == NULL) { + QEDF_ERR(NULL, "device_reset: rport is NULL\n"); + return FAILED; + } lport = shost_priv(sc_cmd->device->host); qedf = lport_priv(lport); |