From nobody Sat Oct 31 23:30:08 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 4jHDj22VFFz6xZps for ; Sat, 31 Oct 2026 23:30:14 +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) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 4jHDj16kYTz4X0K for ; Sat, 31 Oct 2026 23:30:13 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1793489414; 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=G/p+ViDaxNZeP2xQH0ofqJ1b6pwkYHOPfgLTm+QINZY=; b=n+UaeLwIEihFxE3jKPQ4mgk/+3P3zPnj+/dnDLbftcE5nvZIgI0xx8Ux6Hn8/U6wxWgZL/ TcDSb/EhVoi1JntLC5kPG6dBzJHxMEnynls3dZ2hlfvxuQ45Q4jQCHScB11z63Pf9sAwJZ HBbCHDBB7McAK+7TA4TYhM5WohKGxpdnprezZwXuMnltbcmmZX2/g3BxQnJH65XKAQ06/C SkES91s7QVPzfP5KMMMNTB6tzMZ8SuvSOHHPn17gJf7jiKkwI+jmZW4uRigxxrRVojOVcm 6oegHwo4EHmfhQFw5N0niyZEMKoP03o6umxkVSr8JxgQSQSV/kVAhBvippYegg== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1793489414; b=gYOwva89n8WvRs8UcC1Ms8+Ct6kruNyrJX3XcSyRsTH0Gm9dHs61paumXsNLuPu0QJxQoq eIE6fP99Zet5lBzQvo/1e6Mvf8nZf3TyhQ2WFJ03KKGKamux6mgMKFZtniJ9zkN6ivMaBR Zu8yVj94Nmva1LRy9dgPUCppymKtlK1zoCsn6Tvw8gtXFM83VEcQJunAaZ5++mOZUR0o5o /5fgB8z7+PJ91+WObN50M2nCOBzIdCoVs6Grd2udelahm9XtnFyksDDuR6IOh6gWpvYHp0 6aV5KT+B62GodZEsu2q2+Sx6VMBJ1xqPdnrM2fpkpozq8WSlEAzI/eHsTxsY/g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1793489414; 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=G/p+ViDaxNZeP2xQH0ofqJ1b6pwkYHOPfgLTm+QINZY=; b=sjF9Bptl6m2D+qdO9hW+CXW5qXRqCRL1fbsuCHe39peW4o1b/ttT+zBs/Cm1W+eXbwFvWM 3OBEKKAMOsgWYU/p7I6fM+HJKi/MJu/Y8kLZNgtk9YwISgB4noztsXe4lmjzhDJ92CLGi2 W6WdiqDf3wj61/4iWSwNzIPB98VThZS3fneexVL60zvZrhJVoRjN5/oe+E0dkcSp0m1M4g frWR2onvwYLzrkKG9d4cLpBcRpik03pNl4PjEwsJDiSGjBTcV2F+AWjS+k8P0ZZkmSJNq6 fpU1Es7caR9Snvpi2xjzRukXNINN+m2eroQM3dwzWElLuH9+VGVdh7jJuqZ8tg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4jHDj163LwzZJb for ; Sat, 31 Oct 2026 23:30:13 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 478b5 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sat, 31 Oct 2026 23:30:08 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kevin Bowling Subject: git: a0f2994b312e - main - iavf: Report the programmed VF RSS configuration List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: Commit messages for all branches of the src repository 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: a0f2994b312e5a78ffce7dd7bc4521455edbc2cd Auto-Submitted: auto-generated Date: Sat, 31 Oct 2026 23:30:08 +0000 Message-Id: <6ae67a00.478b5.2eef28d6@gitrepo.freebsd.org> The branch main has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=a0f2994b312e5a78ffce7dd7bc4521455edbc2cd commit a0f2994b312e5a78ffce7dd7bc4521455edbc2cd Author: Kevin Bowling AuthorDate: 2026-10-31 23:27:44 +0000 Commit: Kevin Bowling CommitDate: 2026-10-31 23:28:22 +0000 iavf: Report the programmed VF RSS configuration Implement the iflib RSS key and hash query methods for register-based and PF-managed RSS. Cache the programmed key and HENA selections so hn can synchronize its synthetic RSS configuration with the VF without reading hardware or issuing mailbox requests from the query path. For PF-managed RSS, publish the snapshot only after successful replies to both CONFIG_RSS_KEY and SET_RSS_HENA. Failed sends, rejected requests, and missing replies leave it unavailable. Protect the snapshot with vc_mtx and invalidate it at init, stop, mailbox loss, and reset notification. Gate queries with the existing running, reset, and mailbox state. Report the first 40 key bytes used by standard IPv4/IPv6 tuples, or the shorter key length supplied by the PF. Preserve register byte order and report the merged HENA on the direct-programming path. Translate the six representable IPv4/IPv6 TCP/UDP selections without treating fragment PCTYPEs as IPv6 extension-header selections. The single-queue register path reports RSS_FUNC_NONE. Leave RSS policy and queue distribution unchanged. Queries return ENXIO until the current configuration is confirmed, without waiting for a PF reply themselves. MFC after: 2 weeks Sponsored by: BBOX.io Differential Revision: https://reviews.freebsd.org/D59808 --- sys/dev/iavf/iavf_iflib.h | 8 +++++ sys/dev/iavf/iavf_lib.c | 25 +++++++++++++ sys/dev/iavf/iavf_vc_common.c | 50 ++++++++++++++++++++++---- sys/dev/iavf/if_iavf_iflib.c | 84 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 161 insertions(+), 6 deletions(-) diff --git a/sys/dev/iavf/iavf_iflib.h b/sys/dev/iavf/iavf_iflib.h index bbd05e8279ca..3b4de1c8bca7 100644 --- a/sys/dev/iavf/iavf_iflib.h +++ b/sys/dev/iavf/iavf_iflib.h @@ -366,6 +366,13 @@ struct iavf_sc { struct virtchnl_vf_resource *vf_res; struct virtchnl_vsi_resource *vsi_res; + /* RSS query snapshot and outstanding requests, protected by vc_mtx. */ + u8 rss_key[RSS_KEYSIZE]; + u16 rss_key_size; + u64 rss_hena; + u32 rss_pending; + u32 rss_configured; + /* Misc stats maintained by the driver */ u64 admin_irq; @@ -407,4 +414,5 @@ void iavf_add_queues_sysctls(device_t dev, struct iavf_vsi *vsi); void iavf_enable_intr(struct iavf_vsi *); void iavf_disable_intr(struct iavf_vsi *); +void iavf_invalidate_rss(struct iavf_sc *); #endif /* _IAVF_IFLIB_H_ */ diff --git a/sys/dev/iavf/iavf_lib.c b/sys/dev/iavf/iavf_lib.c index c23e14a47444..01d14a58f0b9 100644 --- a/sys/dev/iavf/iavf_lib.c +++ b/sys/dev/iavf/iavf_lib.c @@ -1083,6 +1083,11 @@ iavf_config_rss_reg(struct iavf_sc *sc) u32 rss_seed[IAVF_RSS_KEY_SIZE_REG] = {0}; u32 rss_hash_config; + IAVF_VC_LOCK_ASSERT(sc); + sc->rss_hena = 0; + sc->rss_key_size = 0; + sc->rss_configured = IAVF_FLAG_AQ_CONFIG_RSS_KEY | + IAVF_FLAG_AQ_SET_RSS_HENA; /* Don't set up RSS if using a single queue */ if (IAVF_NRXQS(vsi) == 1) { wr32(hw, IAVF_VFQF_HENA(0), 0); @@ -1097,6 +1102,12 @@ iavf_config_rss_reg(struct iavf_sc *sc) /* Fill out hash function seed */ for (i = 0; i < IAVF_RSS_KEY_SIZE_REG; i++) wr32(hw, IAVF_VFQF_HKEY(i), rss_seed[i]); + /* Report the register byte order, not the host's u32 representation. */ + _Static_assert(sizeof(rss_seed) >= sizeof(sc->rss_key), + "RSS register key too small"); + for (i = 0; i < RSS_KEYSIZE / sizeof(u32); i++) + le32enc(sc->rss_key + i * sizeof(u32), rss_seed[i]); + sc->rss_key_size = sizeof(sc->rss_key); /* Enable PCTYPES for RSS: */ rss_hash_config = rss_gethashconfig(); @@ -1119,6 +1130,7 @@ iavf_config_rss_reg(struct iavf_sc *sc) hena |= set_hena; wr32(hw, IAVF_VFQF_HENA(0), (u32)hena); wr32(hw, IAVF_VFQF_HENA(1), (u32)(hena >> 32)); + sc->rss_hena = hena; /* Populate the LUT with max no. of queues in round robin fashion */ for (i = 0, j = 0; i < IAVF_RSS_VSI_LUT_SIZE; i++, j++) { @@ -1177,7 +1189,9 @@ iavf_config_rss(struct iavf_sc *sc) { if (sc->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_REG) { iavf_dbg_info(sc, "Setting up RSS using VF registers...\n"); + IAVF_VC_LOCK(sc); iavf_config_rss_reg(sc); + IAVF_VC_UNLOCK(sc); } else if (sc->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF) { iavf_dbg_info(sc, "Setting up RSS using messages to PF...\n"); iavf_config_rss_pf(sc); @@ -1185,6 +1199,17 @@ iavf_config_rss(struct iavf_sc *sc) device_printf(sc->dev, "VF does not support RSS capability sent by PF.\n"); } +/* Discard RSS query state when leaving the current running instance. */ +void +iavf_invalidate_rss(struct iavf_sc *sc) +{ + + IAVF_VC_LOCK(sc); + sc->rss_pending = 0; + sc->rss_configured = 0; + IAVF_VC_UNLOCK(sc); +} + /** * iavf_config_promisc - setup promiscuous mode * @sc: device private softc diff --git a/sys/dev/iavf/iavf_vc_common.c b/sys/dev/iavf/iavf_vc_common.c index 5f39f0334e83..2a11f02db59b 100644 --- a/sys/dev/iavf/iavf_vc_common.c +++ b/sys/dev/iavf/iavf_vc_common.c @@ -723,9 +723,11 @@ int iavf_config_rss_key(struct iavf_sc *sc) { struct virtchnl_rss_key *rss_key_msg; - int msg_len, key_length; + int error, msg_len, key_length; u32 rss_seed[IAVF_RSS_KEY_SIZE_REG] = {0}; + mtx_assert(&sc->vc_mtx, MA_NOTOWNED); + /* Fetch the configured RSS key */ rss_getkey((uint8_t *) &rss_seed); @@ -746,11 +748,21 @@ iavf_config_rss_key(struct iavf_sc *sc) iavf_dbg_vc(sc, "%s: vsi_id %d, key_len %d\n", __func__, rss_key_msg->vsi_id, rss_key_msg->key_len); - iavf_send_pf_msg(sc, VIRTCHNL_OP_CONFIG_RSS_KEY, + IAVF_VC_LOCK(sc); + sc->rss_configured &= ~IAVF_FLAG_AQ_CONFIG_RSS_KEY; + sc->rss_pending |= IAVF_FLAG_AQ_CONFIG_RSS_KEY; + /* Standard IPv4/IPv6 tuples use the first 40 bytes of the 52-byte key. */ + sc->rss_key_size = MIN(key_length, sizeof(sc->rss_key)); + bzero(sc->rss_key, sizeof(sc->rss_key)); + memcpy(sc->rss_key, rss_seed, sc->rss_key_size); + error = iavf_send_pf_msg(sc, VIRTCHNL_OP_CONFIG_RSS_KEY, (u8 *)rss_key_msg, msg_len); + if (error != 0) + sc->rss_pending &= ~IAVF_FLAG_AQ_CONFIG_RSS_KEY; + IAVF_VC_UNLOCK(sc); free(rss_key_msg, M_IAVF); - return (0); + return (error); } /** @@ -761,13 +773,16 @@ iavf_config_rss_key(struct iavf_sc *sc) * * @remark the reply from the PF is not checked by this function. * - * @returns zero + * @returns zero on success, or an error code on failure. */ int iavf_set_rss_hena(struct iavf_sc *sc) { struct virtchnl_rss_hena hena; struct iavf_hw *hw = &sc->hw; + int error; + + mtx_assert(&sc->vc_mtx, MA_NOTOWNED); if (hw->mac.type == IAVF_MAC_VF) hena.hena = IAVF_DEFAULT_RSS_HENA_AVF; @@ -776,9 +791,16 @@ iavf_set_rss_hena(struct iavf_sc *sc) else hena.hena = IAVF_DEFAULT_RSS_HENA_BASE; - iavf_send_pf_msg(sc, VIRTCHNL_OP_SET_RSS_HENA, + IAVF_VC_LOCK(sc); + sc->rss_configured &= ~IAVF_FLAG_AQ_SET_RSS_HENA; + sc->rss_pending |= IAVF_FLAG_AQ_SET_RSS_HENA; + sc->rss_hena = hena.hena; + error = iavf_send_pf_msg(sc, VIRTCHNL_OP_SET_RSS_HENA, (u8 *)&hena, sizeof(hena)); - return (0); + if (error != 0) + sc->rss_pending &= ~IAVF_FLAG_AQ_SET_RSS_HENA; + IAVF_VC_UNLOCK(sc); + return (error); } /** @@ -1207,6 +1229,9 @@ iavf_vc_completion(struct iavf_sc *sc, enum virtchnl_status_code v_retval, u8 *msg, u16 msglen __unused) { device_t dev = sc->dev; + u32 rss_op; + + IAVF_VC_LOCK_ASSERT(sc); if (v_opcode != VIRTCHNL_OP_GET_STATS) iavf_dbg_vc(sc, "%s: opcode %s\n", __func__, @@ -1223,6 +1248,8 @@ iavf_vc_completion(struct iavf_sc *sc, case VIRTCHNL_EVENT_RESET_IMPENDING: device_printf(dev, "PF initiated reset!\n"); iavf_set_state(&sc->state, IAVF_STATE_RESET_PENDING); + sc->rss_pending = 0; + sc->rss_configured = 0; break; default: iavf_dbg_vc(sc, "Unknown event %d from AQ\n", @@ -1233,6 +1260,17 @@ iavf_vc_completion(struct iavf_sc *sc, return; } + rss_op = 0; + if (v_opcode == VIRTCHNL_OP_CONFIG_RSS_KEY) + rss_op = IAVF_FLAG_AQ_CONFIG_RSS_KEY; + else if (v_opcode == VIRTCHNL_OP_SET_RSS_HENA) + rss_op = IAVF_FLAG_AQ_SET_RSS_HENA; + if (sc->rss_pending & rss_op) { + sc->rss_pending &= ~rss_op; + if (v_retval == VIRTCHNL_STATUS_SUCCESS) + sc->rss_configured |= rss_op; + } + /* Catch-all error response */ if (v_retval) { bool print_error = true; diff --git a/sys/dev/iavf/if_iavf_iflib.c b/sys/dev/iavf/if_iavf_iflib.c index f0d1f39ee20c..e761ac86c9b0 100644 --- a/sys/dev/iavf/if_iavf_iflib.c +++ b/sys/dev/iavf/if_iavf_iflib.c @@ -85,6 +85,8 @@ static void iavf_if_timer(if_ctx_t ctx, uint16_t qid); static void iavf_if_vlan_register(if_ctx_t ctx, u16 vtag); static void iavf_if_vlan_unregister(if_ctx_t ctx, u16 vtag); static uint64_t iavf_if_get_counter(if_ctx_t ctx, ift_counter cnt); +static int iavf_if_get_rss_key(if_ctx_t, struct ifrsskey *); +static int iavf_if_get_rss_hash(if_ctx_t, struct ifrsshash *); static void iavf_if_init(if_ctx_t ctx); static void iavf_if_stop(if_ctx_t ctx); static bool iavf_if_needs_restart(if_ctx_t, enum iflib_restart_event); @@ -195,6 +197,8 @@ static device_method_t iavf_if_methods[] = { DEVMETHOD(ifdi_vlan_register, iavf_if_vlan_register), DEVMETHOD(ifdi_vlan_unregister, iavf_if_vlan_unregister), DEVMETHOD(ifdi_get_counter, iavf_if_get_counter), + DEVMETHOD(ifdi_get_rss_key, iavf_if_get_rss_key), + DEVMETHOD(ifdi_get_rss_hash, iavf_if_get_rss_hash), DEVMETHOD(ifdi_needs_restart, iavf_if_needs_restart), DEVMETHOD_END }; @@ -881,6 +885,7 @@ iavf_mbx_lost(struct iavf_sc *sc) atomic_store_rel_32(&sc->vc_reinit_required, 1); if (atomic_readandclear_32(&sc->mbx_ready) == 0) return; + iavf_invalidate_rss(sc); vsi = &sc->vsi; iavf_clear_state(&sc->state, IAVF_STATE_RUNNING); sc->link_up = false; @@ -1032,6 +1037,7 @@ iavf_if_init(if_ctx_t ctx) INIT_DBG_IF(ifp, "begin"); sx_assert(iflib_ctx_lock_get(ctx), SA_XLOCKED); + iavf_invalidate_rss(sc); iavf_mbx_retry_prepare(sc); replay_filters = atomic_load_acq_32(&sc->vc_reinit_required) != 0; @@ -1120,6 +1126,83 @@ fail: iavf_mbx_retry_failed(ctx); } +/* Query only a complete configuration from the current running instance. */ +static int +iavf_rss_query_status(struct iavf_sc *sc) +{ + + sx_assert(iflib_ctx_lock_get(sc->vsi.ctx), SA_XLOCKED); + IAVF_VC_LOCK_ASSERT(sc); + if (sc->vf_res == NULL) + return (ENXIO); + if ((sc->vf_res->vf_cap_flags & (VIRTCHNL_VF_OFFLOAD_RSS_REG | + VIRTCHNL_VF_OFFLOAD_RSS_PF)) == 0) + return (EOPNOTSUPP); + if (!iavf_test_state(&sc->state, IAVF_STATE_RUNNING) || + iavf_test_state(&sc->state, IAVF_STATE_RESET_PENDING) || + iavf_test_state(&sc->state, IAVF_STATE_RESET_REQUIRED) || + atomic_load_acq_32(&sc->mbx_ready) == 0 || + atomic_load_acq_32(&sc->vc_reinit_required) != 0 || + sc->rss_configured != (IAVF_FLAG_AQ_CONFIG_RSS_KEY | + IAVF_FLAG_AQ_SET_RSS_HENA)) + return (ENXIO); + return (0); +} + +static int +iavf_if_get_rss_key(if_ctx_t ctx, struct ifrsskey *ifrk) +{ + struct iavf_sc *sc = iavf_sc_from_ctx(ctx); + int error; + + IAVF_VC_LOCK(sc); + error = iavf_rss_query_status(sc); + if (error == 0) { + ifrk->ifrk_func = sc->rss_hena == 0 ? RSS_FUNC_NONE : + RSS_FUNC_TOEPLITZ; + ifrk->ifrk_keylen = sc->rss_hena == 0 ? 0 : sc->rss_key_size; + _Static_assert(sizeof(ifrk->ifrk_key) >= sizeof(sc->rss_key), + "RSS query buffer too small"); + bzero(ifrk->ifrk_key, sizeof(ifrk->ifrk_key)); + memcpy(ifrk->ifrk_key, sc->rss_key, ifrk->ifrk_keylen); + } + IAVF_VC_UNLOCK(sc); + return (error); +} + +static int +iavf_if_get_rss_hash(if_ctx_t ctx, struct ifrsshash *ifrh) +{ + struct iavf_sc *sc = iavf_sc_from_ctx(ctx); + u64 hena; + int error; + + IAVF_VC_LOCK(sc); + error = iavf_rss_query_status(sc); + if (error == 0) { + hena = sc->rss_hena; + ifrh->ifrh_func = hena == 0 ? RSS_FUNC_NONE : RSS_FUNC_TOEPLITZ; + ifrh->ifrh_types = 0; + /* Fragment PCTYPEs are not IPv6 extension-header selections. */ + if (hena & (BIT_ULL(IAVF_FILTER_PCTYPE_NONF_IPV4_OTHER) | + BIT_ULL(IAVF_FILTER_PCTYPE_FRAG_IPV4))) + ifrh->ifrh_types |= RSS_TYPE_IPV4; + if (hena & BIT_ULL(IAVF_FILTER_PCTYPE_NONF_IPV4_TCP)) + ifrh->ifrh_types |= RSS_TYPE_TCP_IPV4; + if (hena & BIT_ULL(IAVF_FILTER_PCTYPE_NONF_IPV4_UDP)) + ifrh->ifrh_types |= RSS_TYPE_UDP_IPV4; + if (hena & (BIT_ULL(IAVF_FILTER_PCTYPE_NONF_IPV6_OTHER) | + BIT_ULL(IAVF_FILTER_PCTYPE_FRAG_IPV6))) + ifrh->ifrh_types |= RSS_TYPE_IPV6; + if (hena & BIT_ULL(IAVF_FILTER_PCTYPE_NONF_IPV6_TCP)) + ifrh->ifrh_types |= RSS_TYPE_TCP_IPV6; + if (hena & BIT_ULL(IAVF_FILTER_PCTYPE_NONF_IPV6_UDP)) + ifrh->ifrh_types |= RSS_TYPE_UDP_IPV6; + } + IAVF_VC_UNLOCK(sc); + return (error); +} + /** * iavf_if_msix_intr_assign - Assign MSI-X interrupts * @ctx: the iflib context pointer @@ -2129,6 +2212,7 @@ iavf_stop(struct iavf_sc *sc) vsi = &sc->vsi; iavf_mbx_retry_stop(sc); iavf_clear_state(&sc->state, IAVF_STATE_RUNNING); + iavf_invalidate_rss(sc); iavf_disable_intr(vsi);