Skip to content

Commit 0373d5c

Browse files
Michael Chankuba-moo
authored andcommitted
bnxt_en: Fix XDP_TX path
For XDP_TX action in bnxt_rx_xdp(), clearing of the event flags is not correct. __bnxt_poll_work() -> bnxt_rx_pkt() -> bnxt_rx_xdp() may be looping within NAPI and some event flags may be set in earlier iterations. In particular, if BNXT_TX_EVENT is set earlier indicating some XDP_TX packets are ready and pending, it will be cleared if it is XDP_TX action again. Normally, we will set BNXT_TX_EVENT again when we successfully call __bnxt_xmit_xdp(). But if the TX ring has no more room, the flag will not be set. This will cause the TX producer to be ahead but the driver will not hit the TX doorbell. For multi-buf XDP_TX, there is no need to clear the event flags and set BNXT_AGG_EVENT. The BNXT_AGG_EVENT flag should have been set earlier in bnxt_rx_pkt(). The visible symptom of this is that the RX ring associated with the TX XDP ring will eventually become empty and all packets will be dropped. Because this condition will cause the driver to not refill the RX ring seeing that the TX ring has forever pending XDP_TX packets. The fix is to only clear BNXT_RX_EVENT when we have successfully called __bnxt_xmit_xdp(). Fixes: 7f0a168 ("bnxt_en: Add completion ring pointer in TX and RX ring structures") Reported-by: Pavel Dubovitsky <pdubovitsky@meta.com> Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com> Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com> Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com> Signed-off-by: Michael Chan <michael.chan@broadcom.com> Reviewed-by: Jacob Keller <jacob.e.keller@intel.com> Link: https://patch.msgid.link/20251203003024.2246699-1-michael.chan@broadcom.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent a479a27 commit 0373d5c

File tree

1 file changed

+1
-2
lines changed

1 file changed

+1
-2
lines changed

drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,13 +268,11 @@ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
268268
case XDP_TX:
269269
rx_buf = &rxr->rx_buf_ring[cons];
270270
mapping = rx_buf->mapping - bp->rx_dma_offset;
271-
*event &= BNXT_TX_CMP_EVENT;
272271

273272
if (unlikely(xdp_buff_has_frags(xdp))) {
274273
struct skb_shared_info *sinfo = xdp_get_shared_info_from_buff(xdp);
275274

276275
tx_needed += sinfo->nr_frags;
277-
*event = BNXT_AGG_EVENT;
278276
}
279277

280278
if (tx_avail < tx_needed) {
@@ -287,6 +285,7 @@ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
287285
dma_sync_single_for_device(&pdev->dev, mapping + offset, *len,
288286
bp->rx_dir);
289287

288+
*event &= ~BNXT_RX_EVENT;
290289
*event |= BNXT_TX_EVENT;
291290
__bnxt_xmit_xdp(bp, txr, mapping + offset, *len,
292291
NEXT_RX(rxr->rx_prod), xdp);

0 commit comments

Comments
 (0)