git: 6751f65e6af1 - main - nvmf: Defer the post-sync shutdown handler to SHUTDOWN_PRI_LAST
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 13 Jan 2025 20:07:59 UTC
The branch main has been updated by jhb:
URL: https://cgit.FreeBSD.org/src/commit/?id=6751f65e6af15348abdc6106cf54c8335d45e49b
commit 6751f65e6af15348abdc6106cf54c8335d45e49b
Author: John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2024-10-31 15:03:41 +0000
Commit: John Baldwin <jhb@FreeBSD.org>
CommitDate: 2025-01-13 20:04:29 +0000
nvmf: Defer the post-sync shutdown handler to SHUTDOWN_PRI_LAST
nda(4) has its own shutdown handler that runs at SHUTDOWN_PRI_DEFAULT
that calls ndaflush() that could run after the nvmf handler. Instead,
give a the flush a chance to run before the graceful shutdown of the
controller.
While here, be a bit more defensive in the post-sync case and shutdown
the consumers (sim and /dev/nvmeXnY devices) before destroying the
queue pairs so that if any requests are submitted after the post-sync
handler they fail gracefully instead of trying to use a destroyed
queue pair.
Reported by: Sony Arpita Das <sonyarpitad@chelsio.com>
Sponsored by: Chelsio Communications
---
sys/dev/nvmf/host/nvmf.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/sys/dev/nvmf/host/nvmf.c b/sys/dev/nvmf/host/nvmf.c
index 09d5cecdfad6..77d3081243f6 100644
--- a/sys/dev/nvmf/host/nvmf.c
+++ b/sys/dev/nvmf/host/nvmf.c
@@ -554,7 +554,7 @@ nvmf_attach(device_t dev)
sc->shutdown_pre_sync_eh = EVENTHANDLER_REGISTER(shutdown_pre_sync,
nvmf_shutdown_pre_sync, sc, SHUTDOWN_PRI_FIRST);
sc->shutdown_post_sync_eh = EVENTHANDLER_REGISTER(shutdown_post_sync,
- nvmf_shutdown_post_sync, sc, SHUTDOWN_PRI_FIRST);
+ nvmf_shutdown_post_sync, sc, SHUTDOWN_PRI_LAST);
return (0);
out:
@@ -776,6 +776,18 @@ nvmf_shutdown_post_sync(void *arg, int howto)
callout_drain(&sc->ka_rx_timer);
nvmf_shutdown_controller(sc);
+
+ /*
+ * Quiesce consumers so that any commands submitted after this
+ * fail with an error. Notably, nda(4) calls nda_flush() from
+ * a post_sync handler that might be ordered after this one.
+ */
+ for (u_int i = 0; i < sc->cdata->nn; i++) {
+ if (sc->ns[i] != NULL)
+ nvmf_shutdown_ns(sc->ns[i]);
+ }
+ nvmf_shutdown_sim(sc);
+
for (u_int i = 0; i < sc->num_io_queues; i++) {
nvmf_destroy_qp(sc->io[i]);
}