BPF List
 help / color / mirror / Atom feed
* [PATCH net 0/4] ICSSG XDP zero copy bug fixes
@ 2026-06-11 18:57 Meghana Malladi
  2026-06-11 18:57 ` [PATCH net 1/4] net: ti: icssg-prueth: Fix AF_XDP fill ring alloc and wakeup condition Meghana Malladi
                   ` (4 more replies)
  0 siblings, 5 replies; 11+ messages in thread
From: Meghana Malladi @ 2026-06-11 18:57 UTC (permalink / raw)
  To: diogo.ivo, haokexin, vadim.fedorenko, devnexen, horms,
	jacob.e.keller, m-malladi, sdf, john.fastabend, hawk, daniel, ast,
	pabeni, kuba, edumazet, davem, andrew+netdev
  Cc: bpf, linux-kernel, netdev, linux-arm-kernel, srk,
	Vignesh Raghavendra, Roger Quadros, danishanwar

This patch series fixes bugs introduced while adding xdp
zero copy support in the icssg driver.

Patch 1/4: Fix wakeup handling for Rx when available CPPI
descriptor is zero
Patch 2,3/4: Fix destination tag in CPPI descriptor to enable
proper Tx xmit for HSR offload mode with XDP and zero copy
Patch 4/4: Fix Tx copy wakeup handling for XDP zero copy

Meghana Malladi (4):
  net: ti: icssg-prueth: Fix AF_XDP fill ring alloc and wakeup condition
  net: ti: icssg: Use undirected TX tag for native XDP in HSR offload
    mode
  net: ti: icssg: Use undirected TX tag for XDP zero copy in HSR offload
    mode
  net: ti: icssg: Fix XSK zero copy TX during application wakeup

 drivers/net/ethernet/ti/icssg/icssg_common.c | 62 +++++++++++++-------
 1 file changed, 41 insertions(+), 21 deletions(-)


base-commit: 29899ec61ac6fcc9d46f5f8d0b72117d9a676c2e
prerequisite-patch-id: ad8d47ed85a33f742a58e9f48e060303908493ba
-- 
2.43.0


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH net 1/4] net: ti: icssg-prueth: Fix AF_XDP fill ring alloc and wakeup condition
  2026-06-11 18:57 [PATCH net 0/4] ICSSG XDP zero copy bug fixes Meghana Malladi
@ 2026-06-11 18:57 ` Meghana Malladi
  2026-06-12 18:58   ` sashiko-bot
  2026-06-11 18:57 ` [PATCH net 2/4] net: ti: icssg: Use undirected TX tag for native XDP in HSR offload mode Meghana Malladi
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: Meghana Malladi @ 2026-06-11 18:57 UTC (permalink / raw)
  To: diogo.ivo, haokexin, vadim.fedorenko, devnexen, horms,
	jacob.e.keller, m-malladi, sdf, john.fastabend, hawk, daniel, ast,
	pabeni, kuba, edumazet, davem, andrew+netdev
  Cc: bpf, linux-kernel, netdev, linux-arm-kernel, srk,
	Vignesh Raghavendra, Roger Quadros, danishanwar

emac_rx_packet_zc() calls prueth_rx_alloc_zc() with count (frames
received in the current NAPI poll) as the allocation budget.  Two
problems arise from this:

1. When the CPPI5 descriptor pool is exhausted (avail_desc == 0,
   FDQ already holds the maximum number of descriptors), count > 0
   still triggers allocation attempts that all fail, spamming the
   kernel log with "rx push: failed to allocate descriptor" at
   high packet rates.

2. The XSK wakeup condition "ret < count" is wrong when avail_desc
   is zero: ret == 0 and count can be up to 64, so the condition is
   always true.  This causes ~200 spurious ndo_xsk_wakeup() calls
   per second even when the FDQ is already full, wasting CPU cycles
   in repeated NAPI invocations that process zero frames.

Fix both by introducing alloc_budget = min(budget, avail_desc):
- When avail_desc == 0 no allocation is attempted, avoiding pool
  exhaustion errors.  The wakeup condition "ret < alloc_budget"
  evaluates to 0 < 0 == false, correctly clearing the wakeup flag
  so the hardware IRQ re-arms NAPI without spurious kicks.
- In steady state avail_desc == count <= budget, so alloc_budget
  == count and behaviour is unchanged.
- After a dry-ring stall (count == 0, avail_desc > 0), alloc_budget
  > 0 causes new descriptors to be posted to the FDQ so the hardware
  can resume receiving immediately.

Fixes: 7a64bb388df3 ("net: ti: icssg-prueth: Add AF_XDP zero copy for RX")
Signed-off-by: Meghana Malladi <m-malladi@ti.com>
---
 drivers/net/ethernet/ti/icssg/icssg_common.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/ti/icssg/icssg_common.c b/drivers/net/ethernet/ti/icssg/icssg_common.c
index a28a608f9bf4..55a696912811 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_common.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_common.c
@@ -927,6 +927,7 @@ static int emac_rx_packet_zc(struct prueth_emac *emac, u32 flow_id,
 	struct cppi5_host_desc_t *desc_rx;
 	struct prueth_swdata *swdata;
 	dma_addr_t desc_dma, buf_dma;
+	int avail_desc, alloc_budget;
 	struct xdp_buff *xdp;
 	int xdp_status = 0;
 	int count = 0;
@@ -993,16 +994,13 @@ static int emac_rx_packet_zc(struct prueth_emac *emac, u32 flow_id,
 	if (xdp_status & ICSSG_XDP_REDIR)
 		xdp_do_flush();
 
-	/* Allocate xsk buffers from the pool for the "count" number of
-	 * packets processed in order to be able to receive more packets.
-	 */
-	ret = prueth_rx_alloc_zc(emac, count);
+	avail_desc = k3_cppi_desc_pool_avail(rx_chn->desc_pool);
+	alloc_budget = min_t(int, budget, avail_desc);
+
+	ret = prueth_rx_alloc_zc(emac, alloc_budget);
 
 	if (xsk_uses_need_wakeup(rx_chn->xsk_pool)) {
-		/* If the user space doesn't provide enough buffers then it must
-		 * explicitly wake up the kernel when new buffers are available
-		 */
-		if (ret < count)
+		if (ret < alloc_budget)
 			xsk_set_rx_need_wakeup(rx_chn->xsk_pool);
 		else
 			xsk_clear_rx_need_wakeup(rx_chn->xsk_pool);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH net 2/4] net: ti: icssg: Use undirected TX tag for native XDP in HSR offload mode
  2026-06-11 18:57 [PATCH net 0/4] ICSSG XDP zero copy bug fixes Meghana Malladi
  2026-06-11 18:57 ` [PATCH net 1/4] net: ti: icssg-prueth: Fix AF_XDP fill ring alloc and wakeup condition Meghana Malladi
