Linux-NVME Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: guzebing <guzebing1612@gmail.com>
To: kbusch@kernel.org, axboe@kernel.dk, hch@lst.de, sagi@grimberg.me
Cc: linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org,
	Guzebing <guzebing@bytedance.com>
Subject: [PATCH] nvme: make firmware activation poll interval configurable
Date: Sat, 27 Jun 2026 09:06:10 +0800	[thread overview]
Message-ID: <20260627010610.47768-1-guzebing1612@gmail.com> (raw)

From: Guzebing <guzebing@bytedance.com>

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
interval can add noticeable latency before the driver observes
completion.

Add an nvme_core.fw_act_poll_interval_ms module parameter to make the
poll interval tunable. Keep the default at 100 ms to preserve existing
behavior, and accept values from 10 ms to 100 ms so systems that need
faster completion detection can opt in to a shorter interval.

Signed-off-by: Guzebing <guzebing@bytedance.com>
---
We recently observed this issue while performing online firmware
updates for Gen5 NVMe SSDs in a production environment.

During firmware activation, the kernel quiesces I/O. Detecting the end
of firmware activation earlier lets the driver unquiesce I/O earlier,
which is important for the long-tail I/O latency of production
workloads.

Operation steps:
  nvme fw-download /dev/nvme13n1 \
    -f ./Inventec_G238B_NVME_LDD5902Q_MZWL61T9HFLT-00B07.bin
  nvme fw-commit /dev/nvme13n1 -s 0 -a 3
  nvme fw-log /dev/nvme13n1

Operation device:
  Samsung PM9D3a Gen5 NVMe SSD, model MZWL67T6HBLC-00B07
  Firmware update: LDD5702Q -> LDD5902Q

Operation results:
  100 ms polling interval: 3 polls, 311 ms
   10 ms polling interval: 24 polls, 266 ms

 drivers/nvme/host/core.c | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 3b7a8f7a35426..784da06fee559 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -58,6 +58,21 @@ module_param_named(io_timeout, nvme_io_timeout, uint, 0644);
 MODULE_PARM_DESC(io_timeout, "timeout in seconds for I/O");
 EXPORT_SYMBOL_GPL(nvme_io_timeout);
 
+#define NVME_FW_ACT_POLL_INTERVAL_MIN_MS	10
+#define NVME_FW_ACT_POLL_INTERVAL_MAX_MS	100
+static int fw_act_poll_interval_ms_set(const char *val,
+				       const struct kernel_param *kp);
+static const struct kernel_param_ops fw_act_poll_interval_ms_ops = {
+	.set = fw_act_poll_interval_ms_set,
+	.get = param_get_uint,
+};
+
+static unsigned int fw_act_poll_interval_ms = 100;
+module_param_cb(fw_act_poll_interval_ms, &fw_act_poll_interval_ms_ops,
+		&fw_act_poll_interval_ms, 0644);
+MODULE_PARM_DESC(fw_act_poll_interval_ms,
+		 "firmware activation polling interval in ms (10-100)");
+
 static unsigned char shutdown_timeout = 5;
 module_param(shutdown_timeout, byte, 0644);
 MODULE_PARM_DESC(shutdown_timeout, "timeout in seconds for controller shutdown");
@@ -106,6 +121,13 @@ module_param(disable_pi_offsets, bool, 0444);
 MODULE_PARM_DESC(disable_pi_offsets,
 	"disable protection information if it has an offset");
 
+static int fw_act_poll_interval_ms_set(const char *val,
+				       const struct kernel_param *kp)
+{
+	return param_set_uint_minmax(val, kp, NVME_FW_ACT_POLL_INTERVAL_MIN_MS,
+				     NVME_FW_ACT_POLL_INTERVAL_MAX_MS);
+}
+
 /*
  * nvme_wq - hosts nvme related works that are not reset or delete
  * nvme_reset_wq - hosts nvme reset works
@@ -4798,7 +4820,7 @@ static void nvme_fw_act_work(struct work_struct *work)
 			nvme_try_sched_reset(ctrl);
 			return;
 		}
-		msleep(100);
+		msleep(READ_ONCE(fw_act_poll_interval_ms));
 	}
 
 	if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_CONNECTING) ||
-- 
2.20.1


             reply	other threads:[~2026-06-27  1:06 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-27  1:06 guzebing [this message]
2026-07-06  6:33 ` [PATCH] nvme: make firmware activation poll interval configurable guzebing
2026-07-09  6:42 ` Christoph Hellwig
2026-07-09  9:06   ` guzebing
2026-07-09 15:07     ` Keith Busch
2026-07-10  9:20       ` guzebing

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260627010610.47768-1-guzebing1612@gmail.com \
    --to=guzebing1612@gmail.com \
    --cc=axboe@kernel.dk \
    --cc=guzebing@bytedance.com \
    --cc=hch@lst.de \
    --cc=kbusch@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-nvme@lists.infradead.org \
    --cc=sagi@grimberg.me \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox