git: e65ccec8c0e3 - main - nvme: Notify namespaces on reset sometimes
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 19 Oct 2026 06:24:39 UTC
The branch main has been updated by imp:
URL: https://cgit.FreeBSD.org/src/commit/?id=e65ccec8c0e359f584b2948c100ee3012e43c6e7
commit e65ccec8c0e359f584b2948c100ee3012e43c6e7
Author: Warner Losh <imp@FreeBSD.org>
AuthorDate: 2026-10-19 04:41:00 +0000
Commit: Warner Losh <imp@FreeBSD.org>
CommitDate: 2026-10-19 06:22:51 +0000
nvme: Notify namespaces on reset sometimes
When we're resetting after a controller failure, and we fix the failure,
and we've not resetting as part of initialization, notify the all the
children devices of new namespaces. When we failed the controller
before, we removed all the namespaces.
Reviewed by: seuros
Differential Revision: https://reviews.freebsd.org/D59832
---
sys/dev/nvme/nvme_ctrlr.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/sys/dev/nvme/nvme_ctrlr.c b/sys/dev/nvme/nvme_ctrlr.c
index f27653536c66..354ca7a78e51 100644
--- a/sys/dev/nvme/nvme_ctrlr.c
+++ b/sys/dev/nvme/nvme_ctrlr.c
@@ -673,6 +673,24 @@ nvme_ctrlr_notify_ns_added(struct nvme_controller *ctrlr, device_t child)
}
}
+static void
+nvme_ctrlr_notify_ns_recovered(struct nvme_controller *ctrlr)
+{
+ device_t *children;
+ int n_children;
+
+ if (device_get_children(ctrlr->dev, &children, &n_children) != 0)
+ return;
+
+ /*
+ * A controller failure was reported to every child, so notify every
+ * child when its namespaces become available again.
+ */
+ for (int i = 0; i < n_children; i++)
+ nvme_ctrlr_notify_ns_added(ctrlr, children[i]);
+ free(children, M_TEMP);
+}
+
static bool
is_log_page_id_valid(uint8_t page_id)
{
@@ -1278,13 +1296,19 @@ static void
nvme_ctrlr_reset_task(void *arg, int pending)
{
struct nvme_controller *ctrlr = arg;
+ bool recovering;
int status;
+ recovering = ctrlr->is_initialized && ctrlr->is_failed;
nvme_ctrlr_devctl_log(ctrlr, "RESET", "event=\"start\"");
status = nvme_ctrlr_hw_reset(ctrlr);
if (status == 0) {
nvme_ctrlr_devctl_log(ctrlr, "RESET", "event=\"success\"");
+ if (recovering)
+ ctrlr->is_failed = false;
nvme_ctrlr_start(ctrlr, true);
+ if (recovering && !ctrlr->is_failed)
+ nvme_ctrlr_notify_ns_recovered(ctrlr);
} else {
nvme_ctrlr_devctl_log(ctrlr, "RESET", "event=\"timed_out\"");
nvme_ctrlr_fail(ctrlr, true);