Skip to content

Commit 3017013

Browse files
lostandy26Christoph Hellwig
authored andcommitted
nvme-rdma: avoid race between time out and tear down
Now use teardown_lock to serialize for time out and tear down. This may cause abnormal: first cancel all request in tear down, then time out may complete the request again, but the request may already be freed or restarted. To avoid race between time out and tear down, in tear down process, first we quiesce the queue, and then delete the timer and cancel the time out work for the queue. At the same time we need to delete teardown_lock. Signed-off-by: Chao Leng <lengchao@huawei.com> Reviewed-by: Sagi Grimberg <sagi@grimberg.me> Signed-off-by: Christoph Hellwig <hch@lst.de>
1 parent 04800fb commit 3017013

1 file changed

Lines changed: 2 additions & 10 deletions

File tree

drivers/nvme/host/rdma.c

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ struct nvme_rdma_ctrl {
122122
struct sockaddr_storage src_addr;
123123

124124
struct nvme_ctrl ctrl;
125-
struct mutex teardown_lock;
126125
bool use_inline_data;
127126
u32 io_queues[HCTX_MAX_TYPES];
128127
};
@@ -1010,8 +1009,8 @@ static int nvme_rdma_configure_io_queues(struct nvme_rdma_ctrl *ctrl, bool new)
10101009
static void nvme_rdma_teardown_admin_queue(struct nvme_rdma_ctrl *ctrl,
10111010
bool remove)
10121011
{
1013-
mutex_lock(&ctrl->teardown_lock);
10141012
blk_mq_quiesce_queue(ctrl->ctrl.admin_q);
1013+
blk_sync_queue(ctrl->ctrl.admin_q);
10151014
nvme_rdma_stop_queue(&ctrl->queues[0]);
10161015
if (ctrl->ctrl.admin_tagset) {
10171016
blk_mq_tagset_busy_iter(ctrl->ctrl.admin_tagset,
@@ -1021,16 +1020,15 @@ static void nvme_rdma_teardown_admin_queue(struct nvme_rdma_ctrl *ctrl,
10211020
if (remove)
10221021
blk_mq_unquiesce_queue(ctrl->ctrl.admin_q);
10231022
nvme_rdma_destroy_admin_queue(ctrl, remove);
1024-
mutex_unlock(&ctrl->teardown_lock);
10251023
}
10261024

10271025
static void nvme_rdma_teardown_io_queues(struct nvme_rdma_ctrl *ctrl,
10281026
bool remove)
10291027
{
1030-
mutex_lock(&ctrl->teardown_lock);
10311028
if (ctrl->ctrl.queue_count > 1) {
10321029
nvme_start_freeze(&ctrl->ctrl);
10331030
nvme_stop_queues(&ctrl->ctrl);
1031+
nvme_sync_io_queues(&ctrl->ctrl);
10341032
nvme_rdma_stop_io_queues(ctrl);
10351033
if (ctrl->ctrl.tagset) {
10361034
blk_mq_tagset_busy_iter(ctrl->ctrl.tagset,
@@ -1041,7 +1039,6 @@ static void nvme_rdma_teardown_io_queues(struct nvme_rdma_ctrl *ctrl,
10411039
nvme_start_queues(&ctrl->ctrl);
10421040
nvme_rdma_destroy_io_queues(ctrl, remove);
10431041
}
1044-
mutex_unlock(&ctrl->teardown_lock);
10451042
}
10461043

10471044
static void nvme_rdma_free_ctrl(struct nvme_ctrl *nctrl)
@@ -1976,16 +1973,12 @@ static void nvme_rdma_complete_timed_out(struct request *rq)
19761973
{
19771974
struct nvme_rdma_request *req = blk_mq_rq_to_pdu(rq);
19781975
struct nvme_rdma_queue *queue = req->queue;
1979-
struct nvme_rdma_ctrl *ctrl = queue->ctrl;
19801976

1981-
/* fence other contexts that may complete the command */
1982-
mutex_lock(&ctrl->teardown_lock);
19831977
nvme_rdma_stop_queue(queue);
19841978
if (!blk_mq_request_completed(rq)) {
19851979
nvme_req(rq)->status = NVME_SC_HOST_ABORTED_CMD;
19861980
blk_mq_complete_request(rq);
19871981
}
1988-
mutex_unlock(&ctrl->teardown_lock);
19891982
}
19901983

19911984
static enum blk_eh_timer_return
@@ -2320,7 +2313,6 @@ static struct nvme_ctrl *nvme_rdma_create_ctrl(struct device *dev,
23202313
return ERR_PTR(-ENOMEM);
23212314
ctrl->ctrl.opts = opts;
23222315
INIT_LIST_HEAD(&ctrl->list);
2323-
mutex_init(&ctrl->teardown_lock);
23242316

23252317
if (!(opts->mask & NVMF_OPT_TRSVCID)) {
23262318
opts->trsvcid =

0 commit comments

Comments
 (0)