[PATCH RFC v3 08/11] nvmet: add delay debugfs file to nvmet_ctrl
Maurizio Lombardi
mlombard at redhat.com
Mon Mar 24 03:23:07 PDT 2025
From: Chris Leech <cleech at redhat.com>
Creates an delay attribute file on the controler in debugfs
/sys/kernel/debug/nvmet/<subsystem>/ctrlN/delay
Reading this file returns two numbers, a reqeust delay count and a delay
time in ms. Each delayed request will decrement the delay count until
it reaches 0.
Writing to this file can set both the delay and count at once, or just
the count to trigger more delays.
# delay the next 5 request by 5 seconds each
echo 5 5000 > delay
# set the delay time to 3 seconds without starting a count
echo 0 3000 > delay
# delay to the next 5 requests by the current delay time
echo 5 > delay
Signed-off-by: Chris Leech <cleech at redhat.com>
---
drivers/nvme/target/Kconfig | 9 ++++++++
drivers/nvme/target/debugfs.c | 40 +++++++++++++++++++++++++++++++++++
drivers/nvme/target/nvmet.h | 4 ++++
3 files changed, 53 insertions(+)
diff --git a/drivers/nvme/target/Kconfig b/drivers/nvme/target/Kconfig
index fb7446d6d682..e0a1ccb93da6 100644
--- a/drivers/nvme/target/Kconfig
+++ b/drivers/nvme/target/Kconfig
@@ -126,3 +126,12 @@ config NVME_TARGET_PCI_EPF
capable PCI controller.
If unsure, say N.
+
+config NVME_TARGET_DELAY_REQUESTS
+ bool "NVMe over Fabrics target request delay"
+ depends on NVME_TARGET && NVME_TARGET_DEBUGFS
+ help
+ This is a testing feature to allow delaying request completion in an
+ NVMe over Fabrics target, which allows for support of the cancel command.
+
+ If unsure, say N.
diff --git a/drivers/nvme/target/debugfs.c b/drivers/nvme/target/debugfs.c
index e4300eb95101..4a80cfceab34 100644
--- a/drivers/nvme/target/debugfs.c
+++ b/drivers/nvme/target/debugfs.c
@@ -153,6 +153,42 @@ static int nvmet_ctrl_tls_concat_show(struct seq_file *m, void *p)
NVMET_DEBUGFS_ATTR(nvmet_ctrl_tls_concat);
#endif
+#if IS_ENABLED(CONFIG_NVME_TARGET_DELAY_REQUESTS)
+static int nvmet_ctrl_delay_show(struct seq_file *m, void *p)
+{
+ struct nvmet_ctrl *ctrl = m->private;
+ int delay_count = atomic_read(&ctrl->delay_count);
+
+ seq_printf(m, "%u %u\n", delay_count, ctrl->delay_msec);
+ return 0;
+}
+
+static ssize_t nvmet_ctrl_delay_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct seq_file *m = file->private_data;
+ struct nvmet_ctrl *ctrl = m->private;
+ char delay_buf[22] = {};
+ int delay_count;
+ int delay_msec;
+ int n;
+
+ if (count >= sizeof(delay_buf))
+ return -EINVAL;
+ if (copy_from_user(delay_buf, buf, count))
+ return -EFAULT;
+
+ n = sscanf(delay_buf, "%u %u", &delay_count, &delay_msec);
+ if (n < 1 || n > 2)
+ return -EINVAL;
+ if (n == 2)
+ ctrl->delay_msec = delay_msec;
+ atomic_set(&ctrl->delay_count, delay_count);
+ return count;
+}
+NVMET_DEBUGFS_RW_ATTR(nvmet_ctrl_delay);
+#endif /* CONFIG_NVME_TARGET_DELAY_REQUESTS */
+
int nvmet_debugfs_ctrl_setup(struct nvmet_ctrl *ctrl)
{
char name[32];
@@ -183,6 +219,10 @@ int nvmet_debugfs_ctrl_setup(struct nvmet_ctrl *ctrl)
&nvmet_ctrl_tls_concat_fops);
debugfs_create_file("tls_key", S_IRUSR, ctrl->debugfs_dir, ctrl,
&nvmet_ctrl_tls_key_fops);
+#endif
+#if IS_ENABLED(CONFIG_NVME_TARGET_DELAY_REQUESTS)
+ debugfs_create_file("delay", S_IWUSR, ctrl->debugfs_dir, ctrl,
+ &nvmet_ctrl_delay_fops);
#endif
return 0;
}
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
index 7599dbb4347c..7a360285b254 100644
--- a/drivers/nvme/target/nvmet.h
+++ b/drivers/nvme/target/nvmet.h
@@ -306,6 +306,10 @@ struct nvmet_ctrl {
#endif
#ifdef CONFIG_NVME_TARGET_TCP_TLS
struct key *tls_key;
+#endif
+#ifdef CONFIG_NVME_TARGET_DELAY_REQUESTS
+ atomic_t delay_count;
+ u32 delay_msec;
#endif
struct nvmet_pr_log_mgr pr_log_mgr;
};
--
2.43.5
More information about the Linux-nvme
mailing list