On Wed, Nov 28, 2018 at 09:26:55AM -0700, Keith Busch wrote: > --- > diff --git a/drivers/nvme/target/loop.c b/drivers/nvme/target/loop.c > index 9908082b32c4..116398b240e5 100644 > --- a/drivers/nvme/target/loop.c > +++ b/drivers/nvme/target/loop.c > @@ -428,10 +428,14 @@ static int nvme_loop_configure_admin_queue(struct nvme_loop_ctrl *ctrl) > static void nvme_loop_shutdown_ctrl(struct nvme_loop_ctrl *ctrl) > { > if (ctrl->ctrl.queue_count > 1) { > - nvme_stop_queues(&ctrl->ctrl); > - blk_mq_tagset_busy_iter(&ctrl->tag_set, > - nvme_cancel_request, &ctrl->ctrl); > + /* > + * The back end device driver is responsible for completing all > + * entered requests > + */ > + nvme_start_freeze(&ctrl->ctrl); > + nvme_wait_freeze(&ctrl->ctrl); > nvme_loop_destroy_io_queues(ctrl); > + nvme_unfreeze(&ctrl->ctrl); > } > > if (ctrl->ctrl.state == NVME_CTRL_LIVE) > --- Grr, the above doesn't work so well when not using NVMe mpath because nvmf_check_ready() will requeue it, leaving entered requests that won't be started. Waiting for a freeze isn't really the criteria we need anyway: we don't care if there are entered requests in REQ_MQ_IDLE. We just want to wait for dispatched ones to return, and we currently don't have a good way to sync with that condition.