]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
net: ti: icssg: Fix XSK zero copy TX during application wakeup
authorMeghana Malladi <m-malladi@ti.com>
Thu, 18 Jun 2026 10:03:48 +0000 (15:33 +0530)
committerJakub Kicinski <kuba@kernel.org>
Tue, 23 Jun 2026 21:45:32 +0000 (14:45 -0700)
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>
Link: https://patch.msgid.link/20260618100348.2209907-1-m-malladi@ti.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/ti/icssg/icssg_common.c

index 9c0280bedefbdbe4596706707d57c865f363bc7c..4a7d1a6f470b17d5dba84d9f3324419cfdfaad6c 100644 (file)
@@ -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;
 
@@ -170,8 +170,8 @@ static int emac_xsk_xmit_zc(struct prueth_emac *emac,
                num_tx++;
        }
 
-       xsk_tx_release(tx_chn->xsk_pool);
-       return num_tx;
+       if (num_tx)
+               xsk_tx_release(tx_chn->xsk_pool);
 }
 
 void prueth_xmit_free(struct prueth_tx_chn *tx_chn,
@@ -279,9 +279,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);
 
@@ -297,16 +294,18 @@ int emac_tx_complete_packets(struct prueth_emac *emac, int chn,
                __netif_tx_unlock(netif_txq);
        }
 
-       if (tx_chn->xsk_pool) {
-               if (xsk_frames_done)
+       if (budget && tx_chn->xsk_pool) {
+               if (xsk_frames_done) {
                        xsk_tx_completed(tx_chn->xsk_pool, xsk_frames_done);
+                       txq_trans_cond_update(netif_txq);
+               }
 
                if (xsk_uses_need_wakeup(tx_chn->xsk_pool))
                        xsk_set_tx_need_wakeup(tx_chn->xsk_pool);
 
-               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;