When driver confirms that the controller is dead, this controller should be deleted with marking as DEAD. Otherwise, upper layer may wait forever in __bio_queue_enter() since the disk won't be marked as DEAD. Especially, in del_gendisk(), disk won't be marked as DEAD unless bdev sync & invalidate returns. If any writeback IO waits in __bio_queue_enter(), IO deadlock is caused. Add nvme_delete_dead_ctrl() for avoiding such kind of io deadlock. Signed-off-by: Ming Lei <ming.lei@xxxxxxxxxx> --- drivers/nvme/host/core.c | 24 +++++++++++++++++++++++- drivers/nvme/host/nvme.h | 1 + 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index ccb6eb1282f8..413213cfa417 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -227,16 +227,38 @@ static void nvme_delete_ctrl_work(struct work_struct *work) nvme_do_delete_ctrl(ctrl); } -int nvme_delete_ctrl(struct nvme_ctrl *ctrl) +static int __nvme_delete_ctrl(struct nvme_ctrl *ctrl, + enum nvme_ctrl_state state) { + if (state != NVME_CTRL_DELETING && state != NVME_CTRL_DEAD) + return -EINVAL; + if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_DELETING)) return -EBUSY; + if (state == NVME_CTRL_DEAD) { + if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_DEAD)) + return -EBUSY; + } if (!queue_work(nvme_delete_wq, &ctrl->delete_work)) return -EBUSY; return 0; } + +int nvme_delete_ctrl(struct nvme_ctrl *ctrl) +{ + return __nvme_delete_ctrl(ctrl, NVME_CTRL_DELETING); +} EXPORT_SYMBOL_GPL(nvme_delete_ctrl); +/* + * Called when driver confirmed that the controller is really dead + */ +int nvme_delete_dead_ctrl(struct nvme_ctrl *ctrl) +{ + return __nvme_delete_ctrl(ctrl, NVME_CTRL_DEAD); +} +EXPORT_SYMBOL_GPL(nvme_delete_dead_ctrl); + static void nvme_delete_ctrl_sync(struct nvme_ctrl *ctrl) { /* diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index bf46f122e9e1..8f62246a85be 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -828,6 +828,7 @@ void nvme_stop_keep_alive(struct nvme_ctrl *ctrl); int nvme_reset_ctrl(struct nvme_ctrl *ctrl); int nvme_reset_ctrl_sync(struct nvme_ctrl *ctrl); int nvme_delete_ctrl(struct nvme_ctrl *ctrl); +int nvme_delete_dead_ctrl(struct nvme_ctrl *ctrl); void nvme_queue_scan(struct nvme_ctrl *ctrl); int nvme_get_log(struct nvme_ctrl *ctrl, u32 nsid, u8 log_page, u8 lsp, u8 csi, void *log, size_t size, u64 offset); -- 2.40.1