git: 4fba78389e5a - stable/15 - iflib: drain admin task and fix teardown order on register failure
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 28 Aug 2026 02:12:17 UTC
The branch stable/15 has been updated by kbowling:
URL: https://cgit.FreeBSD.org/src/commit/?id=4fba78389e5a307c1060fd7785cb560397e82691
commit 4fba78389e5a307c1060fd7785cb560397e82691
Author: Sumit Saxena <ssaxena@FreeBSD.org>
AuthorDate: 2026-04-13 06:33:46 +0000
Commit: Kevin Bowling <kbowling@FreeBSD.org>
CommitDate: 2026-08-28 02:10:52 +0000
iflib: drain admin task and fix teardown order on register failure
When IFDI_ATTACH_POST() fails (or netmap attach fails), iflib tears down with
ether_ifdetach(), taskqueue_free(ifc_tq), and IFDI_DETACH(). CTX_LOCK is still
held after ether_ifattach. ether_ifdetach() and taskqueue_drain(admin) must not
run under CTX_LOCK.
Teardown ordering (match iflib_device_deregister):
- Free the per-interface admin taskqueue after IFDI_DETACH / IFDI_QUEUES_FREE, not before.
- Drop IFNET_WLOCK() across IFDI_DETACH / IFDI_QUEUES_FREE so driver detach can sleep in
LinuxKPI workqueue drain, then retake IFNET_WLOCK() before iflib_free_intr_mem and fail_unlock.
Reviewed by: gallatin, kgalazka, #iflib
Differential Revision: https://reviews.freebsd.org/D56316
(cherry picked from commit 439132310ae1f623f6c0a3dc241d0a34e98e040b)
---
sys/net/iflib.c | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/sys/net/iflib.c b/sys/net/iflib.c
index bb9191a2da31..4726ca5bfaa9 100644
--- a/sys/net/iflib.c
+++ b/sys/net/iflib.c
@@ -5299,16 +5299,33 @@ iflib_device_register(device_t dev, void *sc, if_shared_ctx_t sctx, if_ctx_t *ct
return (0);
fail_detach:
+ CTX_UNLOCK(ctx);
+ taskqueue_drain(ctx->ifc_tq, &ctx->ifc_admin_task);
ether_ifdetach(ctx->ifc_ifp);
+ CTX_LOCK(ctx);
fail_queues:
sysctl_ctx_free(&ctx->ifc_sysctl_ctx);
ctx->ifc_sysctl_node = NULL;
- taskqueue_free(ctx->ifc_tq);
+ /*
+ * Drain without holding CTX_LOCK so _task_fn_admin can run to
+ * completion if it needs the context lock. On fail_detach we already
+ * drained above; a second drain is a no-op when the queue is empty.
+ */
+ CTX_UNLOCK(ctx);
+ taskqueue_drain(ctx->ifc_tq, &ctx->ifc_admin_task);
+ CTX_LOCK(ctx);
iflib_tqg_detach(ctx);
iflib_tx_structures_free(ctx);
iflib_rx_structures_free(ctx);
+ /*
+ * Match iflib_device_deregister: IFDI_DETACH before taskqueue_free.
+ * Avoid IFNET_WLOCK across driver detach (LinuxKPI workqueue drain).
+ */
+ IFNET_WUNLOCK();
IFDI_DETACH(ctx);
IFDI_QUEUES_FREE(ctx);
+ IFNET_WLOCK();
+ taskqueue_free(ctx->ifc_tq);
fail_intr_free:
iflib_free_intr_mem(ctx);
fail_unlock: