Rx: [PATCH bpf-next v3 3/7] ice: make Tx threshold dependent on ring length

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Maciej Fijalkowski <maciej.fijalkowski@xxxxxxxxx>
Date: Fri, 21 Jan 2022 13:00:07 +0100

> XDP_TX workloads use a concept of Tx threshold that indicates the
> interval of setting RS bit on descriptors which in turn tells the HW to
> generate an interrupt to signal the completion of Tx on HW side. It is
> currently based on a constant value of 32 which might not work out well
> for various sizes of ring combined with for example batch size that can
> be set via SO_BUSY_POLL_BUDGET.
> 
> Internal tests based on AF_XDP showed that most convenient setup of
> mentioned threshold is when it is equal to quarter of a ring length.
> 
> Introduce @tx_thresh field in ice_tx_ring struct that will store the
> value of threshold and use it in favor of ICE_TX_THRESH.
> 
> Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@xxxxxxxxx>
> ---
>  drivers/net/ethernet/intel/ice/ice_ethtool.c  |  3 +++
>  drivers/net/ethernet/intel/ice/ice_main.c     |  5 +++--
>  drivers/net/ethernet/intel/ice/ice_txrx.h     |  7 ++++++-
>  drivers/net/ethernet/intel/ice/ice_txrx_lib.c | 14 ++++++++------
>  4 files changed, 20 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c
> index e2e3ef7fba7f..bfa5e5d167ab 100644
> --- a/drivers/net/ethernet/intel/ice/ice_ethtool.c
> +++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c
> @@ -2803,6 +2803,9 @@ ice_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring,
>  		/* clone ring and setup updated count */
>  		xdp_rings[i] = *vsi->xdp_rings[i];
>  		xdp_rings[i].count = new_tx_cnt;
> +		xdp_rings[i].tx_thresh = ice_get_tx_threshold(&xdp_rings[i]);
> +		xdp_rings[i].next_dd = xdp_rings[i].tx_thresh - 1;
> +		xdp_rings[i].next_rs = xdp_rings[i].tx_thresh - 1;
>  		xdp_rings[i].desc = NULL;
>  		xdp_rings[i].tx_buf = NULL;
>  		err = ice_setup_tx_ring(&xdp_rings[i]);
> diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
> index 30814435f779..0fd12a7f6d22 100644
> --- a/drivers/net/ethernet/intel/ice/ice_main.c
> +++ b/drivers/net/ethernet/intel/ice/ice_main.c
> @@ -2495,10 +2495,11 @@ static int ice_xdp_alloc_setup_rings(struct ice_vsi *vsi)
>  		xdp_ring->reg_idx = vsi->txq_map[xdp_q_idx];
>  		xdp_ring->vsi = vsi;
>  		xdp_ring->netdev = NULL;
> -		xdp_ring->next_dd = ICE_TX_THRESH - 1;
> -		xdp_ring->next_rs = ICE_TX_THRESH - 1;
>  		xdp_ring->dev = dev;
>  		xdp_ring->count = vsi->num_tx_desc;
> +		xdp_ring->tx_thresh = ice_get_tx_threshold(xdp_ring);
> +		xdp_ring->next_dd = xdp_ring->tx_thresh - 1;
> +		xdp_ring->next_rs = xdp_ring->tx_thresh - 1;
>  		WRITE_ONCE(vsi->xdp_rings[i], xdp_ring);
>  		if (ice_setup_tx_ring(xdp_ring))
>  			goto free_xdp_rings;
> diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.h b/drivers/net/ethernet/intel/ice/ice_txrx.h
> index 94a46e0e5ed0..09c8ad2f7403 100644
> --- a/drivers/net/ethernet/intel/ice/ice_txrx.h
> +++ b/drivers/net/ethernet/intel/ice/ice_txrx.h
> @@ -13,7 +13,6 @@
>  #define ICE_MAX_CHAINED_RX_BUFS	5
>  #define ICE_MAX_BUF_TXD		8
>  #define ICE_MIN_TX_LEN		17
> -#define ICE_TX_THRESH		32
>  
>  /* The size limit for a transmit buffer in a descriptor is (16K - 1).
>   * In order to align with the read requests we will align the value to
> @@ -333,6 +332,7 @@ struct ice_tx_ring {
>  	struct ice_channel *ch;
>  	struct ice_ptp_tx *tx_tstamps;
>  	spinlock_t tx_lock;
> +	u16 tx_thresh;

Creating 2-byte hole here, but it's likely ok since I don't see a
place to pack it nicely. u8 at the end is not an option obviously.

(unless you want to store the order rather than the threshold
itself -- would require an additional macro, but at the same time
align nicely with the fact that we need the threshold to be of
power of two)

>  	u32 txq_teid;			/* Added Tx queue TEID */
>  #define ICE_TX_FLAGS_RING_XDP		BIT(0)
>  	u8 flags;
> @@ -355,6 +355,11 @@ static inline void ice_clear_ring_build_skb_ena(struct ice_rx_ring *ring)
>  	ring->flags &= ~ICE_RX_FLAGS_RING_BUILD_SKB;
>  }
>  
> +static inline u16 ice_get_tx_threshold(struct ice_tx_ring *tx_ring)
> +{
> +	return ICE_RING_QUARTER(tx_ring);
> +}
> +
>  static inline bool ice_ring_ch_enabled(struct ice_tx_ring *ring)
>  {
>  	return !!ring->ch;
> diff --git a/drivers/net/ethernet/intel/ice/ice_txrx_lib.c b/drivers/net/ethernet/intel/ice/ice_txrx_lib.c
> index 0e87b98e0966..5706b5405373 100644
> --- a/drivers/net/ethernet/intel/ice/ice_txrx_lib.c
> +++ b/drivers/net/ethernet/intel/ice/ice_txrx_lib.c
> @@ -222,6 +222,7 @@ ice_receive_skb(struct ice_rx_ring *rx_ring, struct sk_buff *skb, u16 vlan_tag)
>  static void ice_clean_xdp_irq(struct ice_tx_ring *xdp_ring)
>  {
>  	unsigned int total_bytes = 0, total_pkts = 0;
> +	u16 tx_thresh = xdp_ring->tx_thresh;
>  	u16 ntc = xdp_ring->next_to_clean;
>  	struct ice_tx_desc *next_dd_desc;
>  	u16 next_dd = xdp_ring->next_dd;
> @@ -233,7 +234,7 @@ static void ice_clean_xdp_irq(struct ice_tx_ring *xdp_ring)
>  	    cpu_to_le64(ICE_TX_DESC_DTYPE_DESC_DONE)))
>  		return;
>  
> -	for (i = 0; i < ICE_TX_THRESH; i++) {
> +	for (i = 0; i < tx_thresh; i++) {
>  		tx_buf = &xdp_ring->tx_buf[ntc];
>  
>  		total_bytes += tx_buf->bytecount;
> @@ -254,9 +255,9 @@ static void ice_clean_xdp_irq(struct ice_tx_ring *xdp_ring)
>  	}
>  
>  	next_dd_desc->cmd_type_offset_bsz = 0;
> -	xdp_ring->next_dd = xdp_ring->next_dd + ICE_TX_THRESH;
> +	xdp_ring->next_dd = xdp_ring->next_dd + tx_thresh;
>  	if (xdp_ring->next_dd > xdp_ring->count)
> -		xdp_ring->next_dd = ICE_TX_THRESH - 1;
> +		xdp_ring->next_dd = tx_thresh - 1;
>  	xdp_ring->next_to_clean = ntc;
>  	ice_update_tx_ring_stats(xdp_ring, total_pkts, total_bytes);
>  }
> @@ -269,12 +270,13 @@ static void ice_clean_xdp_irq(struct ice_tx_ring *xdp_ring)
>   */
>  int ice_xmit_xdp_ring(void *data, u16 size, struct ice_tx_ring *xdp_ring)
>  {
> +	u16 tx_thresh = xdp_ring->tx_thresh;
>  	u16 i = xdp_ring->next_to_use;
>  	struct ice_tx_desc *tx_desc;
>  	struct ice_tx_buf *tx_buf;
>  	dma_addr_t dma;
>  
> -	if (ICE_DESC_UNUSED(xdp_ring) < ICE_TX_THRESH)
> +	if (ICE_DESC_UNUSED(xdp_ring) < tx_thresh)
>  		ice_clean_xdp_irq(xdp_ring);
>  
>  	if (!unlikely(ICE_DESC_UNUSED(xdp_ring))) {
> @@ -306,7 +308,7 @@ int ice_xmit_xdp_ring(void *data, u16 size, struct ice_tx_ring *xdp_ring)
>  		tx_desc = ICE_TX_DESC(xdp_ring, xdp_ring->next_rs);
>  		tx_desc->cmd_type_offset_bsz |=
>  			cpu_to_le64(ICE_TX_DESC_CMD_RS << ICE_TXD_QW1_CMD_S);
> -		xdp_ring->next_rs = ICE_TX_THRESH - 1;
> +		xdp_ring->next_rs = tx_thresh - 1;
>  	}
>  	xdp_ring->next_to_use = i;
>  
> @@ -314,7 +316,7 @@ int ice_xmit_xdp_ring(void *data, u16 size, struct ice_tx_ring *xdp_ring)
>  		tx_desc = ICE_TX_DESC(xdp_ring, xdp_ring->next_rs);
>  		tx_desc->cmd_type_offset_bsz |=
>  			cpu_to_le64(ICE_TX_DESC_CMD_RS << ICE_TXD_QW1_CMD_S);
> -		xdp_ring->next_rs += ICE_TX_THRESH;
> +		xdp_ring->next_rs += tx_thresh;
>  	}
>  
>  	return ICE_XDP_TX;
> -- 
> 2.33.1

Thanks,
Al



[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux