]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ice: store max_frame and rx_buf_len only in ice_rx_ring
authorJacob Keller <jacob.e.keller@intel.com>
Mon, 9 Sep 2024 23:07:45 +0000 (16:07 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 25 Sep 2025 09:13:43 +0000 (11:13 +0200)
[ Upstream commit 7e61c89c6065731dfc11ac7a2c0dd27a910f2afb ]

The max_frame and rx_buf_len fields of the VSI set the maximum frame size
for packets on the wire, and configure the size of the Rx buffer. In the
hardware, these are per-queue configuration. Most VSI types use a simple
method to determine the size of the buffers for all queues.

However, VFs may potentially configure different values for each queue.
While the Linux iAVF driver does not do this, it is allowed by the virtchnl
interface.

The current virtchnl code simply sets the per-VSI fields inbetween calls to
ice_vsi_cfg_single_rxq(). This technically works, as these fields are only
ever used when programming the Rx ring, and otherwise not checked again.
However, it is confusing to maintain.

The Rx ring also already has an rx_buf_len field in order to access the
buffer length in the hotpath. It also has extra unused bytes in the ring
structure which we can make use of to store the maximum frame size.

Drop the VSI max_frame and rx_buf_len fields. Add max_frame to the Rx ring,
and slightly re-order rx_buf_len to better fit into the gaps in the
structure layout.

Change the ice_vsi_cfg_frame_size function so that it writes to the ring
fields. Call this function once per ring in ice_vsi_cfg_rxqs(). This is
done over calling it inside the ice_vsi_cfg_rxq(), because
ice_vsi_cfg_rxq() is called in the virtchnl flow where the max_frame and
rx_buf_len have already been configured.

Change the accesses for rx_buf_len and max_frame to all point to the ring
structure. This has the added benefit that ice_vsi_cfg_rxq() no longer has
the surprise side effect of updating ring->rx_buf_len based on the VSI
field.

Update the virtchnl ice_vc_cfg_qs_msg() function to set the ring values
directly, and drop references to the removed VSI fields.

This now makes the VF logic clear, as the ring fields are obviously
per-queue. This reduces the required cognitive load when reasoning about
this logic.

Note that removing the VSI fields does leave a 4 byte gap, but the ice_vsi
structure has many gaps, and its layout is not as critical in the hot path.
The structure may benefit from a more thorough repacking, but no attempt
was made in this change.

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Stable-dep-of: 84bf1ac85af8 ("ice: fix Rx page leak on multi-buffer frames")
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/ethernet/intel/ice/ice.h
drivers/net/ethernet/intel/ice/ice_base.c
drivers/net/ethernet/intel/ice/ice_txrx.h
drivers/net/ethernet/intel/ice/ice_virtchnl.c

index 2960709f6b62ca6b05dcb474d0160bb2aaccd282..0e699a0432c5b2aec93b8c48e76e8a0b1d8930c3 100644 (file)
@@ -372,9 +372,6 @@ struct ice_vsi {
        spinlock_t arfs_lock;   /* protects aRFS hash table and filter state */
        atomic_t *arfs_last_fltr_id;
 
-       u16 max_frame;
-       u16 rx_buf_len;
-
        struct ice_aqc_vsi_props info;   /* VSI properties */
        struct ice_vsi_vlan_info vlan_info;     /* vlan config to be restored */
 
index 4a9a6899fc453cb53b11ad014abceb1ca0fa7441..98c3764fed396e243ad7c6585f6788a185f3d564 100644 (file)
@@ -445,7 +445,7 @@ static int ice_setup_rx_ctx(struct ice_rx_ring *ring)
        /* Max packet size for this queue - must not be set to a larger value
         * than 5 x DBUF
         */
-       rlan_ctx.rxmax = min_t(u32, vsi->max_frame,
+       rlan_ctx.rxmax = min_t(u32, ring->max_frame,
                               ICE_MAX_CHAINED_RX_BUFS * ring->rx_buf_len);
 
        /* Rx queue threshold in units of 64 */
@@ -541,8 +541,6 @@ static int ice_vsi_cfg_rxq(struct ice_rx_ring *ring)
        u32 num_bufs = ICE_RX_DESC_UNUSED(ring);
        int err;
 
-       ring->rx_buf_len = ring->vsi->rx_buf_len;
-
        if (ring->vsi->type == ICE_VSI_PF || ring->vsi->type == ICE_VSI_SF) {
                if (!xdp_rxq_info_is_reg(&ring->xdp_rxq)) {
                        err = __xdp_rxq_info_reg(&ring->xdp_rxq, ring->netdev,
@@ -641,21 +639,25 @@ int ice_vsi_cfg_single_rxq(struct ice_vsi *vsi, u16 q_idx)
 /**
  * ice_vsi_cfg_frame_size - setup max frame size and Rx buffer length
  * @vsi: VSI
+ * @ring: Rx ring to configure
+ *
+ * Determine the maximum frame size and Rx buffer length to use for a PF VSI.
+ * Set these in the associated Rx ring structure.
  */
-static void ice_vsi_cfg_frame_size(struct ice_vsi *vsi)
+static void ice_vsi_cfg_frame_size(struct ice_vsi *vsi, struct ice_rx_ring *ring)
 {
        if (!vsi->netdev || test_bit(ICE_FLAG_LEGACY_RX, vsi->back->flags)) {
-               vsi->max_frame = ICE_MAX_FRAME_LEGACY_RX;
-               vsi->rx_buf_len = ICE_RXBUF_1664;
+               ring->max_frame = ICE_MAX_FRAME_LEGACY_RX;
+               ring->rx_buf_len = ICE_RXBUF_1664;
 #if (PAGE_SIZE < 8192)
        } else if (!ICE_2K_TOO_SMALL_WITH_PADDING &&
                   (vsi->netdev->mtu <= ETH_DATA_LEN)) {
-               vsi->max_frame = ICE_RXBUF_1536 - NET_IP_ALIGN;
-               vsi->rx_buf_len = ICE_RXBUF_1536 - NET_IP_ALIGN;
+               ring->max_frame = ICE_RXBUF_1536 - NET_IP_ALIGN;
+               ring->rx_buf_len = ICE_RXBUF_1536 - NET_IP_ALIGN;
 #endif
        } else {
-               vsi->max_frame = ICE_AQ_SET_MAC_FRAME_SIZE_MAX;
-               vsi->rx_buf_len = ICE_RXBUF_3072;
+               ring->max_frame = ICE_AQ_SET_MAC_FRAME_SIZE_MAX;
+               ring->rx_buf_len = ICE_RXBUF_3072;
        }
 }
 
@@ -670,15 +672,15 @@ int ice_vsi_cfg_rxqs(struct ice_vsi *vsi)
 {
        u16 i;
 
-       if (vsi->type == ICE_VSI_VF)
-               goto setup_rings;
-
-       ice_vsi_cfg_frame_size(vsi);
-setup_rings:
        /* set up individual rings */
        ice_for_each_rxq(vsi, i) {
-               int err = ice_vsi_cfg_rxq(vsi->rx_rings[i]);
+               struct ice_rx_ring *ring = vsi->rx_rings[i];
+               int err;
+
+               if (vsi->type != ICE_VSI_VF)
+                       ice_vsi_cfg_frame_size(vsi, ring);
 
+               err = ice_vsi_cfg_rxq(ring);
                if (err)
                        return err;
        }
index 7130992d417798bd2254303defb6fc8a2c589b10..7eef66f5964a3e27b88140220a26f7983f3a2f4b 100644 (file)
@@ -358,8 +358,9 @@ struct ice_rx_ring {
        struct ice_rx_ring *next;       /* pointer to next ring in q_vector */
        struct xsk_buff_pool *xsk_pool;
        u32 nr_frags;
-       dma_addr_t dma;                 /* physical address of ring */
+       u16 max_frame;
        u16 rx_buf_len;
+       dma_addr_t dma;                 /* physical address of ring */
        u8 dcb_tc;                      /* Traffic class of ring */
        u8 ptp_rx;
 #define ICE_RX_FLAGS_RING_BUILD_SKB    BIT(1)
index 87ffd25b268a2e66cb83c08d7562378126e17581..471d64d202b76093e08f5220b9da2b51886b4432 100644 (file)
@@ -1748,19 +1748,18 @@ static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg)
                            (qpi->rxq.databuffer_size > ((16 * 1024) - 128) ||
                             qpi->rxq.databuffer_size < 1024))
                                goto error_param;
-                       vsi->rx_buf_len = qpi->rxq.databuffer_size;
-                       ring->rx_buf_len = vsi->rx_buf_len;
+                       ring->rx_buf_len = qpi->rxq.databuffer_size;
                        if (qpi->rxq.max_pkt_size > max_frame_size ||
                            qpi->rxq.max_pkt_size < 64)
                                goto error_param;
 
-                       vsi->max_frame = qpi->rxq.max_pkt_size;
+                       ring->max_frame = qpi->rxq.max_pkt_size;
                        /* add space for the port VLAN since the VF driver is
                         * not expected to account for it in the MTU
                         * calculation
                         */
                        if (ice_vf_is_port_vlan_ena(vf))
-                               vsi->max_frame += VLAN_HLEN;
+                               ring->max_frame += VLAN_HLEN;
 
                        if (ice_vsi_cfg_single_rxq(vsi, q_idx)) {
                                dev_warn(ice_pf_to_dev(pf), "VF-%d failed to configure RX queue %d\n",