The branch stable/14 has been updated by kbowling:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=18c03a9df09db380eb77a45d5f654d8af66a60c9

commit 18c03a9df09db380eb77a45d5f654d8af66a60c9
Author:     Sumit Saxena <[email protected]>
AuthorDate: 2026-04-13 06:33:46 +0000
Commit:     Kevin Bowling <[email protected]>
CommitDate: 2026-08-28 02:20:51 +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 0a446adffc9c..0ed570adcff8 100644
--- a/sys/net/iflib.c
+++ b/sys/net/iflib.c
@@ -5439,16 +5439,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:

Reply via email to