Skip to content

Commit bc4db83

Browse files
alobakinborkmann
authored andcommitted
ice: fix ice_tx_ring:: Xdp_tx_active underflow
xdp_tx_active is used to indicate whether an XDP ring has any %XDP_TX frames queued to shortcut processing Tx cleaning for XSk-enabled queues. When !XSk, it simply indicates whether the ring has any queued frames in general. It gets increased on each frame placed onto the ring and counts the whole frame, not each frag. However, currently it gets decremented in ice_clean_xdp_tx_buf(), which is called per each buffer, i.e. per each frag. Thus, on completing multi-frag frames, an underflow happens. Move the decrement to the outer function and do it once per frame, not buf. Also, do that on the stack and update the ring counter after the loop is done to save several cycles. XSk rings are fine since there are no frags at the moment. Fixes: 3246a10 ("ice: Add support for XDP multi-buffer on Tx side") Signed-off-by: Alexander Lobakin <alexandr.lobakin@intel.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com> Link: https://lore.kernel.org/bpf/20230210170618.1973430-2-alexandr.lobakin@intel.com
1 parent 0b07572 commit bc4db83

File tree

1 file changed

+3
-2
lines changed

1 file changed

+3
-2
lines changed

drivers/net/ethernet/intel/ice/ice_txrx_lib.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,6 @@ ice_clean_xdp_tx_buf(struct ice_tx_ring *xdp_ring, struct ice_tx_buf *tx_buf)
231231
dma_unmap_single(xdp_ring->dev, dma_unmap_addr(tx_buf, dma),
232232
dma_unmap_len(tx_buf, len), DMA_TO_DEVICE);
233233
dma_unmap_len_set(tx_buf, len, 0);
234-
xdp_ring->xdp_tx_active--;
235234
page_frag_free(tx_buf->raw_buf);
236235
tx_buf->raw_buf = NULL;
237236
}
@@ -246,8 +245,8 @@ static u32 ice_clean_xdp_irq(struct ice_tx_ring *xdp_ring)
246245
u32 ntc = xdp_ring->next_to_clean;
247246
struct ice_tx_desc *tx_desc;
248247
u32 cnt = xdp_ring->count;
248+
u32 frags, xdp_tx = 0;
249249
u32 ready_frames = 0;
250-
u32 frags;
251250
u32 idx;
252251
u32 ret;
253252

@@ -274,6 +273,7 @@ static u32 ice_clean_xdp_irq(struct ice_tx_ring *xdp_ring)
274273
total_pkts++;
275274
/* count head + frags */
276275
ready_frames -= frags + 1;
276+
xdp_tx++;
277277

278278
if (xdp_ring->xsk_pool)
279279
xsk_buff_free(tx_buf->xdp);
@@ -295,6 +295,7 @@ static u32 ice_clean_xdp_irq(struct ice_tx_ring *xdp_ring)
295295

296296
tx_desc->cmd_type_offset_bsz = 0;
297297
xdp_ring->next_to_clean = ntc;
298+
xdp_ring->xdp_tx_active -= xdp_tx;
298299
ice_update_tx_ring_stats(xdp_ring, total_pkts, total_bytes);
299300

300301
return ret;

0 commit comments

Comments
 (0)