Skip to content

Commit

Permalink
scsi: qedf: Add additional checks when restarting an rport due to ABT…
Browse files Browse the repository at this point in the history
…S 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 <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
  • Loading branch information
Chad Dupuis authored and martinkpetersen committed May 8, 2018
1 parent 96673e1 commit 92bbccd
Showing 1 changed file with 31 additions and 0 deletions.
31 changes: 31 additions & 0 deletions drivers/scsi/qedf/qedf_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -1573,6 +1603,7 @@ int qedf_initiate_abts(struct qedf_ioreq *io_req, bool return_scsi_cmd_on_abts)
* task at the firmware.
*/
qedf_initiate_cleanup(io_req, return_scsi_cmd_on_abts);
out:
return rc;
}

Expand Down

0 comments on commit 92bbccd

Please sign in to comment.