public inbox for linux-nvme@lists.infradead.org
 help / color / mirror / Atom feed
* [PATCH] nvme: don't flush scan work with non-idle request
@ 2022-08-12 18:21 Keith Busch
  2022-08-12 19:12 ` Jonathan Derrick
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Keith Busch @ 2022-08-12 18:21 UTC (permalink / raw)
  To: linux-nvme; +Cc: hch, Keith Busch, Jonathan Derrick

From: Keith Busch <kbusch@kernel.org>

If a reset occurs after the scan work attempts to issue a command, the
reset may quisce the admin queue, which blocks the scan work's command
from dispatching. The scan work will not be able to complete while the
queue is quiesced.

Meanwhile, the reset work will cancel all outstanding admin tags and
wait until all requests have transitioned to idle, which includes the
passthrough request. But the passthrough request won't be set to idle
until after the scan_work flushes, so we're deadlocked.

Fix this by moving the flush_work after the request has been freed.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=216354
Reported-by: Jonathan Derrick <Jonathan.Derrick@solidigm.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
---
 drivers/nvme/host/core.c  |  5 ++---
 drivers/nvme/host/ioctl.c | 12 ++++++++++++
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index af367b22871b..1143f625e195 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -1121,12 +1121,11 @@ static void nvme_passthru_end(struct nvme_ctrl *ctrl, u32 effects,
 		nvme_remove_invalid_namespaces(ctrl, NVME_NSID_ALL);
 		mutex_unlock(&ctrl->scan_lock);
 	}
+
 	if (effects & NVME_CMD_EFFECTS_CCC)
 		nvme_init_ctrl_finish(ctrl);
-	if (effects & (NVME_CMD_EFFECTS_NIC | NVME_CMD_EFFECTS_NCC)) {
+	if (effects & (NVME_CMD_EFFECTS_NIC | NVME_CMD_EFFECTS_NCC))
 		nvme_queue_scan(ctrl);
-		flush_work(&ctrl->scan_work);
-	}
 
 	switch (cmd->common.opcode) {
 	case nvme_admin_set_features:
diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c
index 27614bee7380..97febd5f41a3 100644
--- a/drivers/nvme/host/ioctl.c
+++ b/drivers/nvme/host/ioctl.c
@@ -136,9 +136,11 @@ static int nvme_submit_user_cmd(struct request_queue *q,
 		unsigned bufflen, void __user *meta_buffer, unsigned meta_len,
 		u32 meta_seed, u64 *result, unsigned timeout, bool vec)
 {
+	struct nvme_ctrl *ctrl;
 	struct request *req;
 	void *meta = NULL;
 	struct bio *bio;
+	u32 effects;
 	int ret;
 
 	req = nvme_alloc_user_request(q, cmd, ubuffer, bufflen, meta_buffer,
@@ -147,6 +149,8 @@ static int nvme_submit_user_cmd(struct request_queue *q,
 		return PTR_ERR(req);
 
 	bio = req->bio;
+	ctrl = nvme_req(req)->ctrl;
+	effects = nvme_command_effects(ctrl, q->queuedata, cmd->common.opcode);
 
 	ret = nvme_execute_passthru_rq(req);
 
@@ -158,6 +162,14 @@ static int nvme_submit_user_cmd(struct request_queue *q,
 	if (bio)
 		blk_rq_unmap_user(bio);
 	blk_mq_free_request(req);
+
+	/*
+	 * Ensure the namespace inventory is up-to-date before returning if
+	 * this command can change it.
+	 */
+	if (ret >= 0 && effects & (NVME_CMD_EFFECTS_NIC | NVME_CMD_EFFECTS_NCC))
+		flush_work(&ctrl->scan_work);
+
 	return ret;
 }
 
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2022-08-23 16:14 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-08-12 18:21 [PATCH] nvme: don't flush scan work with non-idle request Keith Busch
2022-08-12 19:12 ` Jonathan Derrick
2022-08-16  8:53 ` Chao Leng
2022-08-17 10:29   ` Sagi Grimberg
2022-08-17 15:07     ` Keith Busch
2022-08-17 15:39       ` Sagi Grimberg
2022-08-21 14:40 ` Christoph Hellwig
2022-08-22 15:09   ` Keith Busch
2022-08-23 16:14     ` Christoph Hellwig

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox