git: 98fad621ed69 - main - ixv: Negotiate VF queue-set limits

Kevin Bowling <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src
Message-ID <6a775421.32aa4.7be759d1__10395.8770212316$1786205248$gmane$org@gitrepo.freebsd.org>
The branch main has been updated by kbowling:

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

commit 98fad621ed697586782e488afdc05252c060fec3
Author:     Kevin Bowling <[email protected]>
AuthorDate: 2026-08-08 10:44:36 +0000
Commit:     Kevin Bowling <[email protected]>
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)
 {
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.