aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/nvme
diff options
context:
space:
mode:
authorJames Smart <jsmart2021@gmail.com>2017-07-18 17:29:34 -0400
committerChristoph Hellwig <hch@lst.de>2017-07-25 11:58:47 -0400
commit8b25f351929b5a5216ccb2c8882965134019679d (patch)
tree8583abf057bf94ccafe3b5877023bb09ec85c178 /drivers/nvme
parent2fd4167fadd1360ab015e4f0e88e51843e49556c (diff)
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>
Diffstat (limited to 'drivers/nvme')
-rw-r--r--drivers/nvme/host/fc.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c
index d666ada39a9b..5630ca46c3b5 100644
--- a/drivers/nvme/host/fc.c
+++ b/drivers/nvme/host/fc.c
@@ -1888,7 +1888,7 @@ nvme_fc_start_fcp_op(struct nvme_fc_ctrl *ctrl, struct nvme_fc_queue *queue,
1888 * the target device is present 1888 * the target device is present
1889 */ 1889 */
1890 if (ctrl->rport->remoteport.port_state != FC_OBJSTATE_ONLINE) 1890 if (ctrl->rport->remoteport.port_state != FC_OBJSTATE_ONLINE)
1891 return BLK_STS_IOERR; 1891 goto busy;
1892 1892
1893 if (!nvme_fc_ctrl_get(ctrl)) 1893 if (!nvme_fc_ctrl_get(ctrl))
1894 return BLK_STS_IOERR; 1894 return BLK_STS_IOERR;
@@ -1958,22 +1958,25 @@ nvme_fc_start_fcp_op(struct nvme_fc_ctrl *ctrl, struct nvme_fc_queue *queue,
1958 queue->lldd_handle, &op->fcp_req); 1958 queue->lldd_handle, &op->fcp_req);
1959 1959
1960 if (ret) { 1960 if (ret) {
1961 if (op->rq) /* normal request */ 1961 if (!(op->flags & FCOP_FLAGS_AEN))
1962 nvme_fc_unmap_data(ctrl, op->rq, op); 1962 nvme_fc_unmap_data(ctrl, op->rq, op);
1963 /* else - aen. no cleanup needed */
1964 1963
1965 nvme_fc_ctrl_put(ctrl); 1964 nvme_fc_ctrl_put(ctrl);
1966 1965
1967 if (ret != -EBUSY) 1966 if (ctrl->rport->remoteport.port_state == FC_OBJSTATE_ONLINE &&
1967 ret != -EBUSY)
1968 return BLK_STS_IOERR; 1968 return BLK_STS_IOERR;
1969 1969
1970 if (op->rq) 1970 goto busy;
1971 blk_mq_delay_run_hw_queue(queue->hctx, NVMEFC_QUEUE_DELAY);
1972
1973 return BLK_STS_RESOURCE;
1974 } 1971 }
1975 1972
1976 return BLK_STS_OK; 1973 return BLK_STS_OK;
1974
1975busy:
1976 if (!(op->flags & FCOP_FLAGS_AEN) && queue->hctx)
1977 blk_mq_delay_run_hw_queue(queue->hctx, NVMEFC_QUEUE_DELAY);
1978
1979 return BLK_STS_RESOURCE;
1977} 1980}
1978 1981
1979static blk_status_t 1982static blk_status_t