Commit 8b25f351 authored by James Smart's avatar James Smart Committed by Christoph Hellwig

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: default avatarJames Smart <james.smart@broadcom.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent 2fd4167f
...@@ -1888,7 +1888,7 @@ nvme_fc_start_fcp_op(struct nvme_fc_ctrl *ctrl, struct nvme_fc_queue *queue, ...@@ -1888,7 +1888,7 @@ nvme_fc_start_fcp_op(struct nvme_fc_ctrl *ctrl, struct nvme_fc_queue *queue,
* the target device is present * the target device is present
*/ */
if (ctrl->rport->remoteport.port_state != FC_OBJSTATE_ONLINE) if (ctrl->rport->remoteport.port_state != FC_OBJSTATE_ONLINE)
return BLK_STS_IOERR; goto busy;
if (!nvme_fc_ctrl_get(ctrl)) if (!nvme_fc_ctrl_get(ctrl))
return BLK_STS_IOERR; return BLK_STS_IOERR;
...@@ -1958,22 +1958,25 @@ nvme_fc_start_fcp_op(struct nvme_fc_ctrl *ctrl, struct nvme_fc_queue *queue, ...@@ -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); queue->lldd_handle, &op->fcp_req);
if (ret) { if (ret) {
if (op->rq) /* normal request */ if (!(op->flags & FCOP_FLAGS_AEN))
nvme_fc_unmap_data(ctrl, op->rq, op); nvme_fc_unmap_data(ctrl, op->rq, op);
/* else - aen. no cleanup needed */
nvme_fc_ctrl_put(ctrl); nvme_fc_ctrl_put(ctrl);
if (ret != -EBUSY) if (ctrl->rport->remoteport.port_state == FC_OBJSTATE_ONLINE &&
ret != -EBUSY)
return BLK_STS_IOERR; return BLK_STS_IOERR;
if (op->rq) goto busy;
blk_mq_delay_run_hw_queue(queue->hctx, NVMEFC_QUEUE_DELAY);
return BLK_STS_RESOURCE;
} }
return BLK_STS_OK; 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 static blk_status_t
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment