nvme-fc: address target disconnect race conditions in fcp io submit

There are cases where threads are in the process of submitting new
io when the LLDD calls in to remove the remote port. In some cases,
the next io actually goes to the LLDD, who knows the remoteport isn't
present and rejects it. To properly recovery/restart these i/o's we
don't want to hard fail them, we want to treat them as temporary
resource errors in which a delayed retry will work.

Add a couple more checks on remoteport connectivity and commonize the
busy response handling when it's seen.

Signed-off-by: James Smart <james.smart@broadcom.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
James Smart 2017-07-18 14:29:34 -07:00 committed by Christoph Hellwig
parent 2fd4167fad
commit 8b25f35192

View File

@ -1888,7 +1888,7 @@ nvme_fc_start_fcp_op(struct nvme_fc_ctrl *ctrl, struct nvme_fc_queue *queue,
* the target device is present
*/
if (ctrl->rport->remoteport.port_state != FC_OBJSTATE_ONLINE)
return BLK_STS_IOERR;
goto busy;
if (!nvme_fc_ctrl_get(ctrl))
return BLK_STS_IOERR;
@ -1958,22 +1958,25 @@ nvme_fc_start_fcp_op(struct nvme_fc_ctrl *ctrl, struct nvme_fc_queue *queue,
queue->lldd_handle, &op->fcp_req);
if (ret) {
if (op->rq) /* normal request */
if (!(op->flags & FCOP_FLAGS_AEN))
nvme_fc_unmap_data(ctrl, op->rq, op);
/* else - aen. no cleanup needed */
nvme_fc_ctrl_put(ctrl);
if (ret != -EBUSY)
if (ctrl->rport->remoteport.port_state == FC_OBJSTATE_ONLINE &&
ret != -EBUSY)
return BLK_STS_IOERR;
if (op->rq)
blk_mq_delay_run_hw_queue(queue->hctx, NVMEFC_QUEUE_DELAY);
return BLK_STS_RESOURCE;
goto busy;
}
return BLK_STS_OK;
busy:
if (!(op->flags & FCOP_FLAGS_AEN) && queue->hctx)
blk_mq_delay_run_hw_queue(queue->hctx, NVMEFC_QUEUE_DELAY);
return BLK_STS_RESOURCE;
}
static blk_status_t