[PATCH RFC v3 09/11] nvmet: delay requests
Maurizio Lombardi
mlombard at redhat.com
Mon Mar 24 03:23:08 PDT 2025
From: Chris Leech <cleech at redhat.com>
Allow requests to be delayed for testing.
Signed-off-by: Chris Leech <cleech at redhat.com>
---
drivers/nvme/target/core.c | 30 ++++++++++++++++++++++++++++++
drivers/nvme/target/nvmet.h | 8 ++++++++
2 files changed, 38 insertions(+)
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index 3e22dacddd76..5622b0608d55 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -6,7 +6,9 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/random.h>
+#include <linux/jiffies.h>
#include <linux/rculist.h>
+#include <linux/workqueue.h>
#include <linux/pci-p2pdma.h>
#include <linux/scatterlist.h>
@@ -1753,6 +1755,34 @@ ssize_t nvmet_ctrl_host_traddr(struct nvmet_ctrl *ctrl,
return ctrl->ops->host_traddr(ctrl, traddr, traddr_len);
}
+#if IS_ENABLED(CONFIG_NVME_TARGET_DELAY_REQUESTS)
+static void nvmet_delayed_execute_req(struct work_struct *work) {
+ struct nvmet_req *req =
+ container_of(to_delayed_work(work), struct nvmet_req, req_work);
+ req->execute(req);
+}
+
+void nvmet_execute_request(struct nvmet_req *req) {
+ struct nvmet_ctrl *ctrl = req->sq->ctrl;
+ int delay_count;
+ u32 delay_msec;
+
+ if (unlikely(req->sq->qid == 0))
+ return req->execute(req);
+
+ if (ctrl) {
+ delay_count = atomic_dec_if_positive(&ctrl->delay_count) + 1;
+ delay_msec = ctrl->delay_msec;
+ }
+ if (!(ctrl && delay_count && delay_msec))
+ return req->execute(req);
+
+ INIT_DELAYED_WORK(&req->req_work, nvmet_delayed_execute_req);
+ queue_delayed_work(nvmet_wq, &req->req_work, msecs_to_jiffies(delay_msec));
+}
+EXPORT_SYMBOL_GPL(nvmet_execute_request);
+#endif
+
static struct nvmet_subsys *nvmet_find_get_subsys(struct nvmet_port *port,
const char *subsysnqn)
{
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
index 7a360285b254..1bfdddceda15 100644
--- a/drivers/nvme/target/nvmet.h
+++ b/drivers/nvme/target/nvmet.h
@@ -496,6 +496,9 @@ struct nvmet_req {
u16 error_loc;
u64 error_slba;
struct nvmet_pr_per_ctrl_ref *pc_ref;
+#if IS_ENABLED(CONFIG_NVME_TARGET_DELAY_REQUESTS)
+ struct delayed_work req_work;
+#endif
};
#define NVMET_MAX_MPOOL_BVEC 16
@@ -971,5 +974,10 @@ struct nvmet_feat_arbitration {
u8 ab;
};
+#if IS_ENABLED(CONFIG_NVME_TARGET_DELAY_REQUESTS)
+void nvmet_execute_request(struct nvmet_req *req);
+#else
static inline void nvmet_execute_request(struct nvmet_req *req) { req->execute(req); }
+#endif
+
#endif /* _NVMET_H */
--
2.43.5
More information about the Linux-nvme
mailing list