@ 2026-06-11 18:57 ` Meghana Malladi
  2026-06-12 18:58   ` sashiko-bot
  2026-06-11 18:57 ` [PATCH net 3/4] net: ti: icssg: Use undirected TX tag for XDP zero copy " Meghana Malladi
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: Meghana Malladi @ 2026-06-11 18:57 UTC (permalink / raw)
  To: diogo.ivo, haokexin, vadim.fedorenko, devnexen, horms,
	jacob.e.keller, m-malladi, sdf, john.fastabend, hawk, daniel, ast,
	pabeni, kuba, edumazet, davem, andrew+netdev
  Cc: bpf, linux-kernel, netdev, linux-arm-kernel, srk,
	Vignesh Raghavendra, Roger Quadros, danishanwar

emac_xmit_xdp_frame() always sets the CPPI5 descriptor destination
tag to emac->port_id, which directs the PRU firmware to transmit
the frame on that specific slave port only.  In HSR offload mode
this bypasses the firmware's HSR duplication logic: the frame goes
out on one ring leg and never appears on the other, breaking HSR
redundancy for XDP_TX paths.

icssg_ndo_start_xmit() already handles this correctly: when HSR
offload mode is active and NETIF_F_HW_HSR_DUP is set it substitutes
PRUETH_UNDIRECTED_PKT_DST_TAG (port 0) so the PRU duplicates the
frame to both slave ports.  It also sets PRUETH_UNDIRECTED_PKT_TAG_INS
in epib[1] when NETIF_F_HW_HSR_TAG_INS is set so the PRU inserts the
HSR sequence tag, which XDP_TX frames lack (the tag is stripped by
the PRU on RX before the frame reaches the XDP program).

Apply the same logic in emac_xmit_xdp_frame() so XDP_TX frames in
HSR mode are treated identically to skb TX via hsr0.

Fixes: 62aa3246f462 ("net: ti: icssg-prueth: Add XDP support")
Signed-off-by: Meghana Malladi <m-malladi@ti.com>
---
 drivers/net/ethernet/ti/icssg/icssg_common.c | 21 ++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/ti/icssg/icssg_common.c b/drivers/net/ethernet/ti/icssg/icssg_common.c
index 55a696912811..ede32f266729 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_common.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_common.c
@@ -696,6 +696,7 @@ u32 emac_xmit_xdp_frame(struct prueth_emac *emac,
 	dma_addr_t desc_dma, buf_dma;
 	struct prueth_swdata *swdata;
 	struct page *page;
+	u32 dst_tag_id;
 	u32 *epib;
 	int ret;
 
@@ -737,9 +738,25 @@ u32 emac_xmit_xdp_frame(struct prueth_emac *emac,
 
 	/* set dst tag to indicate internal qid at the firmware which is at
 	 * bit8..bit15. bit0..bit7 indicates port num for directed
-	 * packets in case of switch mode operation
+	 * packets in case of switch mode operation and port num 0
+	 * for undirected packets in case of HSR offload mode.
+	 *
+	 * XDP_TX frames arrive on a slave port with the HSR tag already
+	 * stripped by the PRU firmware.  Like skb TX via hsr0, they must
+	 * be sent as undirected so the PRU duplicates them to both ports
+	 * and re-inserts the HSR sequence tag.
 	 */
-	cppi5_desc_set_tags_ids(&first_desc->hdr, 0, (emac->port_id | (q_idx << 8)));
+	dst_tag_id = emac->port_id | (q_idx << 8);
+
+	if (emac->prueth->is_hsr_offload_mode &&
+	    (ndev->features & NETIF_F_HW_HSR_DUP))
+		dst_tag_id = PRUETH_UNDIRECTED_PKT_DST_TAG;
+
+	if (emac->prueth->is_hsr_offload_mode &&
+	    (ndev->features & NETIF_F_HW_HSR_TAG_INS))
+		epib[1] |= PRUETH_UNDIRECTED_PKT_TAG_INS;
+
+	cppi5_desc_set_tags_ids(&first_desc->hdr, 0, dst_tag_id);
 	k3_udma_glue_tx_dma_to_cppi5_addr(tx_chn->tx_chn, &buf_dma);
 	cppi5_hdesc_attach_buf(first_desc, buf_dma, xdpf->len, buf_dma, xdpf->len);
 	swdata = cppi5_hdesc_get_swdata(first_desc);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH net 3/4] net: ti: icssg: Use undirected TX tag for XDP zero copy in HSR offload mode
  2026-06-11 18:57 [PATCH net 0/4] ICSSG XDP zero copy bug fixes Meghana Malladi
  2026-06-11 18:57 ` [PATCH net 1/4] net: ti: icssg-prueth: Fix AF_XDP fill ring alloc and wakeup condition Meghana Malladi
  2026-06-11 18:57 ` [PATCH net 2/4] net: ti: icssg: Use undirected TX tag for native XDP in HSR offload mode Meghana Malladi
@ 2026-06-11 18:57 ` Meghana Malladi
  2026-06-12 18:58   ` sashiko-bot
  2026-06-11 18:57 ` [PATCH net 4/4] net: ti: icssg: Fix XSK zero copy TX during application wakeup Meghana Malladi
  2026-06-15 23:40 ` [PATCH net 0/4] ICSSG XDP zero copy bug fixes patchwork-bot+netdevbpf
  4 siblings, 1 reply; 11+ messages in thread
From: Meghana Malladi @ 2026-06-11 18:57 UTC (permalink / raw)
  To: diogo.ivo, haokexin, vadim.fedorenko, devnexen, horms,
	jacob.e.keller, m-malladi, sdf, john.fastabend, hawk, daniel, ast,
	pabeni, kuba, edumazet, davem, andrew+netdev
  Cc: bpf, linux-kernel, netdev, linux-arm-kernel, srk,
	Vignesh Raghavendra, Roger Quadros, danishanwar

emac_xsk_xmit_zc() has the same issue as the fixed emac_xmit_xdp_frame():
it always sets the CPPI5 descriptor destination tag to emac->port_id,
which directs the PRU firmware to transmit on only one slave port in HSR
mode, breaking redundancy.

Apply the same fix: in HSR offload mode when NETIF_F_HW_HSR_DUP is set,
use PRUETH_UNDIRECTED_PKT_DST_TAG (port 0) so the PRU duplicates frames
to both ports. Also set PRUETH_UNDIRECTED_PKT_TAG_INS when
NETIF_F_HW_HSR_TAG_INS is set so the PRU re-inserts the HSR sequence tag
that was stripped by the PRU on RX before the XDP program saw the frame.

This ensures XSK XDP_TX frames in HSR mode are treated identically to
skb TX via hsr0.

Fixes: 8756ef2eb078 ("net: ti: icssg-prueth: Add AF_XDP zero copy for TX")
Signed-off-by: Meghana Malladi <m-malladi@ti.com>
---
 drivers/net/ethernet/ti/icssg/icssg_common.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/ti/icssg/icssg_common.c b/drivers/net/ethernet/ti/icssg/icssg_common.c
index ede32f266729..82ddef9c17d5 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_common.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_common.c
@@ -105,6 +105,7 @@ static int emac_xsk_xmit_zc(struct prueth_emac *emac,
 	struct xdp_desc xdp_desc;
 	int num_tx = 0, pkt_len;
 	int descs_avail, ret;
+	u32 dst_tag_id;
 	u32 *epib;
 	int i;
 
@@ -137,9 +138,17 @@ static int emac_xsk_xmit_zc(struct prueth_emac *emac,
 		epib[0] = 0;
 		epib[1] = 0;
 		cppi5_hdesc_set_pktlen(host_desc, pkt_len);
-		cppi5_desc_set_tags_ids(&host_desc->hdr, 0,
-					(emac->port_id | (q_idx << 8)));
+		dst_tag_id = emac->port_id | (q_idx << 8);
+
+		if (emac->prueth->is_hsr_offload_mode &&
+		    (ndev->features & NETIF_F_HW_HSR_DUP))
+			dst_tag_id = PRUETH_UNDIRECTED_PKT_DST_TAG;
+
+		if (emac->prueth->is_hsr_offload_mode &&
+		    (ndev->features & NETIF_F_HW_HSR_TAG_INS))
+			epib[1] |= PRUETH_UNDIRECTED_PKT_TAG_INS;
 
+		cppi5_desc_set_tags_ids(&host_desc->hdr, 0, dst_tag_id);
 		k3_udma_glue_tx_dma_to_cppi5_addr(tx_chn->tx_chn, &dma_buf);
 		cppi5_hdesc_attach_buf(host_desc, dma_buf, pkt_len, dma_buf,
 				       pkt_len);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH net 4/4] net: ti: icssg: Fix XSK zero copy TX during application wakeup
  2026-06-11 18:57 [PATCH net 0/4] ICSSG XDP zero copy bug fixes Meghana Malladi
                   ` (2 preceding siblings ...)
  2026-06-11 18:57 ` [PATCH net 3/4] net: ti: icssg: Use undirected TX tag for XDP zero copy " Meghana Malladi
@ 2026-06-11 18:57 ` Meghana Malladi
  2026-06-12 18:58   ` sashiko-bot
  2026-06-15 23:21   ` Jakub Kicinski
  2026-06-15 23:40 ` [PATCH net 0/4] ICSSG XDP zero copy bug fixes patchwork-bot+netdevbpf
  4 siblings, 2 replies; 11+ messages in thread
From: Meghana Malladi @ 2026-06-11 18:57 UTC (permalink / raw)
  To: diogo.ivo, haokexin, vadim.fedorenko, devnexen, horms,
	jacob.e.keller, m-malladi, sdf, john.fastabend, hawk, daniel, ast,
	pabeni, kuba, edumazet, davem, andrew+netdev
  Cc: bpf, linux-kernel, netdev, linux-arm-kernel, srk,
	Vignesh Raghavendra, Roger Quadros, danishanwar

emac_xsk_xmit_zc() handles tx xmit for zero copy and gets called
inside napi context. User application wakes up the kernel while
initiating the transmit which triggers napi to start processing
the tx packets. The num_tx check inside emac_tx_complete_packets()
returns early if no packet transfer happen hindering the call
to emac_xsk_xmit_zc(). Remove this check to let application
wakeup initiate zero copy xmit traffic.

Add __netif_tx_lock() to ensure that the TX queue is protected
from concurrent access during the transmission of XDP frames.
This fixes netdev watchdog timeout for long runs.

Fixes: e2dc7bfd677f ("net: ti: icssg-prueth: Move common functions into a separate file")
Signed-off-by: Meghana Malladi <m-malladi@ti.com>
---
 drivers/net/ethernet/ti/icssg/icssg_common.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/ti/icssg/icssg_common.c b/drivers/net/ethernet/ti/icssg/icssg_common.c
index 82ddef9c17d5..c3f3cacdb28e 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_common.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_common.c
@@ -93,8 +93,8 @@ void prueth_ndev_del_tx_napi(struct prueth_emac *emac, int num)
 }
 EXPORT_SYMBOL_GPL(prueth_ndev_del_tx_napi);
 
-static int emac_xsk_xmit_zc(struct prueth_emac *emac,
-			    unsigned int q_idx)
+static void emac_xsk_xmit_zc(struct prueth_emac *emac,
+			     unsigned int q_idx)
 {
 	struct prueth_tx_chn *tx_chn = &emac->tx_chns[q_idx];
 	struct xsk_buff_pool *pool = tx_chn->xsk_pool;
@@ -115,7 +115,7 @@ static int emac_xsk_xmit_zc(struct prueth_emac *emac,
 	 * necessary
 	 */
 	if (descs_avail <= MAX_SKB_FRAGS)
-		return 0;
+		return;
 
 	descs_avail -= MAX_SKB_FRAGS;
 
@@ -169,9 +169,6 @@ static int emac_xsk_xmit_zc(struct prueth_emac *emac,
 
 		num_tx++;
 	}
-
-	xsk_tx_release(tx_chn->xsk_pool);
-	return num_tx;
 }
 
 void prueth_xmit_free(struct prueth_tx_chn *tx_chn,
@@ -279,9 +276,6 @@ int emac_tx_complete_packets(struct prueth_emac *emac, int chn,
 		num_tx++;
 	}
 
-	if (!num_tx)
-		return 0;
-
 	netif_txq = netdev_get_tx_queue(ndev, chn);
 	netdev_tx_completed_queue(netif_txq, num_tx, total_bytes);
 
@@ -306,7 +300,9 @@ int emac_tx_complete_packets(struct prueth_emac *emac, int chn,
 
 		netif_txq = netdev_get_tx_queue(ndev, chn);
 		txq_trans_cond_update(netif_txq);
+		__netif_tx_lock(netif_txq, smp_processor_id());
 		emac_xsk_xmit_zc(emac, chn);
+		__netif_tx_unlock(netif_txq);
 	}
 
 	return num_tx;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH net 2/4] net: ti: icssg: Use undirected TX tag for native XDP in HSR offload mode
  2026-06-11 18:57 ` [PATCH net 2/4] net: ti: icssg: Use undirected TX tag for native XDP in HSR offload mode Meghana Malladi
