diff options
| author | Daniel Borkmann <daniel@iogearbox.net> | 2023-02-13 19:13:13 +0100 | 
|---|---|---|
| committer | Daniel Borkmann <daniel@iogearbox.net> | 2023-02-13 19:13:18 +0100 | 
| commit | 39c536acc3cf89b49c22f9e7f3f6578d3332944e (patch) | |
| tree | a4711ebfbe3eda0cdc10b3c91d0d2c13762132e4 /drivers/net/ethernet/intel/ice/ice_txrx.c | |
| parent | 0b0757244754ea1d0721195c824770f5576e119e (diff) | |
| parent | ad07f29b9c9a29eba04b19116c6db51387a638d7 (diff) | |
Merge branch 'xdp-ice-mbuf'
Alexander Lobakin says:
====================
The set grew from the poor performance of %BPF_F_TEST_XDP_LIVE_FRAMES
when the ice-backed device is a sender. Initially there were around
3.3 Mpps / thread, while I have 5.5 on skb-based pktgen ...
After fixing 0005 (0004 is a prereq for it) first (strange thing nobody
noticed that earlier), I started catching random OOMs. This is how 0002
(and partially 0001) appeared.
0003 is a suggestion from Maciej to not waste time on refactoring dead
lines. 0006 is a "cherry on top" to get away with the final 6.7 Mpps.
4.5 of 6 are fixes, but only the first three are tagged, since it then
starts being tricky. I may backport them manually later on.
TL;DR for the series is that shortcuts are good, but only as long as
they don't make the driver miss important things. %XDP_TX is purely
driver-local, however .ndo_xdp_xmit() is not, and sometimes assumptions
can be unsafe there.
With that series and also one core code patch[0], "live frames" and
xdp-trafficgen are now safe'n'fast on ice (probably more to come).
  [0] https://lore.kernel.org/all/20230209172827.874728-1-alexandr.lobakin@intel.com
====================
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'drivers/net/ethernet/intel/ice/ice_txrx.c')
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_txrx.c | 67 | 
1 files changed, 43 insertions, 24 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c index 466113c86e6f..aaf313a95368 100644 --- a/drivers/net/ethernet/intel/ice/ice_txrx.c +++ b/drivers/net/ethernet/intel/ice/ice_txrx.c @@ -85,7 +85,7 @@ ice_prgm_fdir_fltr(struct ice_vsi *vsi, struct ice_fltr_desc *fdir_desc,  	td_cmd = ICE_TXD_LAST_DESC_CMD | ICE_TX_DESC_CMD_DUMMY |  		 ICE_TX_DESC_CMD_RE; -	tx_buf->tx_flags = ICE_TX_FLAGS_DUMMY_PKT; +	tx_buf->type = ICE_TX_BUF_DUMMY;  	tx_buf->raw_buf = raw_packet;  	tx_desc->cmd_type_offset_bsz = @@ -112,31 +112,29 @@ ice_prgm_fdir_fltr(struct ice_vsi *vsi, struct ice_fltr_desc *fdir_desc,  static void  ice_unmap_and_free_tx_buf(struct ice_tx_ring *ring, struct ice_tx_buf *tx_buf)  { -	if (tx_buf->skb) { -		if (tx_buf->tx_flags & ICE_TX_FLAGS_DUMMY_PKT) { -			devm_kfree(ring->dev, tx_buf->raw_buf); -		} else if (ice_ring_is_xdp(ring)) { -			if (ring->xsk_pool) -				xsk_buff_free(tx_buf->xdp); -			else -				page_frag_free(tx_buf->raw_buf); -		} else { -			dev_kfree_skb_any(tx_buf->skb); -		} -		if (dma_unmap_len(tx_buf, len)) -			dma_unmap_single(ring->dev, -					 dma_unmap_addr(tx_buf, dma), -					 dma_unmap_len(tx_buf, len), -					 DMA_TO_DEVICE); -	} else if (dma_unmap_len(tx_buf, len)) { +	if (dma_unmap_len(tx_buf, len))  		dma_unmap_page(ring->dev,  			       dma_unmap_addr(tx_buf, dma),  			       dma_unmap_len(tx_buf, len),  			       DMA_TO_DEVICE); + +	switch (tx_buf->type) { +	case ICE_TX_BUF_DUMMY: +		devm_kfree(ring->dev, tx_buf->raw_buf); +		break; +	case ICE_TX_BUF_SKB: +		dev_kfree_skb_any(tx_buf->skb); +		break; +	case ICE_TX_BUF_XDP_TX: +		page_frag_free(tx_buf->raw_buf); +		break; +	case ICE_TX_BUF_XDP_XMIT: +		xdp_return_frame(tx_buf->xdpf); +		break;  	}  	tx_buf->next_to_watch = NULL; -	tx_buf->skb = NULL; +	tx_buf->type = ICE_TX_BUF_EMPTY;  	dma_unmap_len_set(tx_buf, len, 0);  	/* tx_buf must be completely set up in the transmit path */  } @@ -269,7 +267,7 @@ static bool ice_clean_tx_irq(struct ice_tx_ring *tx_ring, int napi_budget)  				 DMA_TO_DEVICE);  		/* clear tx_buf data */ -		tx_buf->skb = NULL; +		tx_buf->type = ICE_TX_BUF_EMPTY;  		dma_unmap_len_set(tx_buf, len, 0);  		/* unmap remaining buffers */ @@ -580,7 +578,7 @@ ice_run_xdp(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,  	case XDP_TX:  		if (static_branch_unlikely(&ice_xdp_locking_key))  			spin_lock(&xdp_ring->tx_lock); -		ret = __ice_xmit_xdp_ring(xdp, xdp_ring); +		ret = __ice_xmit_xdp_ring(xdp, xdp_ring, false);  		if (static_branch_unlikely(&ice_xdp_locking_key))  			spin_unlock(&xdp_ring->tx_lock);  		if (ret == ICE_XDP_CONSUMED) @@ -608,6 +606,25 @@ exit:  }  /** + * ice_xmit_xdp_ring - submit frame to XDP ring for transmission + * @xdpf: XDP frame that will be converted to XDP buff + * @xdp_ring: XDP ring for transmission + */ +static int ice_xmit_xdp_ring(const struct xdp_frame *xdpf, +			     struct ice_tx_ring *xdp_ring) +{ +	struct xdp_buff xdp; + +	xdp.data_hard_start = (void *)xdpf; +	xdp.data = xdpf->data; +	xdp.data_end = xdp.data + xdpf->len; +	xdp.frame_sz = xdpf->frame_sz; +	xdp.flags = xdpf->flags; + +	return __ice_xmit_xdp_ring(&xdp, xdp_ring, true); +} + +/**   * ice_xdp_xmit - submit packets to XDP ring for transmission   * @dev: netdev   * @n: number of XDP frames to be transmitted @@ -652,7 +669,7 @@ ice_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames,  	tx_buf = &xdp_ring->tx_buf[xdp_ring->next_to_use];  	for (i = 0; i < n; i++) { -		struct xdp_frame *xdpf = frames[i]; +		const struct xdp_frame *xdpf = frames[i];  		int err;  		err = ice_xmit_xdp_ring(xdpf, xdp_ring); @@ -1712,6 +1729,7 @@ ice_tx_map(struct ice_tx_ring *tx_ring, struct ice_tx_buf *first,  				       DMA_TO_DEVICE);  		tx_buf = &tx_ring->tx_buf[i]; +		tx_buf->type = ICE_TX_BUF_FRAG;  	}  	/* record SW timestamp if HW timestamp is not available */ @@ -2355,6 +2373,7 @@ ice_xmit_frame_ring(struct sk_buff *skb, struct ice_tx_ring *tx_ring)  	/* record the location of the first descriptor for this packet */  	first = &tx_ring->tx_buf[tx_ring->next_to_use];  	first->skb = skb; +	first->type = ICE_TX_BUF_SKB;  	first->bytecount = max_t(unsigned int, skb->len, ETH_ZLEN);  	first->gso_segs = 1;  	first->tx_flags = 0; @@ -2527,11 +2546,11 @@ void ice_clean_ctrl_tx_irq(struct ice_tx_ring *tx_ring)  					 dma_unmap_addr(tx_buf, dma),  					 dma_unmap_len(tx_buf, len),  					 DMA_TO_DEVICE); -		if (tx_buf->tx_flags & ICE_TX_FLAGS_DUMMY_PKT) +		if (tx_buf->type == ICE_TX_BUF_DUMMY)  			devm_kfree(tx_ring->dev, tx_buf->raw_buf);  		/* clear next_to_watch to prevent false hangs */ -		tx_buf->raw_buf = NULL; +		tx_buf->type = ICE_TX_BUF_EMPTY;  		tx_buf->tx_flags = 0;  		tx_buf->next_to_watch = NULL;  		dma_unmap_len_set(tx_buf, len, 0);  | 
