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
next 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