From nobody Sun Aug 9 23:38:36 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4hJDq60QwXz6pHP4 for ; Sun, 09 Aug 2026 23:38:42 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hJDq55lH0z3fK1 for ; Sun, 09 Aug 2026 23:38:41 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1786318721; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=L9/bO5MdquYt8L9+3VK+Imb1lxtnATsy8SrHRU/GDiU=; b=YpJ6KDqtMXikuxGc+SbjrvoTgGYDS1b5fWGYlqCK8O4jUqiXlngJHkHn9JY1XHAGNeuEJn M2D9Yy7piv6tgZ1VqNonWRG4pTO6Ga+8gZGkgG12j3bO9wFDjCpiMAVEVKQGo/BEoaxOC7 CaXHLosJySecoTXBXgxnrNPgxWQU1EyOaW7iOx/ZAhE4/5dS+JwVWFo6W7lF+TdOvjB7FS sJIRiOd+/71grTlJ68yeMClNTatsUZdLo2DaVsHErqhsUwI1itdlOLfkJyKgFHbAnAybOM GY/6Ay/gM2td+Cs/hrHuZLRI8xKGjAEjUnaxF2Qka2hHMUoMV58AnpnHgpeGJw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1786318721; a=rsa-sha256; cv=none; b=THopkx+fKyJKp4IlbVnoYpK7D1cuN/wGZcj6Dpm0nIhpcJYnL2ty2A+l4QI9Mnsuln5Wvk 9esO5eXYGwJSHyEL8/i/hO/ZoHleJ/AbXYKIf1sLxVUyDQ+xalOqZcDwuCOL+ODGj6bHL7 FJaqSj8uvmtFdqn5Kk6nHN2vUz/UPbzR4GFZKhKdP4lKi0VNwOR9d/YyBivCPPRacn1499 4iYyQDUCYG1z1seJGU4salbIVzcjJEq8CKLrwkcbQZL244gogJzutop6O9OBOwA72moYly sD3r5SWgZSahWduWu0RmSozfugQaLD326PXrHoGjkX73IhMApNTnC0KUrzThBw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1786318721; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=L9/bO5MdquYt8L9+3VK+Imb1lxtnATsy8SrHRU/GDiU=; b=VbCxrgrHSryYyMfcIHRjpLGruttmwxxhe0tSg+bEe/JRtpyBH38VK6rLj9TcJR61SwFxRj fvUH+XUZk+0wiM2SnQ85FK0Cein+aGCYXvvUkSKwY9KbgF/h3kI8i1HU6PnLdiqrTqit6r WkcYzXdHStNarDWqH7bdgS5k3facKuXOU5LwMdYIvwi2dPdg6tLrTWx176FMCSrtmUybBb XWkJLjD4OQO444e5JbCwnMsBLCRnJuygTTZLwKGnF3yopoTlLBKL0CWaVqJqRplkRHp1fO Stc323W0uk+uij80MlTMGpXQczjTsbCs0y+MtZeXmzKKd861OAeO3QZ96OCQ/g== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hJDq54JTZzlTh for ; Sun, 09 Aug 2026 23:38:41 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 3a865 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sun, 09 Aug 2026 23:38:36 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kevin Bowling Subject: git: 9328a7eedba1 - main - iflib: Support recoverable initialization failure List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kbowling X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 9328a7eedba115040312bd1ea368371a0dbd0cac Auto-Submitted: auto-generated Date: Sun, 09 Aug 2026 23:38:36 +0000 Message-Id: <6a790f7c.3a865.f2736ce@gitrepo.freebsd.org> The branch main has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=9328a7eedba115040312bd1ea368371a0dbd0cac commit 9328a7eedba115040312bd1ea368371a0dbd0cac Author: Kevin Bowling AuthorDate: 2026-08-09 07:16:56 +0000 Commit: Kevin Bowling CommitDate: 2026-08-09 23:38:29 +0000 iflib: Support recoverable initialization failure The ifdi_init method cannot report an error, so iflib always marks an interface running and enables its interrupts after the callback returns. Drivers whose hardware initialization depends on an unavailable peer can only return early and leave a falsely running interface. Add iflib_init_failed() so a callback can leave the interface stopped. Also add a conditional reset request for asynchronous recovery: it is discarded if the interface is administratively down when the admin task runs, preventing a queued retry from resurrecting a stopped interface. Do not restore saved driver flags after an MTU or capability change when initialization failed. Restoring the pre-init flags would overwrite the stopped result with stale RUNNING state. Document that reset requests require the caller to schedule the admin task, that output remains blocked during recovery, and that iflib rather than the driver owns the driver flags. MFC after: 2 weeks --- share/man/man9/Makefile | 3 +++ share/man/man9/iflibdd.9 | 11 +++++++---- share/man/man9/iflibdi.9 | 35 ++++++++++++++++++++++++++++++++++ sys/net/iflib.c | 49 ++++++++++++++++++++++++++++++++++++++++++------ sys/net/iflib.h | 5 +++++ 5 files changed, 93 insertions(+), 10 deletions(-) diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile index 6df531d5300c..1deb3d048f12 100644 --- a/share/man/man9/Makefile +++ b/share/man/man9/Makefile @@ -1355,8 +1355,11 @@ MLINKS+=iflibdi.9 iflib_add_int_delay_sysctl.9 \ iflibdi.9 iflib_led_create.9 \ iflibdi.9 iflib_irq_alloc.9 \ iflibdi.9 iflib_irq_alloc_generic.9 \ + iflibdi.9 iflib_init_failed.9 \ iflibdi.9 iflib_link_intr_deferred.9 \ iflibdi.9 iflib_link_state_change.9 \ + iflibdi.9 iflib_request_reset.9 \ + iflibdi.9 iflib_request_reset_if_up.9 \ iflibdi.9 iflib_rx_intr_deferred.9 \ iflibdi.9 iflib_tx_intr_deferred.9 MLINKS+=iflibtxrx.9 isc_rxd_available.9 \ diff --git a/share/man/man9/iflibdd.9 b/share/man/man9/iflibdd.9 index 67645fe5c87a..7777cbaa0022 100644 --- a/share/man/man9/iflibdd.9 +++ b/share/man/man9/iflibdd.9 @@ -1,4 +1,4 @@ -.Dd May 3, 2018 +.Dd August 8, 2026 .Dt IFLIBDD 9 .Os .Sh NAME @@ -245,9 +245,12 @@ Optional function that resumes a driver. .It Fn ifdi_init Mandatory function that will initialize and bring up the hardware. For example, it will reset the chip and enable the receiver unit. -It should mark the interface running, but not active ( -.Dv IFF_DRV_RUNNING , -.Dv ~IIF_DRV_OACTIVE ). +Iflib marks the interface running after the callback returns successfully; +the driver must not modify the driver flags itself. +If initialization cannot complete, the driver must leave the hardware stopped +and call +.Fn iflib_init_failed +before returning. .It Fn ifdi_stop Mandatory function that should disable all traffic on the interface by issuing a global reset on the MAC and deallocating the TX and RX buffers. diff --git a/share/man/man9/iflibdi.9 b/share/man/man9/iflibdi.9 index b148f74c560b..edc2c7f172f1 100644 --- a/share/man/man9/iflibdi.9 +++ b/share/man/man9/iflibdi.9 @@ -6,6 +6,7 @@ .Nd Device Independent Configuration Functions .Sh SYNOPSIS .In "ifdi_if.h" +.In "net/iflib.h" .Ss "Device Independent Functions" .Ft int .Fo iflib_device_attach @@ -80,6 +81,18 @@ .Fa "int linkstate" .Fc .Ft void +.Fo iflib_request_reset +.Fa "if_ctx_t ctx" +.Fc +.Ft void +.Fo iflib_request_reset_if_up +.Fa "if_ctx_t ctx" +.Fc +.Ft void +.Fo iflib_init_failed +.Fa "if_ctx_t ctx" +.Fc +.Ft void .Fo iflib_add_int_delay_sysctl .Fa "if_ctx_t ctx" .Fa "const char *" @@ -225,6 +238,28 @@ The following link states are currently defined: The link is up. .It Dv LINK_STATE_DOWN The link is down. +.It Fn iflib_request_reset +Request that the admin task stop and reinitialize the interface. +.It Fn iflib_request_reset_if_up +Request that the admin task stop and reinitialize the interface only if it +remains administratively up when the task runs. +This form is suitable for asynchronous recovery work that must not restart an +interface after an intervening administrative down operation. +Like +.Fn iflib_request_reset , +this function only records the request; the caller must schedule the admin +task, normally with +.Fn iflib_admin_intr_deferred . +.It Fn iflib_init_failed +Report that the current +.Fn ifdi_init +callback could not initialize the hardware. +The driver must leave the hardware stopped and call this function while the +callback holds the iflib context lock. +Iflib then leaves +.Dv IFF_DRV_RUNNING +clear and does not enable interrupts or periodic timers. +Output remains blocked so explicitly scheduled admin recovery work can run. .It Fn iflib_add_int_delay_sysctl Modifies settings to user defined values for a given set of variables. .El diff --git a/sys/net/iflib.c b/sys/net/iflib.c index 8322dbfb074d..00f4f2921dd2 100644 --- a/sys/net/iflib.c +++ b/sys/net/iflib.c @@ -337,13 +337,13 @@ typedef struct iflib_sw_tx_desc_array { #define IFC_LEGACY 0x001 #define IFC_QFLUSH 0x002 #define IFC_MULTISEG 0x004 -#define IFC_SPARE1 0x008 +#define IFC_INIT_FAILED 0x008 #define IFC_SC_ALLOCATED 0x010 #define IFC_INIT_DONE 0x020 #define IFC_PREFETCH 0x040 #define IFC_DO_RESET 0x080 #define IFC_DO_WATCHDOG 0x100 -#define IFC_SPARE0 0x200 +#define IFC_DO_RESET_IF_UP 0x200 #define IFC_SPARE2 0x400 #define IFC_IN_DETACH 0x800 @@ -2555,6 +2555,7 @@ iflib_init_locked(if_ctx_t ctx) iflib_txq_t txq; iflib_rxq_t rxq; int i, j, tx_ip_csum_flags, tx_ip6_csum_flags; + bool init_failed; if_setdrvflagbits(ifp, IFF_DRV_OACTIVE, IFF_DRV_RUNNING); IFDI_INTR_DISABLE(ctx); @@ -2598,8 +2599,16 @@ iflib_init_locked(if_ctx_t ctx) #ifdef INVARIANTS i = if_getdrvflags(ifp); #endif + STATE_LOCK(ctx); + ctx->ifc_flags &= ~IFC_INIT_FAILED; + STATE_UNLOCK(ctx); IFDI_INIT(ctx); MPASS(if_getdrvflags(ifp) == i); + STATE_LOCK(ctx); + init_failed = (ctx->ifc_flags & IFC_INIT_FAILED) != 0; + STATE_UNLOCK(ctx); + if (init_failed) + return; for (i = 0, rxq = ctx->ifc_rxqs; i < scctx->isc_nrxqsets; i++, rxq++) { if (iflib_netmap_rxq_init(ctx, rxq) > 0) { /* This rxq is in netmap mode. Skip normal init. */ @@ -4187,15 +4196,18 @@ _task_fn_admin(void *context, int pending) if_softc_ctx_t sctx = &ctx->ifc_softc_ctx; iflib_txq_t txq; int i; - bool oactive, running, do_reset, do_watchdog, in_detach; + bool oactive, running, do_reset, do_reset_if_up, do_watchdog; + bool in_detach; STATE_LOCK(ctx); running = (if_getdrvflags(ctx->ifc_ifp) & IFF_DRV_RUNNING); oactive = (if_getdrvflags(ctx->ifc_ifp) & IFF_DRV_OACTIVE); do_reset = (ctx->ifc_flags & IFC_DO_RESET); + do_reset_if_up = (ctx->ifc_flags & IFC_DO_RESET_IF_UP); do_watchdog = (ctx->ifc_flags & IFC_DO_WATCHDOG); in_detach = (ctx->ifc_flags & IFC_IN_DETACH); - ctx->ifc_flags &= ~(IFC_DO_RESET | IFC_DO_WATCHDOG); + ctx->ifc_flags &= ~(IFC_DO_RESET | IFC_DO_RESET_IF_UP | + IFC_DO_WATCHDOG); STATE_UNLOCK(ctx); if ((!running && !oactive) && !(ctx->ifc_sctx->isc_flags & IFLIB_ADMIN_ALWAYS_RUN)) @@ -4204,6 +4216,9 @@ _task_fn_admin(void *context, int pending) return; CTX_LOCK(ctx); + if (!do_reset && do_reset_if_up && + (if_getflags(ctx->ifc_ifp) & IFF_UP) != 0) + do_reset = true; for (txq = ctx->ifc_txqs, i = 0; i < sctx->isc_ntxqsets; i++, txq++) { CALLOUT_LOCK(txq); callout_stop(&txq->ift_timer); @@ -4529,7 +4544,9 @@ iflib_if_ioctl(if_t ifp, u_long command, caddr_t data) } iflib_init_locked(ctx); STATE_LOCK(ctx); - if_setdrvflags(ifp, bits); + /* Preserve the stopped state reported by iflib_init_failed(). */ + if ((ctx->ifc_flags & IFC_INIT_FAILED) == 0) + if_setdrvflags(ifp, bits); STATE_UNLOCK(ctx); CTX_UNLOCK(ctx); break; @@ -4638,7 +4655,8 @@ iflib_if_ioctl(if_t ifp, u_long command, caddr_t data) if (bits & IFF_DRV_RUNNING && setmask & ~IFCAP_WOL) iflib_init_locked(ctx); STATE_LOCK(ctx); - if_setdrvflags(ifp, bits); + if ((ctx->ifc_flags & IFC_INIT_FAILED) == 0) + if_setdrvflags(ifp, bits); STATE_UNLOCK(ctx); CTX_UNLOCK(ctx); } @@ -7220,6 +7238,25 @@ iflib_request_reset(if_ctx_t ctx) STATE_UNLOCK(ctx); } +void +iflib_request_reset_if_up(if_ctx_t ctx) +{ + + STATE_LOCK(ctx); + ctx->ifc_flags |= IFC_DO_RESET_IF_UP; + STATE_UNLOCK(ctx); +} + +void +iflib_init_failed(if_ctx_t ctx) +{ + + sx_assert(&ctx->ifc_ctx_sx, SA_XLOCKED); + STATE_LOCK(ctx); + ctx->ifc_flags |= IFC_INIT_FAILED; + STATE_UNLOCK(ctx); +} + #ifndef __NO_STRICT_ALIGNMENT static struct mbuf * iflib_fixup_rx(struct mbuf *m) diff --git a/sys/net/iflib.h b/sys/net/iflib.h index 6e9c6e10cc5d..40080b49b0ab 100644 --- a/sys/net/iflib.h +++ b/sys/net/iflib.h @@ -428,6 +428,11 @@ if_shared_ctx_t iflib_get_sctx(if_ctx_t ctx); void iflib_set_mac(if_ctx_t ctx, uint8_t mac[ETHER_ADDR_LEN]); void iflib_request_reset(if_ctx_t ctx); +/* Defer a reset, but discard it if the interface is administratively down. */ +void iflib_request_reset_if_up(if_ctx_t ctx); + +/* Report an error from the otherwise void ifdi_init method while it runs. */ +void iflib_init_failed(if_ctx_t ctx); uint8_t iflib_in_detach(if_ctx_t ctx); uint32_t iflib_get_rx_mbuf_sz(if_ctx_t ctx);