[PATCH v3] nvme: reduce firmware activation poll interval

guzebing <[email protected]>
Newsgroups org.infradead.lists.linux-nvme,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
From: Guzebing <[email protected]>

nvme_fw_act_work() polls the controller processing-paused status every
100 ms while firmware activation is pending. Some devices can complete
online activation in only a few hundred milliseconds, so the fixed
100 ms interval can add up to 100 ms of latency before the driver
observes completion.

nvme_wait_ready() already uses a 1 to 2 ms delay between CSTS reads.
Use the same delay in nvme_fw_act_work() for consistency, and add a
common helper for both paths.

Signed-off-by: Guzebing <[email protected]>
---
Changes in v3:
- Add a common polling delay helper for nvme_fw_act_work() and
  nvme_wait_ready().

Changes in v2:
- Drop the module parameter and use a fixed 1 to 2 ms poll interval.

v2: https://lore.kernel.org/linux-nvme/[email protected]/
v1: https://lore.kernel.org/linux-nvme/[email protected]/

 drivers/nvme/host/core.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 453c1f0b2dd09..499fe36792266 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -2688,6 +2688,16 @@ const struct block_device_operations nvme_bdev_ops = {
 	.pr_ops		= &nvme_pr_ops,
 };
 
+/*
+ * Wait between CSTS reads in nvme_wait_ready() and nvme_fw_act_work().
+ * A 1 to 2 ms interval avoids excessive register reads while allowing
+ * changes in controller status to be detected promptly.
+ */
+static void nvme_busy_wait(void)
+{
+	usleep_range(1000, 2000);
+}
+
 static int nvme_wait_ready(struct nvme_ctrl *ctrl, u32 mask, u32 val,
 		u32 timeout, const char *op)
 {
@@ -2701,7 +2711,7 @@ static int nvme_wait_ready(struct nvme_ctrl *ctrl, u32 mask, u32 val,
 		if ((csts & mask) == val)
 			break;
 
-		usleep_range(1000, 2000);
+		nvme_busy_wait();
 		if (fatal_signal_pending(current))
 			return -EINTR;
 		if (time_after(jiffies, timeout_jiffies)) {
@@ -4813,7 +4823,7 @@ static void nvme_fw_act_work(struct work_struct *work)
 			nvme_try_sched_reset(ctrl);
 			return;
 		}
-		msleep(100);
+		nvme_busy_wait();
 	}
 
 	if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_CONNECTING) ||
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.