git: 98fad621ed69 - main - ixv: Negotiate VF queue-set limits
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 08 Aug 2026 16:06:57 UTC
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)
{