Date: Tue, 14 Apr 2026 09:14:19 +0000 From: Sumit Saxena <ssaxena@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 439132310ae1 - main - iflib: drain admin task and fix teardown order on register failure Message-ID: <69de056b.1eb43.38d63c8a@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by ssaxena: URL: https://cgit.FreeBSD.org/src/commit/?id=439132310ae1f623f6c0a3dc241d0a34e98e040b commit 439132310ae1f623f6c0a3dc241d0a34e98e040b Author: Sumit Saxena <ssaxena@FreeBSD.org> AuthorDate: 2026-04-13 06:33:46 +0000 Commit: Sumit Saxena <ssaxena@FreeBSD.org> CommitDate: 2026-04-14 09:13:53 +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. MFC after: 2 weeks Reviewed by: gallatin, kgalazka, #iflib Differential Revision: https://reviews.freebsd.org/D56316 --- 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 186c41d9f839..b58544255efd 100644 --- a/sys/net/iflib.c +++ b/sys/net/iflib.c @@ -5292,16 +5292,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:home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69de056b.1eb43.38d63c8a>