@ 2026-06-12 18:58   ` sashiko-bot
  0 siblings, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-06-12 18:58 UTC (permalink / raw)
  To: Meghana Malladi; +Cc: bpf

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] DMA Mapping / Page Pool Corruption
--

commit e56804b68dffcb60ec1826c1b1a00d1c6ff8b34b
Author: Meghana Malladi <m-malladi@ti.com>

net: ti: icssg: Use undirected TX tag for native XDP in HSR offload mode

This commit updates emac_xmit_xdp_frame() to set the correct destination
tag and tag insertion flags for XDP TX frames when in HSR offload mode.
This allows the PRU firmware to properly duplicate the frames and insert
the HSR sequence tag.

> diff --git a/drivers/net/ethernet/ti/icssg/icssg_common.c b/drivers/net/ethernet/ti/icssg/icssg_common.c
> index 55a696912811f..ede32f266729e 100644
> --- a/drivers/net/ethernet/ti/icssg/icssg_common.c
> +++ b/drivers/net/ethernet/ti/icssg/icssg_common.c

[ ... ]

> @@ -737,9 +738,25 @@ u32 emac_xmit_xdp_frame(struct prueth_emac *emac,
>  
>  	/* set dst tag to indicate internal qid at the firmware which is at
>  	 * bit8..bit15. bit0..bit7 indicates port num for directed
> -	 * packets in case of switch mode operation
> +	 * packets in case of switch mode operation and port num 0
> +	 * for undirected packets in case of HSR offload mode.
> +	 *
> +	 * XDP_TX frames arrive on a slave port with the HSR tag already
> +	 * stripped by the PRU firmware.  Like skb TX via hsr0, they must
> +	 * be sent as undirected so the PRU duplicates them to both ports
> +	 * and re-inserts the HSR sequence tag.
>  	 */
> -	cppi5_desc_set_tags_ids(&first_desc->hdr, 0, (emac->port_id | (q_idx << 8)));
> +	dst_tag_id = emac->port_id | (q_idx << 8);
> +
> +	if (emac->prueth->is_hsr_offload_mode &&
> +	    (ndev->features & NETIF_F_HW_HSR_DUP))
> +		dst_tag_id = PRUETH_UNDIRECTED_PKT_DST_TAG;
> +
> +	if (emac->prueth->is_hsr_offload_mode &&
> +	    (ndev->features & NETIF_F_HW_HSR_TAG_INS))
> +		epib[1] |= PRUETH_UNDIRECTED_PKT_TAG_INS;
> +
> +	cppi5_desc_set_tags_ids(&first_desc->hdr, 0, dst_tag_id);

[Severity: High]
This is a pre-existing issue, but is it possible that prueth_xmit_free()
inadvertently destroys the persistent DMA mapping managed by the page pool
for XDP_TX frames?

In emac_xmit_xdp_frame(), when an XDP frame is transmitted via XDP_TX, it
reuses the page pool's pre-existing DMA address without creating a new mapping:

    if (buff_type == PRUETH_TX_BUFF_TYPE_XDP_TX) {
        page = virt_to_head_page(xdpf->data);
        ...
        buf_dma = page_pool_get_dma_addr(page);
        buf_dma += xdpf->headroom + sizeof(struct xdp_frame);
    } else {
        buf_dma = dma_map_single(...);

However, during TX completion or error handling, prueth_xmit_free()
unconditionally calls dma_unmap_single() on the buffer for PRUETH_SWDATA_XDPF:

    dma_unmap_single(tx_chn->dma_dev, buf_dma, buf_dma_len,
                     DMA_TO_DEVICE);

Could this cause an IOMMU fault or memory corruption when this page is
later recycled and the hardware tries to DMA into the unmapped address?

>  	k3_udma_glue_tx_dma_to_cppi5_addr(tx_chn->tx_chn, &buf_dma);
>  	cppi5_hdesc_attach_buf(first_desc, buf_dma, xdpf->len, buf_dma, xdpf->len);
>  	swdata = cppi5_hdesc_get_swdata(first_desc);

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260611185744.2498070-1-m-malladi@ti.com?part=2

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH net 4/4] net: ti: icssg: Fix XSK zero copy TX during application wakeup
  2026-06-11 18:57 ` [PATCH net 4/4] net: ti: icssg: Fix XSK zero copy TX during application wakeup Meghana Malladi
