summaryrefslogtreecommitdiff
path: root/drivers/scsi
diff options
context:
space:
mode:
authorChad Dupuis <chad.dupuis@cavium.com>2018-04-25 06:09:01 -0700
committerMartin K. Petersen <martin.petersen@oracle.com>2018-05-08 00:57:11 -0400
commit92bbccdf72ae7f605dbbae050e92dda8971c592d (patch)
tree277c29a769477e4420ef7c7ad346756382732a62 /drivers/scsi
parent96673e1e224c8ecb44effc5aaf32455456b7c3e9 (diff)
downloadlwn-92bbccdf72ae7f605dbbae050e92dda8971c592d.tar.gz
lwn-92bbccdf72ae7f605dbbae050e92dda8971c592d.zip
scsi: qedf: Add additional checks when restarting an rport due to ABTS timeout
There are a couple of kernel cases when we restart a remote port due to ABTS timeout that we need to handle: 1. Flush any outstanding ABTS requests when flushing I/Os so that we do not hold up the eh_abort handler indefinitely causing process hangs. 2. Check if we are currently uploading a connection before issuing an ABTS. Signed-off-by: Chad Dupuis <chad.dupuis@cavium.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/qedf/qedf_io.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/scsi/qedf/qedf_io.c b/drivers/scsi/qedf/qedf_io.c
index 589414f06376..f669df03f37d 100644
--- a/drivers/scsi/qedf/qedf_io.c
+++ b/drivers/scsi/qedf/qedf_io.c
@@ -1457,6 +1457,31 @@ void qedf_flush_active_ios(struct qedf_rport *fcport, int lun)
goto free_cmd;
}
+ if (io_req->cmd_type == QEDF_ABTS) {
+ rc = kref_get_unless_zero(&io_req->refcount);
+ if (!rc) {
+ QEDF_ERR(&(qedf->dbg_ctx),
+ "Could not get kref for abort io_req=0x%p xid=0x%x.\n",
+ io_req, io_req->xid);
+ continue;
+ }
+ QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO,
+ "Flushing abort xid=0x%x.\n", io_req->xid);
+
+ clear_bit(QEDF_CMD_IN_ABORT, &io_req->flags);
+
+ if (io_req->sc_cmd) {
+ if (io_req->return_scsi_cmd_on_abts)
+ qedf_scsi_done(qedf, io_req, DID_ERROR);
+ }
+
+ /* Notify eh_abort handler that ABTS is complete */
+ complete(&io_req->abts_done);
+ kref_put(&io_req->refcount, qedf_release_cmd);
+
+ goto free_cmd;
+ }
+
if (!io_req->sc_cmd)
continue;
if (lun > 0) {
@@ -1534,6 +1559,11 @@ int qedf_initiate_abts(struct qedf_ioreq *io_req, bool return_scsi_cmd_on_abts)
goto abts_err;
}
+ if (test_bit(QEDF_RPORT_UPLOADING_CONNECTION, &fcport->flags)) {
+ QEDF_ERR(&qedf->dbg_ctx, "fcport is uploading.\n");
+ rc = 1;
+ goto out;
+ }
kref_get(&io_req->refcount);
@@ -1573,6 +1603,7 @@ abts_err:
* task at the firmware.
*/
qedf_initiate_cleanup(io_req, return_scsi_cmd_on_abts);
+out:
return rc;
}