From nobody Sat Aug 8 07:12: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 4hHBzm4k0bz6n9Zw for ; Sat, 08 Aug 2026 07:12:36 +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 4hHBzm1kQ5z3nJc for ; Sat, 08 Aug 2026 07:12:36 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1786173156; 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=dtDHN3vT3YpbaQ7zI6BqH3SgQ4r0kd4PiJ2xb8RY+FU=; b=NTm2XFkseQ9I3h5fRqTTS4pjsg+sq+Rl/HPP6MyQqJFId4xcnzK2hIX7asYpvmwNusWLw5 eWpi2OgQW95rXse45JfFhpOM92w2RFSHK+Hdyu1B0KMyOCi/ErRtgObIss8lXp8Zo455q1 if+UClEbaE1lQ+BuA3YhjUBUYG85Ahq7peMfTRR94WL2MBakfDFP6/hYu2zvxrbal2PC9g 3uudfuyrbaJarzmyvkCw0m7ODEOfbhHlTxYWyi1ehIr2hMLF56owcL7Z/Zl538IRk8HuXz +rY7R0h2PTYazYtpt7YXRikX+vi2Y1iVTkg76blNPmHIy6CrSI4gOVQCYBNJ1w== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1786173156; a=rsa-sha256; cv=none; b=kh5v8mspvp8XO/qSNM0WCYrQUR6OicPuQC1breMsxtz//YHNEZW4SBe9sNcN7QU51ztR3g 3FkCHjCExsDWItU2XIyoFgXdZzc+lU0rhdxHhYkCQ8Ws4zKm5LhFTbV9dP1hdifib3udkB GwrWZDC0FuPy6fl08imcY64wPQJBBYUq1Us2nDmphNANpkvf9dXxLy/JKE5nICkFH8Jgz5 yw1aJR09MykzAnAwAeDxPZTERQ7Nw3MYFlx4EryYm2nbi0kvE2D9AXdMsjXTCgVj7szNx3 w0enHHLXrETFayYcBGAOgKr1wV+V+mbE80uAucEF0EEDroVG05mKq0hJSrMN4Q== 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=1786173156; 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=dtDHN3vT3YpbaQ7zI6BqH3SgQ4r0kd4PiJ2xb8RY+FU=; b=RrUbDOHKJ5CjYP4fBs9WopVtAhQ+NRk8E1mdrYDX0dqM32jf3VqC6AcRpsT/aBNR2KzNnE /NdFErrbVwQK07bImT8WyTMNs2hXkf8iguA/9rYYEQz05SghPplNBmBWCS5QEx5s0+tYJT vxVT2aBEPkXJjl1bHWYFNgd8mUlsopymiDJZvDfEMsaMdNiXJCEYsGLvdebaT3gAxPT+ql n3LHBAUnDuqdgUxSRn2befsMG5msbRBJrvyXRAoi1sb8mXK81SNniU5qFOQ9RFtYt5gXPK VQXAeitSaov1RQ9lOy/efDsclbIlFA+4djSD1es6cjAshjAqHmWe2tgpQSDzpg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hHBzm0fGnzCLJ for ; Sat, 08 Aug 2026 07:12:36 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 3e3fb by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sat, 08 Aug 2026 07:12:36 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kevin Bowling Subject: git: 2b763a82f9f2 - main - ixgbe: Handle deferred link-status requests 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: 2b763a82f9f21b722b50830bc22af2b2acf36746 Auto-Submitted: auto-generated Date: Sat, 08 Aug 2026 07:12:36 +0000 Message-Id: <6a76d6e4.3e3fb.535e3124@gitrepo.freebsd.org> The branch main has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=2b763a82f9f21b722b50830bc22af2b2acf36746 commit 2b763a82f9f21b722b50830bc22af2b2acf36746 Author: Kevin Bowling AuthorDate: 2026-08-06 08:22:21 +0000 Commit: Kevin Bowling CommitDate: 2026-08-08 07:07:31 +0000 ixgbe: Handle deferred link-status requests The iflib conversion records link-status interrupts in the administrative request mask, but the administrative task did not consume them. Timer polling usually hid the omission; frequent mailbox interrupts could continually rearm that timer and leave cached link state down after hardware recovered. Claim request batches atomically, process link-setup dependencies, and sample hardware before publishing link state. Bound each invocation to eight batches and requeue residual work so a continuous producer cannot monopolize the admin taskqueue. Queue every link-related request from the legacy interrupt path. Unlike MSI-X, its threaded continuation services RX and does not enqueue the admin task. This restores the event-driven behavior of ix-3.4.39. Fixes: b2c1e8e62049 ("ix(4): Run {mod,msf,mbx,fdir,phy}_task in if_update_admin_status") MFC after: 2 weeks --- sys/dev/ixgbe/if_ix.c | 133 +++++++++++++++++++++++++++++++------------------- 1 file changed, 83 insertions(+), 50 deletions(-) diff --git a/sys/dev/ixgbe/if_ix.c b/sys/dev/ixgbe/if_ix.c index e0e627b915d9..0c40feed48c9 100644 --- a/sys/dev/ixgbe/if_ix.c +++ b/sys/dev/ixgbe/if_ix.c @@ -51,6 +51,9 @@ ************************************************************************/ static const char ixgbe_driver_version[] = "5.0.1-k"; +/* Bound one admin-task invocation while still coalescing new requests. */ +#define IXGBE_ADMIN_TASK_BUDGET 8 + /************************************************************************ * PCI Device ID Table * @@ -280,9 +283,9 @@ static int ixgbe_sysctl_dump_debug_dump(SYSCTL_HANDLER_ARGS); /* Deferred interrupt tasklets */ static void ixgbe_handle_msf(void *); -static void ixgbe_handle_mod(void *); +static bool ixgbe_handle_mod(void *); static void ixgbe_handle_phy(void *); -static void ixgbe_handle_fw_event(void *); +static u32 ixgbe_handle_fw_event(void *); static int ixgbe_enable_lse(struct ixgbe_softc *sc); static int ixgbe_disable_lse(struct ixgbe_softc *sc); @@ -1838,7 +1841,7 @@ ixgbe_config_link(if_ctx_t ctx) if (sfp) { /* ixgbe_if_stop() disables it on every 82599 SFP port. */ ixgbe_enable_tx_laser(hw); - sc->task_requests |= IXGBE_REQUEST_TASK_MOD; + atomic_set_32(&sc->task_requests, IXGBE_REQUEST_TASK_MOD); iflib_admin_intr_deferred(ctx); } else { if (hw->mac.ops.check_link) @@ -3123,12 +3126,12 @@ ixgbe_msix_link(void *arg) /* Link status change */ if (eicr & IXGBE_EICR_LSC) { IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_LSC); - sc->task_requests |= IXGBE_REQUEST_TASK_LSC; + atomic_set_32(&sc->task_requests, IXGBE_REQUEST_TASK_LSC); } if (eicr & IXGBE_EICR_FW_EVENT) { IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EICR_FW_EVENT); - sc->task_requests |= IXGBE_REQUEST_TASK_FWEVENT; + atomic_set_32(&sc->task_requests, IXGBE_REQUEST_TASK_FWEVENT); } if (sc->hw.mac.type != ixgbe_mac_82598EB) { @@ -3139,7 +3142,7 @@ ixgbe_msix_link(void *arg) return (FILTER_HANDLED); /* Disable the interrupt */ IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EICR_FLOW_DIR); - sc->task_requests |= IXGBE_REQUEST_TASK_FDIR; + atomic_set_32(&sc->task_requests, IXGBE_REQUEST_TASK_FDIR); } else if (eicr & IXGBE_EICR_ECC) { device_printf(iflib_get_dev(sc->ctx), @@ -3190,7 +3193,7 @@ ixgbe_msix_link(void *arg) /* Check for VF message */ if ((sc->feat_en & IXGBE_FEATURE_SRIOV) && (eicr & IXGBE_EICR_MAILBOX)) { - sc->task_requests |= IXGBE_REQUEST_TASK_MBX; + atomic_set_32(&sc->task_requests, IXGBE_REQUEST_TASK_MBX); } } @@ -3207,14 +3210,14 @@ ixgbe_msix_link(void *arg) if (eicr & eicr_mask) { IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr_mask); - sc->task_requests |= IXGBE_REQUEST_TASK_MOD; + atomic_set_32(&sc->task_requests, IXGBE_REQUEST_TASK_MOD); } if ((hw->mac.type == ixgbe_mac_82599EB) && (eicr & IXGBE_EICR_GPI_SDP1_BY_MAC(hw))) { IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1_BY_MAC(hw)); - sc->task_requests |= IXGBE_REQUEST_TASK_MSF; + atomic_set_32(&sc->task_requests, IXGBE_REQUEST_TASK_MSF); } } @@ -3229,10 +3232,10 @@ ixgbe_msix_link(void *arg) if ((hw->phy.type == ixgbe_phy_x550em_ext_t) && (eicr & IXGBE_EICR_GPI_SDP0_X540)) { IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP0_X540); - sc->task_requests |= IXGBE_REQUEST_TASK_PHY; + atomic_set_32(&sc->task_requests, IXGBE_REQUEST_TASK_PHY); } - return (sc->task_requests != 0) ? + return (atomic_load_acq_32(&sc->task_requests) != 0) ? FILTER_SCHEDULE_THREAD : FILTER_HANDLED; } /* ixgbe_msix_link */ @@ -3986,10 +3989,9 @@ ixgbe_if_init(if_ctx_t ctx) ixgbe_initialize_receive_units(ctx); /* - * Initialize variable holding task enqueue requests - * from MSI-X interrupts + * Initialize the deferred administrative request mask. */ - sc->task_requests = 0; + atomic_store_rel_32(&sc->task_requests, 0); /* Enable SDP & MSI-X interrupts based on adapter */ ixgbe_config_gpie(sc); @@ -4548,7 +4550,7 @@ out: /************************************************************************ * ixgbe_handle_mod - Tasklet for SFP module interrupts ************************************************************************/ -static void +static bool ixgbe_handle_mod(void *context) { if_ctx_t ctx = context; @@ -4593,11 +4595,10 @@ ixgbe_handle_mod(void *context) "Setup failure - unsupported SFP+ module type.\n"); goto handle_mod_out; } - sc->task_requests |= IXGBE_REQUEST_TASK_MSF; - return; + return (true); handle_mod_out: - sc->task_requests &= ~(IXGBE_REQUEST_TASK_MSF); + return (false); } /* ixgbe_handle_mod */ @@ -4689,7 +4690,7 @@ s32 ixgbe_disable_lse(struct ixgbe_softc *sc) /************************************************************************ * ixgbe_handle_fw_event - Tasklet for MSI-X Link Status Event interrupts ************************************************************************/ -static void +static u32 ixgbe_handle_fw_event(void *context) { if_ctx_t ctx = context; @@ -4698,13 +4699,14 @@ ixgbe_handle_fw_event(void *context) struct ixgbe_aci_event event; bool pending = false; s32 error; + u32 requests = 0; event.buf_len = IXGBE_ACI_MAX_BUFFER_SIZE; event.msg_buf = malloc(event.buf_len, M_IXGBE, M_ZERO | M_NOWAIT); if (!event.msg_buf) { device_printf(sc->dev, "Can not allocate buffer for " "event message\n"); - return; + return (0); } do { @@ -4717,7 +4719,7 @@ ixgbe_handle_fw_event(void *context) switch (le16toh(event.desc.opcode)) { case ixgbe_aci_opc_get_link_status: - sc->task_requests |= IXGBE_REQUEST_TASK_LSC; + requests |= IXGBE_REQUEST_TASK_LSC; break; case ixgbe_aci_opc_fw_logs_event: @@ -4741,6 +4743,7 @@ ixgbe_handle_fw_event(void *context) } while (pending); free(event.msg_buf, M_IXGBE); + return (requests); } /* ixgbe_handle_fw_event */ /************************************************************************ @@ -4812,15 +4815,61 @@ ixgbe_link_speed_to_str(u32 link_speed) /************************************************************************ * ixgbe_update_link_status - Update OS on link state * - * Note: Only updates the OS on the cached link state. - * The real check of the hardware only happens with - * a link interrupt. + * Process deferred administrative requests and update the OS link state. ************************************************************************/ static void ixgbe_if_update_admin_status(if_ctx_t ctx) { struct ixgbe_softc *sc = iflib_get_softc(ctx); device_t dev = iflib_get_dev(ctx); + u32 requests; + u_int pass; + bool check_link = false; + + /* + * The interrupt filter and other producers can run concurrently with + * this task. Claim each batch atomically so a request posted while the + * task is running remains pending for this or the next invocation. + * + * MOD and firmware events can produce dependent requests. Fold those + * into the claimed batch so link state is sampled after any link setup. + */ + if ((if_getdrvflags(iflib_get_ifp(ctx)) & IFF_DRV_RUNNING) != 0 && + (sc->iov_mbx_cleanup_pending || ixgbe_mbx_pending(sc))) + atomic_set_32(&sc->task_requests, IXGBE_REQUEST_TASK_MBX); + for (pass = 0; pass < IXGBE_ADMIN_TASK_BUDGET; pass++) { + requests = atomic_readandclear_32(&sc->task_requests); + if (requests == 0) + break; + if (requests & IXGBE_REQUEST_TASK_FWEVENT) + requests |= ixgbe_handle_fw_event(ctx); + if (requests & IXGBE_REQUEST_TASK_MOD) { + if (ixgbe_handle_mod(ctx)) + requests |= IXGBE_REQUEST_TASK_MSF; + else + requests &= ~IXGBE_REQUEST_TASK_MSF; + } + if (requests & IXGBE_REQUEST_TASK_MSF) + ixgbe_handle_msf(ctx); + /* A reset request can re-enable VF traffic; skip it while stopped. */ + if ((requests & IXGBE_REQUEST_TASK_MBX) != 0 && + (if_getdrvflags(iflib_get_ifp(ctx)) & IFF_DRV_RUNNING) != 0) + ixgbe_handle_mbx(ctx); + if (requests & IXGBE_REQUEST_TASK_FDIR) + ixgbe_reinit_fdir(ctx); + if (requests & IXGBE_REQUEST_TASK_PHY) + ixgbe_handle_phy(ctx); + if (requests & IXGBE_REQUEST_TASK_LSC) + check_link = true; + } + + /* Do not let a continuous producer monopolize the admin taskqueue. */ + if (atomic_load_acq_32(&sc->task_requests) != 0) + iflib_admin_intr_deferred(ctx); + + if (check_link) + ixgbe_check_link(&sc->hw, &sc->link_speed, &sc->link_up, + false); if (sc->link_up) { if (sc->link_active == false) { @@ -4864,27 +4913,6 @@ ixgbe_if_update_admin_status(if_ctx_t ctx) } } - /* Handle task requests from msix_link() */ - if (sc->task_requests & IXGBE_REQUEST_TASK_FWEVENT) - ixgbe_handle_fw_event(ctx); - if (sc->task_requests & IXGBE_REQUEST_TASK_MOD) - ixgbe_handle_mod(ctx); - if (sc->task_requests & IXGBE_REQUEST_TASK_MSF) - ixgbe_handle_msf(ctx); - /* - * A reset request re-enables VF traffic, so do not service mailboxes - * while the PF is stopped. VFREQ, VFACK, and VFLR are hardware-latched - * and ixgbe_mbx_pending() resamples them after the PF is running again. - */ - if ((if_getdrvflags(iflib_get_ifp(ctx)) & IFF_DRV_RUNNING) != 0 && - ((sc->task_requests & IXGBE_REQUEST_TASK_MBX) != 0 || - sc->iov_mbx_cleanup_pending || ixgbe_mbx_pending(sc))) - ixgbe_handle_mbx(ctx); - if (sc->task_requests & IXGBE_REQUEST_TASK_FDIR) - ixgbe_reinit_fdir(ctx); - if (sc->task_requests & IXGBE_REQUEST_TASK_PHY) - ixgbe_handle_phy(ctx); - sc->task_requests = 0; ixgbe_schedule_iov_recovery(sc); ixgbe_update_stats_counters(sc); @@ -5109,9 +5137,10 @@ ixgbe_intr(void *arg) struct ix_rx_queue *que = sc->rx_queues; struct ixgbe_hw *hw = &sc->hw; if_ctx_t ctx = sc->ctx; - u32 eicr, eicr_mask; + u32 eicr, eicr_mask, requests; eicr = IXGBE_READ_REG(hw, IXGBE_EICR); + requests = 0; ++que->irqs; if (eicr == 0) { @@ -5131,7 +5160,7 @@ ixgbe_intr(void *arg) /* Link status change */ if (eicr & IXGBE_EICR_LSC) { IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_LSC); - iflib_admin_intr_deferred(ctx); + requests |= IXGBE_REQUEST_TASK_LSC; } if (ixgbe_is_sfp(hw)) { @@ -5143,21 +5172,25 @@ ixgbe_intr(void *arg) if (eicr & eicr_mask) { IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr_mask); - sc->task_requests |= IXGBE_REQUEST_TASK_MOD; + requests |= IXGBE_REQUEST_TASK_MOD; } if ((hw->mac.type == ixgbe_mac_82599EB) && (eicr & IXGBE_EICR_GPI_SDP1_BY_MAC(hw))) { IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1_BY_MAC(hw)); - sc->task_requests |= IXGBE_REQUEST_TASK_MSF; + requests |= IXGBE_REQUEST_TASK_MSF; } } /* External PHY interrupt */ if ((hw->phy.type == ixgbe_phy_x550em_ext_t) && (eicr & IXGBE_EICR_GPI_SDP0_X540)) { - sc->task_requests |= IXGBE_REQUEST_TASK_PHY; + requests |= IXGBE_REQUEST_TASK_PHY; + } + if (requests != 0) { + atomic_set_32(&sc->task_requests, requests); + iflib_admin_intr_deferred(ctx); } return (FILTER_SCHEDULE_THREAD);