git: 1c31ef40e185 - main - nvme: support per-request timeouts
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 19 Oct 2026 06:24:36 UTC
The branch main has been updated by imp:
URL: https://cgit.FreeBSD.org/src/commit/?id=1c31ef40e185a09c030d53640f6ebc71bb0c830f
commit 1c31ef40e185a09c030d53640f6ebc71bb0c830f
Author: Warner Losh <imp@FreeBSD.org>
AuthorDate: 2026-10-19 04:38:45 +0000
Commit: Warner Losh <imp@FreeBSD.org>
CommitDate: 2026-10-19 06:22:50 +0000
nvme: support per-request timeouts
Allow different timeouts per command.
Reviewed by: seuros, chuck
Differential Revision: https://reviews.freebsd.org/D59828
---
sys/dev/nvme/nvme_ctrlr.c | 2 +-
sys/dev/nvme/nvme_private.h | 8 +++++---
sys/dev/nvme/nvme_qpair.c | 17 +++++++++++------
3 files changed, 17 insertions(+), 10 deletions(-)
diff --git a/sys/dev/nvme/nvme_ctrlr.c b/sys/dev/nvme/nvme_ctrlr.c
index ccfbe576fd26..c8c891eaf806 100644
--- a/sys/dev/nvme/nvme_ctrlr.c
+++ b/sys/dev/nvme/nvme_ctrlr.c
@@ -795,7 +795,7 @@ nvme_ctrlr_construct_and_submit_aer(struct nvme_controller *ctrlr,
* Disable timeout here, since asynchronous event requests should by
* nature never be timed out.
*/
- req->timeout = false;
+ req->timeout_ms = NVME_TIMEOUT_NONE;
req->cmd.opc = NVME_OPC_ASYNC_EVENT_REQUEST;
nvme_ctrlr_submit_admin_request(ctrlr, req);
}
diff --git a/sys/dev/nvme/nvme_private.h b/sys/dev/nvme/nvme_private.h
index c50ddf2a2a3b..b55159145de9 100644
--- a/sys/dev/nvme/nvme_private.h
+++ b/sys/dev/nvme/nvme_private.h
@@ -86,6 +86,9 @@ MALLOC_DECLARE(M_NVME);
#define NVME_MAX_TIMEOUT_PERIOD (120)
#define NVME_MAX_FORMAT_TIMEOUT_PERIOD (60 * 60)
+#define NVME_TIMEOUT_DEFAULT 0U
+#define NVME_TIMEOUT_NONE UINT32_MAX
+
#define NVME_DEFAULT_RETRY_COUNT (4)
/* Maximum log page size to fetch for AERs. */
@@ -115,12 +118,11 @@ struct nvme_request {
struct memdesc payload;
nvme_cb_fn_t cb_fn;
void *cb_arg;
+ uint32_t timeout_ms;
int16_t retries;
uint16_t ioq;
#define NVME_IOQ_DEFAULT 0xffff
bool payload_valid;
- bool timeout;
- bool spare[2]; /* Future use */
STAILQ_ENTRY(nvme_request) stailq;
};
@@ -544,7 +546,7 @@ _nvme_allocate_request(const int how, nvme_cb_fn_t cb_fn, void *cb_arg)
req->ioq = NVME_IOQ_DEFAULT;
req->cb_fn = cb_fn;
req->cb_arg = cb_arg;
- req->timeout = true;
+ req->timeout_ms = NVME_TIMEOUT_DEFAULT;
}
return (req);
}
diff --git a/sys/dev/nvme/nvme_qpair.c b/sys/dev/nvme/nvme_qpair.c
index c918539ce28c..1fd853513fcb 100644
--- a/sys/dev/nvme/nvme_qpair.c
+++ b/sys/dev/nvme/nvme_qpair.c
@@ -1037,7 +1037,7 @@ nvme_qpair_submit_tracker(struct nvme_qpair *qpair, struct nvme_tracker *tr)
{
struct nvme_request *req;
struct nvme_controller *ctrlr;
- int timeout;
+ uint32_t timeout_ms;
mtx_assert(&qpair->lock, MA_OWNED);
@@ -1045,14 +1045,19 @@ nvme_qpair_submit_tracker(struct nvme_qpair *qpair, struct nvme_tracker *tr)
qpair->act_tr[tr->cid] = tr;
ctrlr = qpair->ctrlr;
- if (req->timeout) {
+ if (req->timeout_ms != NVME_TIMEOUT_NONE) {
if (req->cb_fn == nvme_completion_poll_cb)
- timeout = 1;
+ timeout_ms = 1000;
+ else if (req->timeout_ms != NVME_TIMEOUT_DEFAULT)
+ timeout_ms = req->timeout_ms;
+ else if (qpair->id == 0 && req->cmd.opc == NVME_OPC_FORMAT_NVM)
+ timeout_ms = ctrlr->format_timeout_period * 1000;
else if (qpair->id == 0)
- timeout = ctrlr->admin_timeout_period;
+ timeout_ms = ctrlr->admin_timeout_period * 1000;
else
- timeout = ctrlr->timeout_period;
- tr->deadline = getsbinuptime() + timeout * SBT_1S;
+ timeout_ms = ctrlr->timeout_period * 1000;
+ tr->deadline = getsbinuptime() +
+ (sbintime_t)timeout_ms * SBT_1MS;
if (!qpair->timer_armed) {
qpair->timer_armed = true;
callout_reset_sbt_on(&qpair->timer, SBT_1S / 2, SBT_1S / 2,