Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 08 Aug 2026 16:06:57 +0000
From:      Kevin Bowling <kbowling@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 98fad621ed69 - main - ixv: Negotiate VF queue-set limits
Message-ID:  <6a775421.32aa4.7be759d1@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by kbowling:

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

commit 98fad621ed697586782e488afdc05252c060fec3
Author:     Kevin Bowling <kbowling@FreeBSD.org>
AuthorDate: 2026-08-08 10:44:36 +0000
Commit:     Kevin Bowling <kbowling@FreeBSD.org>
CommitDate: 2026-08-08 16:06:37 +0000

    ixv: Negotiate VF queue-set limits
    
    ixv uses one queue set on 82599 and X540 VFs and assumes two on
    X550-family VFs.  The PF reports the queues assigned to each VF with
    GET_QUEUES after mailbox API 1.1 negotiation.
    
    Query the PF during attach.  Bound symmetric iflib queue sets by the PF
    grant and available MSI-X data vectors.  Retain one queue set per data
    vector: ixgbe VFs expose at most three vectors and one is reserved for
    the mailbox.  The hardware permits each pool to use a subset of its RSS
    queues, so a two-queue ceiling is valid when the PF assigns four.
    
    This enables the second data vector on 82599 and X540 while avoiding an
    assumed second queue when an X550-family VF is granted only one.  Keep
    the existing family limits if the mailbox is unavailable or the PF uses
    an older API.
    
    MFC after:      2 weeks
---
 sys/dev/ixgbe/if_ixv.c | 70 +++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 61 insertions(+), 9 deletions(-)

diff --git a/sys/dev/ixgbe/if_ixv.c b/sys/dev/ixgbe/if_ixv.c
index f9e58ecf5877..e8c3606721e2 100644
--- a/sys/dev/ixgbe/if_ixv.c
+++ b/sys/dev/ixgbe/if_ixv.c
@@ -104,6 +104,7 @@ static void     ixv_if_init(if_ctx_t);
 static void     ixv_if_local_timer(if_ctx_t, uint16_t);
 static void     ixv_if_stop(if_ctx_t);
 static int      ixv_negotiate_api(struct ixgbe_softc *);
+static int      ixv_queue_limit(struct ixgbe_softc *, bool);
 
 static void     ixv_initialize_transmit_units(if_ctx_t);
 static void     ixv_initialize_receive_units(if_ctx_t);
@@ -481,15 +482,8 @@ ixv_if_attach_pre(if_ctx_t ctx)
 	/* Most of the iflib initialization... */
 
 	iflib_set_mac(ctx, hw->mac.addr);
-	switch (sc->hw.mac.type) {
-	case ixgbe_mac_X550_vf:
-	case ixgbe_mac_X550EM_x_vf:
-	case ixgbe_mac_X550EM_a_vf:
-		scctx->isc_ntxqsets_max = scctx->isc_nrxqsets_max = 2;
-		break;
-	default:
-		scctx->isc_ntxqsets_max = scctx->isc_nrxqsets_max = 1;
-	}
+	scctx->isc_ntxqsets_max = scctx->isc_nrxqsets_max =
+	    ixv_queue_limit(sc, mailbox_ready);
 	scctx->isc_txqsizes[0] =
 	    roundup2(scctx->isc_ntxd[0] * sizeof(union ixgbe_adv_tx_desc) +
 	    sizeof(u32), DBA_ALIGN);
@@ -875,6 +869,64 @@ ixv_negotiate_api(struct ixgbe_softc *sc)
 	return (EINVAL);
 } /* ixv_negotiate_api */
 
+/************************************************************************
+ * ixv_queue_limit
+ *
+ *   Discover the number of symmetric RSS queue sets available to iflib.
+ ************************************************************************/
+static int
+ixv_queue_limit(struct ixgbe_softc *sc, bool mailbox_ready)
+{
+	struct ixgbe_hw *hw;
+	unsigned int default_tc, num_tcs;
+	int admin_vectors, limit, msix_vectors;
+
+	hw = &sc->hw;
+	/* Preserve the current family limit as the mailbox fallback. */
+	switch (hw->mac.type) {
+	case ixgbe_mac_82599_vf:
+	case ixgbe_mac_X540_vf:
+		limit = 1;
+		break;
+	case ixgbe_mac_X550_vf:
+	case ixgbe_mac_X550EM_x_vf:
+	case ixgbe_mac_X550EM_a_vf:
+		limit = 2;
+		break;
+	default:
+		return (1);
+	}
+
+	/* Replace the fallback with the queue grant reported by the PF. */
+	if (mailbox_ready) {
+		switch (hw->api_version) {
+		case ixgbe_mbox_api_11:
+		case ixgbe_mbox_api_12:
+		case ixgbe_mbox_api_13:
+			num_tcs = default_tc = 0;
+			if (ixgbevf_get_queues(hw, &num_tcs, &default_tc) == 0) {
+				limit = imin(hw->mac.max_tx_queues,
+				    hw->mac.max_rx_queues);
+				limit = imin(limit, 2);
+			}
+			break;
+		default:
+			break;
+		}
+	}
+
+	/*
+	 * iflib assigns one data vector to each queue set.  A VF has at most
+	 * three MSI-X vectors; reserve one of them for the mailbox interrupt.
+	 */
+	admin_vectors = iflib_get_sctx(sc->ctx)->isc_admin_intrcnt;
+	msix_vectors = pci_msix_count(sc->dev);
+	if (msix_vectors <= admin_vectors)
+		return (1);
+
+	return (imax(1, imin(limit, msix_vectors - admin_vectors)));
+} /* ixv_queue_limit */
+
 static int
 ixv_update_xcast_mode(struct ixgbe_softc *sc, int flags)
 {


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a775421.32aa4.7be759d1>