[PATCH RFC v3 11/11] nvmet: cancel implementation

Maurizio Lombardi mlombard at redhat.com
Mon Mar 24 03:23:10 PDT 2025


From: Chris Leech <cleech at redhat.com>

Requests are canceled if the have been delayed and cancel_delayed_work
is successfull.

replace emulate_cancel_commands modparam with the delay kconfig

Signed-off-by: Chris Leech <cleech at redhat.com>
---
 drivers/nvme/target/Makefile        |  3 ++-
 drivers/nvme/target/admin-cmd.c     |  7 +++----
 drivers/nvme/target/core.c          |  9 +++------
 drivers/nvme/target/io-cmd-cancel.c | 27 ++++++++++++++++++++++++++-
 drivers/nvme/target/nvmet.h         |  2 --
 5 files changed, 34 insertions(+), 14 deletions(-)

diff --git a/drivers/nvme/target/Makefile b/drivers/nvme/target/Makefile
index a533357e9be4..5d9848605285 100644
--- a/drivers/nvme/target/Makefile
+++ b/drivers/nvme/target/Makefile
@@ -11,7 +11,8 @@ obj-$(CONFIG_NVME_TARGET_TCP)		+= nvmet-tcp.o
 obj-$(CONFIG_NVME_TARGET_PCI_EPF)	+= nvmet-pci-epf.o
 
 nvmet-y		+= core.o configfs.o admin-cmd.o fabrics-cmd.o \
-			discovery.o io-cmd-file.o io-cmd-bdev.o pr.o io-cmd-cancel.o
+			discovery.o io-cmd-file.o io-cmd-bdev.o pr.o
+nvmet-$(CONFIG_NVME_TARGET_DELAY_REQUESTS) += io-cmd-cancel.o
 nvmet-$(CONFIG_NVME_TARGET_DEBUGFS)	+= debugfs.o
 nvmet-$(CONFIG_NVME_TARGET_PASSTHRU)	+= passthru.o
 nvmet-$(CONFIG_BLK_DEV_ZONED)		+= zns.o
diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c
index 57b90263a7cb..149c72d0b429 100644
--- a/drivers/nvme/target/admin-cmd.c
+++ b/drivers/nvme/target/admin-cmd.c
@@ -398,10 +398,9 @@ static void nvmet_get_cmd_effects_nvm(struct nvme_effects_log *log)
 	log->iocs[nvme_cmd_resv_release] =
 	log->iocs[nvme_cmd_resv_report] =
 		cpu_to_le32(NVME_CMD_EFFECTS_CSUPP);
-	if (emulate_cancel_support) {
-		log->iocs[nvme_cmd_cancel] =
-			cpu_to_le32(NVME_CMD_EFFECTS_CSUPP);
-	}
+#if IS_ENABLED(CONFIG_NVME_TARGET_DELAY_REQUESTS)
+	log->iocs[nvme_cmd_cancel] = cpu_to_le32(NVME_CMD_EFFECTS_CSUPP);
+#endif
 	log->iocs[nvme_cmd_write] =
 	log->iocs[nvme_cmd_write_zeroes] =
 		cpu_to_le32(NVME_CMD_EFFECTS_CSUPP | NVME_CMD_EFFECTS_LBCC);
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index b446db3804f1..fd242af9fefb 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -29,10 +29,6 @@ static DEFINE_IDA(cntlid_ida);
 struct workqueue_struct *nvmet_wq;
 EXPORT_SYMBOL_GPL(nvmet_wq);
 
-bool emulate_cancel_support;
-module_param(emulate_cancel_support, bool, 0644);
-MODULE_PARM_DESC(emulate_cancel_support, "Emulate the cancel command support. Default = false");
-
 /*
  * This read/write semaphore is used to synchronize access to configuration
  * information on a target system that will result in discovery log page
@@ -1078,12 +1074,13 @@ static u16 nvmet_parse_io_cmd(struct nvmet_req *req)
 	if (nvmet_is_passthru_req(req))
 		return nvmet_parse_passthru_io_cmd(req);
 
-	if (emulate_cancel_support &&
-	    req->cmd->common.opcode == nvme_cmd_cancel) {
+#if IS_ENABLED(CONFIG_NVME_TARGET_DELAY_REQUESTS)
+	if (req->cmd->common.opcode == nvme_cmd_cancel) {
 		req->execute = nvmet_execute_cancel;
 		if (req->cmd->cancel.nsid == NVME_NSID_ALL)
 			return 0;
 	}
+#endif
 
 	ret = nvmet_req_find_ns(req);
 	if (unlikely(ret))
diff --git a/drivers/nvme/target/io-cmd-cancel.c b/drivers/nvme/target/io-cmd-cancel.c
index 8f55458e646a..8d7f363c9163 100644
--- a/drivers/nvme/target/io-cmd-cancel.c
+++ b/drivers/nvme/target/io-cmd-cancel.c
@@ -14,6 +14,8 @@ void nvmet_execute_cancel(struct nvmet_req *req)
 	int ret = 0;
 	struct nvmet_ctrl *ctrl = req->sq->ctrl;
 	struct nvmet_sq *sq = req->sq;
+	struct nvmet_req *treq;
+	u32 canceled = 0;
 
 	if (!nvmet_check_transfer_len(req, 0))
 		return;
@@ -45,8 +47,31 @@ void nvmet_execute_cancel(struct nvmet_req *req)
 		ret = NVME_SC_INVALID_FIELD | NVME_STATUS_DNR;
 	}
 
+	if (!mult_cmds) {
+		treq = xa_load(&sq->outstanding_requests, cid);
+		if (treq) {
+			if (cancel_delayed_work(&treq->req_work)) {
+				pr_info("nvmet: CANCEL success: %d", cid);
+				nvmet_req_complete(treq, NVME_SC_ABORT_REQ);
+				canceled += 1;
+			} else {
+				pr_info("nvmet: CANCEL failed: %d", cid);
+			}
+		} else {
+			pr_info("nvmet: CANCEL request not found: %d", cid);
+		}
+	} else {
+		unsigned long ucid;
+		xa_for_each(&sq->outstanding_requests, ucid, treq) {
+			if (cancel_delayed_work(&treq->req_work)) {
+				nvmet_req_complete(treq, NVME_SC_ABORT_REQ);
+				canceled += 1;
+			}
+		}
+		pr_info("nvmet: CANCEL removed %d requests", canceled);
+	}
 exit:
-	nvmet_set_result(req, 0);
+	nvmet_set_result(req, canceled);
 	nvmet_req_complete(req, ret);
 }
 
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
index fc61f28c63da..525803774183 100644
--- a/drivers/nvme/target/nvmet.h
+++ b/drivers/nvme/target/nvmet.h
@@ -40,8 +40,6 @@
 #define nvmet_for_each_enabled_ns(xa, index, entry) \
 	xa_for_each_marked(xa, index, entry, NVMET_NS_ENABLED)
 
-extern bool emulate_cancel_support;
-
 /*
  * Supported optional AENs:
  */
-- 
2.43.5




More information about the Linux-nvme mailing list