[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