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)
 {

Reply via email to