Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 07 Aug 2026 12:56:33 +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: 4383ab82b0bb - main - ixgbe: force receive drops on every VF queue
Message-ID:  <6a75d601.39067.59f8fdc7@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=4383ab82b0bbaf1c78ecdf4eb7628f1e154db24b

commit 4383ab82b0bbaf1c78ecdf4eb7628f1e154db24b
Author:     Kevin Bowling <kbowling@FreeBSD.org>
AuthorDate: 2026-08-01 06:43:08 +0000
Commit:     Kevin Bowling <kbowling@FreeBSD.org>
CommitDate: 2026-08-07 12:51:10 +0000

    ixgbe: force receive drops on every VF queue
    
    PFQDE is indexed by absolute receive queue, but the driver programs one
    index per VF. Only the first quarter or half of the VF queues therefore
    have queue-drop isolation, depending on the virtualization mode. The
    flow-control path can also clear those bits even though SR-IOV requires
    them independently of the PF pause policy.
    
    Program every queue in a VF pool before enabling receive for that VF.
    For an X550-family VF with an administrative port VLAN, also hide the
    VLAN tag as the hardware requires. Keep PF flow-control changes
    confined to the PF SRRCTL registers, and clear the VF queue settings
    when SR-IOV is torn down and the queues can be reassigned to the PF.
    
    MFC after:      2 weeks
---
 sys/dev/ixgbe/if_ix.c    | 12 ------------
 sys/dev/ixgbe/if_sriov.c | 28 ++++++++++++++++++++++++++++
 2 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/sys/dev/ixgbe/if_ix.c b/sys/dev/ixgbe/if_ix.c
index 4606e735b821..0a8c5573977e 100644
--- a/sys/dev/ixgbe/if_ix.c
+++ b/sys/dev/ixgbe/if_ix.c
@@ -5265,13 +5265,6 @@ ixgbe_enable_rx_drop(struct ixgbe_softc *sc)
 		IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(rxr->me), srrctl);
 	}
 
-	/* enable drop for each vf */
-	for (int i = 0; i < sc->num_vfs; i++) {
-		IXGBE_WRITE_REG(hw, IXGBE_QDE,
-		    (IXGBE_QDE_WRITE |
-		    (i << IXGBE_QDE_IDX_SHIFT) |
-		    IXGBE_QDE_ENABLE));
-	}
 } /* ixgbe_enable_rx_drop */
 
 /************************************************************************
@@ -5291,11 +5284,6 @@ ixgbe_disable_rx_drop(struct ixgbe_softc *sc)
 		IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(rxr->me), srrctl);
 	}
 
-	/* disable drop for each vf */
-	for (int i = 0; i < sc->num_vfs; i++) {
-		IXGBE_WRITE_REG(hw, IXGBE_QDE,
-		    (IXGBE_QDE_WRITE | (i << IXGBE_QDE_IDX_SHIFT)));
-	}
 } /* ixgbe_disable_rx_drop */
 
 /************************************************************************
diff --git a/sys/dev/ixgbe/if_sriov.c b/sys/dev/ixgbe/if_sriov.c
index 98c31b3d7a17..7987009eb8f0 100644
--- a/sys/dev/ixgbe/if_sriov.c
+++ b/sys/dev/ixgbe/if_sriov.c
@@ -587,6 +587,31 @@ ixgbe_vf_enable_transmit(struct ixgbe_softc *sc, struct ixgbe_vf *vf)
 } /* ixgbe_vf_enable_transmit */
 
 
+static void
+ixgbe_vf_set_rx_drop(struct ixgbe_softc *sc, struct ixgbe_vf *vf,
+    bool enable)
+{
+	struct ixgbe_hw *hw;
+	u32 qde;
+	int i, queue_count;
+
+	hw = &sc->hw;
+	queue_count = ixgbe_vf_queues(sc->iov_mode);
+	for (i = 0; i < queue_count; i++) {
+		qde = IXGBE_QDE_WRITE |
+		    (ixgbe_vf_que_index(sc->iov_mode, vf->pool, i) <<
+		    IXGBE_QDE_IDX_SHIFT);
+		if (enable) {
+			qde |= IXGBE_QDE_ENABLE;
+			if (vf->default_vlan != 0 &&
+			    hw->mac.type >= ixgbe_mac_X550)
+				qde |= IXGBE_QDE_HIDE_VLAN;
+		}
+		IXGBE_WRITE_REG(hw, IXGBE_QDE, qde);
+		IXGBE_WRITE_FLUSH(hw);
+	}
+}
+
 static void
 ixgbe_vf_enable_receive(struct ixgbe_softc *sc, struct ixgbe_vf *vf)
 {
@@ -594,6 +619,8 @@ ixgbe_vf_enable_receive(struct ixgbe_softc *sc, struct ixgbe_vf *vf)
 	uint32_t vf_index, vfre;
 
 	hw = &sc->hw;
+	/* Keep one VF without receive descriptors from blocking its peers. */
+	ixgbe_vf_set_rx_drop(sc, vf, true);
 
 	vf_index = IXGBE_VF_INDEX(vf->pool);
 	vfre = IXGBE_READ_REG(hw, IXGBE_VFRE(vf_index));
@@ -1442,6 +1469,7 @@ ixgbe_if_iov_uninit(if_ctx_t ctx)
 	for (i = 0; i < sc->num_vfs; i++) {
 		if (!(sc->vfs[i].flags & IXGBE_VF_ACTIVE))
 			continue;
+		ixgbe_vf_set_rx_drop(sc, &sc->vfs[i], false);
 		ixgbe_vf_clear_mac_filters(sc, &sc->vfs[i], true);
 		sc->vfs[i].flags &= ~IXGBE_VF_ANTI_SPOOF;
 		ixgbe_vf_set_anti_spoof(sc, &sc->vfs[i]);


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a75d601.39067.59f8fdc7>