git: ac56d36007a5 - main - iflib: Add an admin task detach fail point

From: Kevin Bowling <kbowling_at_FreeBSD.org>
Date: Fri, 14 Aug 2026 22:17:55 UTC
The branch main has been updated by kbowling:

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

commit ac56d36007a5a1a01fe69df370f272060e852e0b
Author:     Kevin Bowling <kbowling@FreeBSD.org>
AuthorDate: 2026-08-08 06:18:26 +0000
Commit:     Kevin Bowling <kbowling@FreeBSD.org>
CommitDate: 2026-08-14 22:17:04 +0000

    iflib: Add an admin task detach fail point
    
    Add an exact-device fail point immediately after the admin task checks
    IFC_IN_DETACH. This makes the detach race reproducible without affecting
    another interface.
    
    Use a bounded delay to keep the task active while detach enters the
    taskqueue drain.  Mark the point nonsleepable as a safety backstop, and
    document a one-shot test for verifying that deregistration drains an
    already-running task before ether_ifdetach().
    
    Reviewed by:    gallatin, kgalazka
    MFC after:      2 weeks
    Sponsored by:   BBOX.io
    Differential Revision:  https://reviews.freebsd.org/D58720
---
 share/man/man4/iflib.4 | 19 +++++++++++++++++++
 sys/net/iflib.c        | 11 +++++++++++
 2 files changed, 30 insertions(+)

diff --git a/share/man/man4/iflib.4 b/share/man/man4/iflib.4
index 031e33a2409e..4cf08602fd04 100644
--- a/share/man/man4/iflib.4
+++ b/share/man/man4/iflib.4
@@ -286,6 +286,25 @@ devctl attach pci0:4:0:0       # succeeds
 .Pp
 After detach, a device may no longer have its former name.
 Use a bus-specific address, as shown in the PCI example above, to reprobe it.
+.Pp
+The normal detach path can be synchronized with an in-flight admin task to
+test taskqueue teardown.
+Set
+.Va debug.fail_point.iflib.admin_task_device
+to the exact device name, bring the interface up, and set
+.Va debug.fail_point.iflib.admin_task_after_detach_check
+to a one-shot bounded delay, such as
+.Ql 1*print(1)->1*delay(5000000) .
+The delay keeps the admin task active long enough for detach to begin and
+remain blocked in the taskqueue drain.
+As a safety backstop, this fail point is marked nonsleepable and converts a
+configured
+.Sy sleep
+action to a delay.
+Once the execution message appears in the system log,
+detach should wait for the delay to finish.
+This exercises the case where an admin task has passed its detach check but
+has not yet acquired the context lock.
 .Sh SEE ALSO
 .Xr devctl 8 ,
 .Xr fail 9 ,
diff --git a/sys/net/iflib.c b/sys/net/iflib.c
index cda60f174a31..9efd4b56c5d1 100644
--- a/sys/net/iflib.c
+++ b/sys/net/iflib.c
@@ -575,6 +575,12 @@ SYSCTL_STRING(_debug_fail_point_iflib, OID_AUTO, register_device,
     iflib_register_fail_device, sizeof(iflib_register_fail_device),
     "device name eligible for registration fail points");
 
+static char iflib_admin_task_fail_device[32];
+SYSCTL_STRING(_debug_fail_point_iflib, OID_AUTO, admin_task_device,
+    CTLFLAG_RW | CTLFLAG_MPSAFE,
+    iflib_admin_task_fail_device, sizeof(iflib_admin_task_fail_device),
+    "device name eligible for admin task fail points");
+
 /*
  * XXX need to ensure that this can't accidentally cause the head to be moved backwards
  */
@@ -4233,6 +4239,11 @@ _task_fn_admin(void *context, int pending)
 		return;
 	if (in_detach)
 		return;
+	KFAIL_POINT_CODE_COND(_debug_fail_point_iflib,
+	    admin_task_after_detach_check,
+	    iflib_admin_task_fail_device[0] != '\0' &&
+	    strcmp(device_get_nameunit(ctx->ifc_dev),
+	    iflib_admin_task_fail_device) == 0, FAIL_POINT_NONSLEEPABLE, {});
 
 	CTX_LOCK(ctx);
 	if (!do_reset && do_reset_if_up &&