From bd65b2faea02018cd715508a449acd11056029e0 Mon Sep 17 00:00:00 2001 From: Maurizio Lombardi Date: Tue, 9 May 2023 18:14:11 +0200 Subject: [PATCH] nvme: do not remove the ctrl until it's fully initialized --- drivers/nvme/host/core.c | 7 ++++++- drivers/nvme/host/fc.c | 4 ++++ drivers/nvme/host/nvme.h | 1 + drivers/nvme/host/rdma.c | 3 +++ drivers/nvme/host/tcp.c | 3 +++ drivers/nvme/target/loop.c | 3 +++ 6 files changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index a099257753c4..451f23d664b1 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -244,8 +244,12 @@ static void nvme_delete_ctrl_sync(struct nvme_ctrl *ctrl) * since ->delete_ctrl can free the controller. */ nvme_get_ctrl(ctrl); - if (nvme_change_ctrl_state(ctrl, NVME_CTRL_DELETING)) + wait_for_completion(&ctrl->first_init_comp); + if (nvme_change_ctrl_state(ctrl, NVME_CTRL_DELETING) && + test_bit(NVME_CTRL_STARTED_ONCE, + &ctrl->flags)) { nvme_do_delete_ctrl(ctrl); + } nvme_put_ctrl(ctrl); } @@ -5145,6 +5149,7 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev, INIT_WORK(&ctrl->fw_act_work, nvme_fw_act_work); INIT_WORK(&ctrl->delete_work, nvme_delete_ctrl_work); init_waitqueue_head(&ctrl->state_wq); + init_completion(&ctrl->first_init_comp); INIT_DELAYED_WORK(&ctrl->ka_work, nvme_keep_alive_work); INIT_DELAYED_WORK(&ctrl->failfast_work, nvme_failfast_work); diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index 456ee42a6133..a7fb6a50dfd4 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c @@ -3565,6 +3565,8 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, "NVME-FC{%d}: new ctrl: NQN \"%s\"\n", ctrl->cnum, nvmf_ctrl_subsysnqn(&ctrl->ctrl)); + complete_all(&ctrl->ctrl.first_init_comp); + return &ctrl->ctrl; fail_ctrl: @@ -3578,6 +3580,8 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, /* initiate nvme ctrl ref counting teardown */ nvme_uninit_ctrl(&ctrl->ctrl); + complete_all(&ctrl->ctrl.first_init_comp); + /* Remove core ctrl ref. */ nvme_put_ctrl(&ctrl->ctrl); diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index 6d6e4366ec2f..a486fd5e1fa6 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -325,6 +325,7 @@ struct nvme_ctrl { struct delayed_work failfast_work; struct nvme_command ka_cmd; struct work_struct fw_act_work; + struct completion first_init_comp; unsigned long events; #ifdef CONFIG_NVME_MULTIPATH diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c index bbad26b82b56..928f26f33f89 100644 --- a/drivers/nvme/host/rdma.c +++ b/drivers/nvme/host/rdma.c @@ -2366,10 +2366,13 @@ static struct nvme_ctrl *nvme_rdma_create_ctrl(struct device *dev, list_add_tail(&ctrl->list, &nvme_rdma_ctrl_list); mutex_unlock(&nvme_rdma_ctrl_mutex); + complete_all(&ctrl->ctrl.first_init_comp); + return &ctrl->ctrl; out_uninit_ctrl: nvme_uninit_ctrl(&ctrl->ctrl); + complete_all(&ctrl->ctrl.first_init_comp); nvme_put_ctrl(&ctrl->ctrl); if (ret > 0) ret = -EIO; diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index e3ede7d56701..4e99ca21680b 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -2662,10 +2662,13 @@ static struct nvme_ctrl *nvme_tcp_create_ctrl(struct device *dev, list_add_tail(&ctrl->list, &nvme_tcp_ctrl_list); mutex_unlock(&nvme_tcp_ctrl_mutex); + complete_all(&ctrl->ctrl.first_init_comp); + return &ctrl->ctrl; out_uninit_ctrl: nvme_uninit_ctrl(&ctrl->ctrl); + complete_all(&ctrl->ctrl.first_init_comp); nvme_put_ctrl(&ctrl->ctrl); if (ret > 0) ret = -EIO; diff --git a/drivers/nvme/target/loop.c b/drivers/nvme/target/loop.c index f2d24b2d992f..223a15a3e306 100644 --- a/drivers/nvme/target/loop.c +++ b/drivers/nvme/target/loop.c @@ -597,6 +597,8 @@ static struct nvme_ctrl *nvme_loop_create_ctrl(struct device *dev, nvme_start_ctrl(&ctrl->ctrl); + complete_all(&ctrl->ctrl.first_init_comp); + return &ctrl->ctrl; out_remove_admin_queue: @@ -605,6 +607,7 @@ static struct nvme_ctrl *nvme_loop_create_ctrl(struct device *dev, kfree(ctrl->queues); out_uninit_ctrl: nvme_uninit_ctrl(&ctrl->ctrl); + complete_all(&ctrl->ctrl.first_init_comp); nvme_put_ctrl(&ctrl->ctrl); out: if (ret > 0) -- 2.31.1