diff options
author | Michal Kubiak <michal.kubiak@intel.com> | 2025-05-14 14:37:24 +0200 |
---|---|---|
committer | Tony Nguyen <anthony.l.nguyen@intel.com> | 2025-06-09 09:56:18 -0700 |
commit | dc5e7a3513efcbf886c53dc5401b524aa3dea92a (patch) | |
tree | 0ca82760ab77d9c067968470199ed6490698cb82 /drivers/net/ethernet/intel/ice/ice_txrx.c | |
parent | cb9e0de77761309f1b30a6800a16f4bedc17e512 (diff) |
ice: add a separate Rx handler for flow director commands
The "ice" driver implementation uses the control VSI to handle
the flow director configuration for PFs and VFs.
Unfortunately, although a separate VSI type was created to handle flow
director queues, the Rx queue handler was shared between the flow
director and a standard NAPI Rx handler.
Such a design approach was not very flexible. First, it mixed hotpath
and slowpath code, blocking their further optimization. It also created
a huge overkill for the flow director command processing, which is
descriptor-based only, so there is no need to allocate Rx data buffers.
For the above reasons, implement a separate Rx handler for the control
VSI. Also, remove from the NAPI handler the code dedicated to
configuring the flow director rules on VFs.
Do not allocate Rx data buffers to the flow director queues because
their processing is descriptor-based only.
Finally, allow Rx data queues to be allocated only for VSIs that have
netdev assigned to them.
This handler splitting approach is the first step in converting the
driver to use the Page Pool (which can only be used for data queues).
Test hints:
1. Create a VF for any PF managed by the ice driver.
2. In a loop, add and delete flow director rules for the VF, e.g.:
for i in {1..128}; do
q=$(( i % 16 ))
ethtool -N ens802f0v0 flow-type tcp4 dst-port "$i" action "$q"
done
for i in {0..127}; do
ethtool -N ens802f0v0 delete "$i"
done
Suggested-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
Suggested-by: Michal Swiatkowski <michal.swiatkowski@intel.com>
Acked-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Michal Kubiak <michal.kubiak@intel.com>
Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/ice/ice_txrx.c')
-rw-r--r-- | drivers/net/ethernet/intel/ice/ice_txrx.c | 87 |
1 files changed, 72 insertions, 15 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c index 0e5107fe62ad..29e0088ab6b2 100644 --- a/drivers/net/ethernet/intel/ice/ice_txrx.c +++ b/drivers/net/ethernet/intel/ice/ice_txrx.c @@ -20,7 +20,6 @@ #define ICE_RX_HDR_SIZE 256 -#define FDIR_DESC_RXDID 0x40 #define ICE_FDIR_CLEAN_DELAY 10 /** @@ -707,6 +706,37 @@ ice_alloc_mapped_page(struct ice_rx_ring *rx_ring, struct ice_rx_buf *bi) } /** + * ice_init_ctrl_rx_descs - Initialize Rx descriptors for control vsi. + * @rx_ring: ring to init descriptors on + * @count: number of descriptors to initialize + */ +void ice_init_ctrl_rx_descs(struct ice_rx_ring *rx_ring, u32 count) +{ + union ice_32b_rx_flex_desc *rx_desc; + u32 ntu = rx_ring->next_to_use; + + if (!count) + return; + + rx_desc = ICE_RX_DESC(rx_ring, ntu); + + do { + rx_desc++; + ntu++; + if (unlikely(ntu == rx_ring->count)) { + rx_desc = ICE_RX_DESC(rx_ring, 0); + ntu = 0; + } + + rx_desc->wb.status_error0 = 0; + count--; + } while (count); + + if (rx_ring->next_to_use != ntu) + ice_release_rx_desc(rx_ring, ntu); +} + +/** * ice_alloc_rx_bufs - Replace used receive buffers * @rx_ring: ring to place buffers on * @cleaned_count: number of buffers to replace @@ -726,8 +756,7 @@ bool ice_alloc_rx_bufs(struct ice_rx_ring *rx_ring, unsigned int cleaned_count) struct ice_rx_buf *bi; /* do nothing if no valid netdev defined */ - if ((!rx_ring->netdev && rx_ring->vsi->type != ICE_VSI_CTRL) || - !cleaned_count) + if (!rx_ring->netdev || !cleaned_count) return false; /* get the Rx descriptor and buffer based on next_to_use */ @@ -1184,6 +1213,45 @@ static void ice_put_rx_mbuf(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp, } /** + * ice_clean_ctrl_rx_irq - Clean descriptors from flow director Rx ring + * @rx_ring: Rx descriptor ring for ctrl_vsi to transact packets on + * + * This function cleans Rx descriptors from the ctrl_vsi Rx ring used + * to set flow director rules on VFs. + */ +void ice_clean_ctrl_rx_irq(struct ice_rx_ring *rx_ring) +{ + u32 ntc = rx_ring->next_to_clean; + unsigned int total_rx_pkts = 0; + u32 cnt = rx_ring->count; + + while (likely(total_rx_pkts < ICE_DFLT_IRQ_WORK)) { + struct ice_vsi *ctrl_vsi = rx_ring->vsi; + union ice_32b_rx_flex_desc *rx_desc; + u16 stat_err_bits; + + rx_desc = ICE_RX_DESC(rx_ring, ntc); + + stat_err_bits = BIT(ICE_RX_FLEX_DESC_STATUS0_DD_S); + if (!ice_test_staterr(rx_desc->wb.status_error0, stat_err_bits)) + break; + + dma_rmb(); + + if (ctrl_vsi->vf) + ice_vc_fdir_irq_handler(ctrl_vsi, rx_desc); + + if (++ntc == cnt) + ntc = 0; + total_rx_pkts++; + } + + rx_ring->first_desc = ntc; + rx_ring->next_to_clean = ntc; + ice_init_ctrl_rx_descs(rx_ring, ICE_RX_DESC_UNUSED(rx_ring)); +} + +/** * ice_clean_rx_irq - Clean completed descriptors from Rx ring - bounce buf * @rx_ring: Rx descriptor ring to transact packets on * @budget: Total limit on number of packets to process @@ -1195,7 +1263,7 @@ static void ice_put_rx_mbuf(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp, * * Returns amount of work completed */ -int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget) +static int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget) { unsigned int total_rx_bytes = 0, total_rx_pkts = 0; unsigned int offset = rx_ring->rx_offset; @@ -1242,17 +1310,6 @@ int ice_clean_rx_irq(struct ice_rx_ring *rx_ring, int budget) dma_rmb(); ice_trace(clean_rx_irq, rx_ring, rx_desc); - if (rx_desc->wb.rxdid == FDIR_DESC_RXDID || !rx_ring->netdev) { - struct ice_vsi *ctrl_vsi = rx_ring->vsi; - - if (rx_desc->wb.rxdid == FDIR_DESC_RXDID && - ctrl_vsi->vf) - ice_vc_fdir_irq_handler(ctrl_vsi, rx_desc); - if (++ntc == cnt) - ntc = 0; - rx_ring->first_desc = ntc; - continue; - } size = le16_to_cpu(rx_desc->wb.pkt_len) & ICE_RX_FLX_DESC_PKT_LEN_M; |