@ 2026-06-12 18:58   ` sashiko-bot
  2026-06-15 23:21   ` Jakub Kicinski
  1 sibling, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-06-12 18:58 UTC (permalink / raw)
  To: Meghana Malladi; +Cc: bpf

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:

New issues:
- [High] Removal of `xsk_tx_release()` prevents the AF_XDP TX ring consumer pointer from being updated, permanently stalling zero-copy transmissions.
- [High] The TX queue's `trans_start` timestamp is unconditionally updated even if no packets are transmitted, defeating the netdev watchdog.
- [Low] The variable `num_tx` is initialized and incremented but never read.

Pre-existing issues:
- [High] AF_XDP descriptors and Completion Queue (CQ) slots are permanently leaked on hardware allocation failure.
--

commit 569205869c791341578b147053176ec7b14de505
Author: Meghana Malladi <m-malladi@ti.com>

net: ti: icssg: Fix XSK zero copy TX during application wakeup
    
This patch modifies emac_xsk_xmit_zc() to handle zero-copy TX without returning
the number of packets transmitted. It removes the early return in
emac_tx_complete_packets() to allow application wakeups to initiate zero-copy
xmit traffic, and adds __netif_tx_lock() for queue protection.

> diff --git a/drivers/net/ethernet/ti/icssg/icssg_common.c b/drivers/net/ethernet/ti/icssg/icssg_common.c
> index 82ddef9c17d54..c3f3cacdb28e7 100644
> --- a/drivers/net/ethernet/ti/icssg/icssg_common.c
> +++ b/drivers/net/ethernet/ti/icssg/icssg_common.c
> @@ -93,8 +93,8 @@ void prueth_ndev_del_tx_napi(struct prueth_emac *emac, int num)
>  }
>  EXPORT_SYMBOL_GPL(prueth_ndev_del_tx_napi);
>  
> -static int emac_xsk_xmit_zc(struct prueth_emac *emac,
> -			    unsigned int q_idx)
> +static void emac_xsk_xmit_zc(struct prueth_emac *emac,
> +			     unsigned int q_idx)
>  {
>  	struct prueth_tx_chn *tx_chn = &emac->tx_chns[q_idx];
>  	struct xsk_buff_pool *pool = tx_chn->xsk_pool;
> @@ -115,7 +115,7 @@ static int emac_xsk_xmit_zc(struct prueth_emac *emac,
>  	 * necessary
>  	 */
>  	if (descs_avail <= MAX_SKB_FRAGS)
> -		return 0;
> +		return;
>  
>  	descs_avail -= MAX_SKB_FRAGS;
>  
> @@ -169,9 +169,6 @@ static int emac_xsk_xmit_zc(struct prueth_emac *emac,
>  
>  		num_tx++;
>  	}

[Severity: High]
This is a pre-existing issue, but does early exit on hardware push failure
permanently leak the peeked AF_XDP descriptor?

If k3_udma_glue_push_tx_chn() fails, the driver breaks out of the loop right
before the num_tx increment shown above:

		if (ret) {
			ndev->stats.tx_errors++;
			k3_cppi_desc_pool_free(tx_chn->desc_pool, host_desc);
			break;
		}

At this point, xsk_tx_peek_desc() has already consumed the descriptor from
the user space TX ring. Because the packet is never pushed to hardware, it
will never trigger a TX completion interrupt, and xsk_tx_completed() will
never be called.

Does the driver need to manually submit the completion for dropped packets
here to prevent the memory from being permanently lost to the application?

> -
> -	xsk_tx_release(tx_chn->xsk_pool);
> -	return num_tx;

[Severity: High]
Does removing xsk_tx_release() prevent the AF_XDP TX ring consumer pointer
from being updated? 

Since xsk_tx_peek_desc() only advances a local cached consumer pointer, it
seems xsk_tx_release() is required to publish this pointer to the shared
memory ring. 

Without this, will userspace eventually observe the TX ring as completely
full and stop producing new packets, leading to a permanent traffic stall?

[Severity: Low]
Since the return of num_tx was removed and the function changed to void,
is the num_tx variable now unused? 

It looks like it is initialized and incremented inside the loop but never
read.

>  }
>  
>  void prueth_xmit_free(struct prueth_tx_chn *tx_chn,
> @@ -279,9 +276,6 @@ int emac_tx_complete_packets(struct prueth_emac *emac, int chn,
>  		num_tx++;
>  	}
>  
> -	if (!num_tx)
> -		return 0;
> -

[Severity: High]
Because this early return was removed, does the code now unconditionally
update the TX queue's trans_start timestamp on every NAPI poll?

Later in this function, if tx_chn->xsk_pool is set, the driver calls
txq_trans_cond_update(), which updates txq->trans_start to jiffies. 

If the hardware stalls but NAPI is still being polled (e.g., due to userspace
wakeups or RX packets), trans_start will continually be pushed forward.

Will this mask genuine hardware TX stalls from the kernel and prevent the
netdev watchdog from triggering a recovery?

>  	netif_txq = netdev_get_tx_queue(ndev, chn);
>  	netdev_tx_completed_queue(netif_txq, num_tx, total_bytes);
>  
> @@ -306,7 +300,9 @@ int emac_tx_complete_packets(struct prueth_emac *emac, int chn,
>  
>  		netif_txq = netdev_get_tx_queue(ndev, chn);
>  		txq_trans_cond_update(netif_txq);
> +		__netif_tx_lock(netif_txq, smp_processor_id());
>  		emac_xsk_xmit_zc(emac, chn);
> +		__netif_tx_unlock(netif_txq);
>  	}
>  
>  	return num_tx;

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260611185744.2498070-1-m-malladi@ti.com?part=4

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH net 1/4] net: ti: icssg-prueth: Fix AF_XDP fill ring alloc and wakeup condition
  2026-06-11 18:57 ` [PATCH net 1/4] net: ti: icssg-prueth: Fix AF_XDP fill ring alloc and wakeup condition Meghana Malladi
@ 2026-06-12 18:58   ` sashiko-bot
  0 siblings, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-06-12 18:58 UTC (permalink / raw)
  To: Meghana Malladi; +Cc: bpf

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

Pre-existing issues:
- [Critical] Integer underflow in `pkt_len -= 4` leads to massive XDP out-of-bounds read/write in Zero Copy mode and skb_over_panic in standard mode.
- [High] In `icssg_napi_rx_poll()`, when zero-copy is enabled, `num_rx` is overwritten instead of accumulated across multiple flows, and the full `budget` is passed to each flow.
--

commit c6fd345481cd54bff877bdb42096a81eabfe43d0
Author: Meghana Malladi <m-malladi@ti.com>

net: ti: icssg-prueth: Fix AF_XDP fill ring alloc and wakeup condition

This patch fixes AF_XDP fill ring allocation by introducing an allocation
budget based on available descriptors. It prevents pool exhaustion errors
and spurious XSK wakeups by avoiding allocations when the descriptor pool
is empty.

> diff --git a/drivers/net/ethernet/ti/icssg/icssg_common.c b/drivers/net/ethernet/ti/icssg/icssg_common.c
> index a28a608f9bf4b..55a696912811f 100644
> --- a/drivers/net/ethernet/ti/icssg/icssg_common.c
> +++ b/drivers/net/ethernet/ti/icssg/icssg_common.c
> @@ -927,6 +927,7 @@ static int emac_rx_packet_zc(struct prueth_emac *emac, u32 flow_id,
>  	struct cppi5_host_desc_t *desc_rx;
>  	struct prueth_swdata *swdata;
>  	dma_addr_t desc_dma, buf_dma;
> +	int avail_desc, alloc_budget;

[Severity: High]
This isn't a bug introduced by this patch, but could icssg_napi_rx_poll()
mishandle the budget and num_rx values when calling emac_rx_packet_zc()
for multiple flows?

In icssg_napi_rx_poll():

    if (rx_chn->xsk_pool) {
        num_rx = emac_rx_packet_zc(emac, flow, budget);
    } else {

Because num_rx is overwritten instead of accumulated across multiple flows,
and the full budget is unconditionally passed to each flow, might the driver
process up to N * budget packets per NAPI cycle? If the last flow evaluated
processes 0 packets while previous flows processed many, could NAPI
incorrectly assume no work was done and drop out of polling mode?

[Severity: Critical]
This is a pre-existing issue, but does unconditionally subtracting 4 from
pkt_len cause an integer underflow if a short descriptor is received?

In emac_rx_packet_zc():

    pkt_len = cppi5_hdesc_get_pktlen(desc_rx);
    /* firmware adds 4 CRC bytes, strip them */
    pkt_len -= 4;
    ...
    xsk_buff_set_size(xdp, pkt_len);

If the hardware provides a malformed descriptor with a length less than 4,
the unsigned subtraction could underflow, resulting in a large 32-bit value.
When passed to xsk_buff_set_size(), this sets a malformed data_end, which
could allow an XDP program to perform out-of-bounds reads or writes.

The same integer underflow exists in the standard RX path in
emac_rx_packet():

    pkt_len -= 4;
    ...
    skb_put(skb, pkt_len);

Passing the underflowed length to skb_put() might directly trigger a kernel
panic via skb_over_panic(). Should there be a bounds check before the
subtraction?

>  	struct xdp_buff *xdp;
>  	int xdp_status = 0;
>  	int count = 0;
> @@ -993,16 +994,13 @@ static int emac_rx_packet_zc(struct prueth_emac *emac, u32 flow_id,
>  	if (xdp_status & ICSSG_XDP_REDIR)
>  		xdp_do_flush();
>  
> -	/* Allocate xsk buffers from the pool for the "count" number of
> -	 * packets processed in order to be able to receive more packets.
> -	 */
> -	ret = prueth_rx_alloc_zc(emac, count);
> +	avail_desc = k3_cppi_desc_pool_avail(rx_chn->desc_pool);
> +	alloc_budget = min_t(int, budget, avail_desc);
> +
> +	ret = prueth_rx_alloc_zc(emac, alloc_budget);
>  
>  	if (xsk_uses_need_wakeup(rx_chn->xsk_pool)) {
> -		/* If the user space doesn't provide enough buffers then it must
> -		 * explicitly wake up the kernel when new buffers are available
> -		 */
> -		if (ret < count)
> +		if (ret < alloc_budget)
>  			xsk_set_rx_need_wakeup(rx_chn->xsk_pool);
>  		else
>  			xsk_clear_rx_need_wakeup(rx_chn->xsk_pool);

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260611185744.2498070-1-m-malladi@ti.com?part=1

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH net 3/4] net: ti: icssg: Use undirected TX tag for XDP zero copy in HSR offload mode
  2026-06-11 18:57 ` [PATCH net 3/4] net: ti: icssg: Use undirected TX tag for XDP zero copy " Meghana Malladi
@ 2026-06-12 18:58   ` sashiko-bot
  0 siblings, 0 replies; 11+ messages in thread
From: sashiko-bot @ 2026-06-12 18:58 UTC (permalink / raw)
  To: Meghana Malladi; +Cc: bpf

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

Pre-existing issues:
- [Critical] AF_XDP UMEM buffer and Completion Queue (CQ) slot leak due to unhandled completion for dropped descriptors.
- [Critical] Double-free of zero-copy buffer and memory leak of xdp_frame upon XDP_TX failure.
--

commit e244d2327204d5a8a195243fec7c3ad5c3b5cf36
Author: Meghana Malladi <m-malladi@ti.com>

net: ti: icssg: Use undirected TX tag for XDP zero copy in HSR offload mode

This patch updates emac_xsk_xmit_zc() to set the correct destination tags
when operating in HSR offload mode. It ensures that XSK XDP_TX frames are
duplicated to both ports when NETIF_F_HW_HSR_DUP is set, and handles HSR
sequence tag insertion.

> diff --git a/drivers/net/ethernet/ti/icssg/icssg_common.c b/drivers/net/ethernet/ti/icssg/icssg_common.c
> index ede32f266729e..82ddef9c17d54 100644
> --- a/drivers/net/ethernet/ti/icssg/icssg_common.c
> +++ b/drivers/net/ethernet/ti/icssg/icssg_common.c
[ ... ]
> @@ -137,9 +138,17 @@ static int emac_xsk_xmit_zc(struct prueth_emac *emac,
>  		epib[0] = 0;
>  		epib[1] = 0;
>  		cppi5_hdesc_set_pktlen(host_desc, pkt_len);
> -		cppi5_desc_set_tags_ids(&host_desc->hdr, 0,
> -					(emac->port_id | (q_idx << 8)));
> +		dst_tag_id = emac->port_id | (q_idx << 8);
> +
> +		if (emac->prueth->is_hsr_offload_mode &&
> +		    (ndev->features & NETIF_F_HW_HSR_DUP))
> +			dst_tag_id = PRUETH_UNDIRECTED_PKT_DST_TAG;
> +
> +		if (emac->prueth->is_hsr_offload_mode &&
> +		    (ndev->features & NETIF_F_HW_HSR_TAG_INS))
> +			epib[1] |= PRUETH_UNDIRECTED_PKT_TAG_INS;
>  
> +		cppi5_desc_set_tags_ids(&host_desc->hdr, 0, dst_tag_id);
>  		k3_udma_glue_tx_dma_to_cppi5_addr(tx_chn->tx_chn, &dma_buf);
>  		cppi5_hdesc_attach_buf(host_desc, dma_buf, pkt_len, dma_buf,
>  				       pkt_len);

[Severity: Critical]
This isn't a bug introduced by this patch, but looking at the failure paths
in emac_xsk_xmit_zc() further down in this loop:

		if (ret) {
			ndev->stats.tx_errors++;
			k3_cppi_desc_pool_free(tx_chn->desc_pool, host_desc);
			break;
		}

Does this code leak UMEM buffers and Completion Queue (CQ) slots?

The driver peeks an AF_XDP descriptor using xsk_tx_peek_desc(), which
reserves a slot in the CQ ring. If pushing to the DMA queue fails and the
loop breaks, the peeked descriptor is dropped without reaching the hardware.

Since xsk_tx_completed() will never be called for this descriptor, does this
leave a permanently reserved but un-submitted slot in the CQ ring,
potentially desynchronizing it and leaking slots?

[Severity: Critical]
This is another pre-existing issue in this file, but looking at XDP_TX
handling in emac_run_xdp():

	xdpf = xdp_convert_buff_to_frame(xdp);
	if (unlikely(!xdpf)) {
		ndev->stats.tx_dropped++;
		goto drop;
	}
	...
	if (result == ICSSG_XDP_CONSUMED) {
		ndev->stats.tx_dropped++;
		goto drop;
	}

And then in emac_rx_packet_zc():

	case ICSSG_XDP_CONSUMED:
		xsk_buff_free(xdp);
		break;

Could this sequence trigger a double-free of the zero-copy buffer and leak
the xdp_frame page?

If the XDP program returns XDP_TX, xdp_convert_buff_to_frame() (which calls
xdp_convert_zc_to_xdp_frame() for zero-copy pools) allocates a new page and
completely frees the original xdp_buff via xsk_buff_free().

If the transmit then fails, it returns ICSSG_XDP_CONSUMED but doesn't free
the newly allocated xdpf page. When ICSSG_XDP_CONSUMED is passed back to
emac_rx_packet_zc(), it explicitly calls xsk_buff_free(xdp) on the original
buffer that was already freed during conversion.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260611185744.2498070-1-m-malladi@ti.com?part=3

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH net 4/4] net: ti: icssg: Fix XSK zero copy TX during application wakeup
  2026-06-11 18:57 ` [PATCH net 4/4] net: ti: icssg: Fix XSK zero copy TX during application wakeup Meghana Malladi
  2026-06-12 18:58   ` sashiko-bot
@ 2026-06-15 23:21   ` Jakub Kicinski
  1 sibling, 0 replies; 11+ messages in thread
From: Jakub Kicinski @ 2026-06-15 23:21 UTC (permalink / raw)
  To: Meghana Malladi
  Cc: diogo.ivo, haokexin, vadim.fedorenko, devnexen, horms,
	jacob.e.keller, sdf, john.fastabend, hawk, daniel, ast, pabeni,
	edumazet, davem, andrew+netdev, bpf, linux-kernel, netdev,
	linux-arm-kernel, srk, Vignesh Raghavendra, Roger Quadros,
	danishanwar

On Fri, 12 Jun 2026 00:27:44 +0530 Meghana Malladi wrote:
> @@ -169,9 +169,6 @@ static int emac_xsk_xmit_zc(struct prueth_emac *emac,
>  
>  		num_tx++;
>  	}
> -
> -	xsk_tx_release(tx_chn->xsk_pool);
> -	return num_tx;

Why are you deleting this?

>  }
>  
>  void prueth_xmit_free(struct prueth_tx_chn *tx_chn,
> @@ -279,9 +276,6 @@ int emac_tx_complete_packets(struct prueth_emac *emac, int chn,
>  		num_tx++;
>  	}
>  
> -	if (!num_tx)
> -		return 0;

Does something prevent us from running all this code if budget is 0?
If budget is 0 we can complete normal Tx with skbs but we must
not touch any AF-XDP related state.

>  	netif_txq = netdev_get_tx_queue(ndev, chn);
>  	netdev_tx_completed_queue(netif_txq, num_tx, total_bytes);
>  
> @@ -306,7 +300,9 @@ int emac_tx_complete_packets(struct prueth_emac *emac, int chn,
>  
>  		netif_txq = netdev_get_tx_queue(ndev, chn);
>  		txq_trans_cond_update(netif_txq);

This looks misplaced, now we will hit it even if we didn't complete 
or submit any Tx.

> +		__netif_tx_lock(netif_txq, smp_processor_id());
>  		emac_xsk_xmit_zc(emac, chn);
> +		__netif_tx_unlock(netif_txq);
>  	}

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH net 0/4] ICSSG XDP zero copy bug fixes
  2026-06-11 18:57 [PATCH net 0/4] ICSSG XDP zero copy bug fixes Meghana Malladi
                   ` (3 preceding siblings ...)
  2026-06-11 18:57 ` [PATCH net 4/4] net: ti: icssg: Fix XSK zero copy TX during application wakeup Meghana Malladi
@ 2026-06-15 23:40 ` patchwork-bot+netdevbpf
  4 siblings, 0 replies; 11+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-06-15 23:40 UTC (permalink / raw)
  To: Meghana Malladi
  Cc: diogo.ivo, haokexin, vadim.fedorenko, devnexen, horms,
	jacob.e.keller, sdf, john.fastabend, hawk, daniel, ast, pabeni,
	kuba, edumazet, davem, andrew+netdev, bpf, linux-kernel, netdev,
	linux-arm-kernel, srk, vigneshr, rogerq, danishanwar

Hello:

This series was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Fri, 12 Jun 2026 00:27:40 +0530 you wrote:
> This patch series fixes bugs introduced while adding xdp
> zero copy support in the icssg driver.
> 
> Patch 1/4: Fix wakeup handling for Rx when available CPPI
> descriptor is zero
> Patch 2,3/4: Fix destination tag in CPPI descriptor to enable
> proper Tx xmit for HSR offload mode with XDP and zero copy
> Patch 4/4: Fix Tx copy wakeup handling for XDP zero copy
> 
> [...]

Here is the summary with links:
  - [net,1/4] net: ti: icssg-prueth: Fix AF_XDP fill ring alloc and wakeup condition
    https://git.kernel.org/netdev/net/c/dfb787f7d157
  - [net,2/4] net: ti: icssg: Use undirected TX tag for native XDP in HSR offload mode
    https://git.kernel.org/netdev/net/c/bcbf73d98195
  - [net,3/4] net: ti: icssg: Use undirected TX tag for XDP zero copy in HSR offload mode
    https://git.kernel.org/netdev/net/c/f9691288413c
  - [net,4/4] net: ti: icssg: Fix XSK zero copy TX during application wakeup
    (no matching commit)

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2026-06-15 23:40 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-11 18:57 [PATCH net 0/4] ICSSG XDP zero copy bug fixes Meghana Malladi
2026-06-11 18:57 ` [PATCH net 1/4] net: ti: icssg-prueth: Fix AF_XDP fill ring alloc and wakeup condition Meghana Malladi
2026-06-12 18:58   ` sashiko-bot
2026-06-11 18:57 ` [PATCH net 2/4] net: ti: icssg: Use undirected TX tag for native XDP in HSR offload mode Meghana Malladi
2026-06-12 18:58   ` sashiko-bot
2026-06-11 18:57 ` [PATCH net 3/4] net: ti: icssg: Use undirected TX tag for XDP zero copy " Meghana Malladi
2026-06-12 18:58   ` sashiko-bot
2026-06-11 18:57 ` [PATCH net 4/4] net: ti: icssg: Fix XSK zero copy TX during application wakeup Meghana Malladi
2026-06-12 18:58   ` sashiko-bot
2026-06-15 23:21   ` Jakub Kicinski
2026-06-15 23:40 ` [PATCH net 0/4] ICSSG XDP zero copy bug fixes patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox