Collect received skbs on a local list during RX polling and pass the
completed batch to netif_receive_skb_list(). This lets the networking
stack process packets from a poll cycle in bulk instead of handing each
skb up individually.

Speedup tested with bidirectional iperf3.

Before:

[ ID][Role] Interval           Transfer     Bitrate         Retr
[  5][TX-C]   0.00-10.00  sec   490 MBytes   411 Mbits/sec                  
sender
[  5][TX-C]   0.00-10.01  sec   488 MBytes   409 Mbits/sec                  
receiver
[  7][RX-C]   0.00-10.00  sec   176 MBytes   147 Mbits/sec  167            
sender
[  7][RX-C]   0.00-10.01  sec   175 MBytes   146 Mbits/sec                  
receiver

After:

[ ID][Role] Interval           Transfer     Bitrate         Retr
[  5][TX-C]   0.00-10.00  sec   502 MBytes   421 Mbits/sec                  
sender
[  5][TX-C]   0.00-10.01  sec   501 MBytes   420 Mbits/sec                  
receiver
[  7][RX-C]   0.00-10.00  sec   212 MBytes   178 Mbits/sec  148            
sender
[  7][RX-C]   0.00-10.01  sec   211 MBytes   177 Mbits/sec                  
receiver

Assisted-by: Codex:GPT-5.5
Signed-off-by: Rosen Penev <[email protected]>
---
 drivers/net/ethernet/freescale/ucc_geth.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/ucc_geth.c 
b/drivers/net/ethernet/freescale/ucc_geth.c
index 7af4b5e3f38e..bce1079fc06a 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -2894,6 +2894,7 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 
rxQ, int rx_work_limit
        u32 bd_status;
        u8 *bdBuffer;
        struct net_device *dev;
+       LIST_HEAD(rx_list);
 
        ugeth_vdbg("%s: IN", __func__);
 
@@ -2934,7 +2935,7 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 
rxQ, int rx_work_limit
 
                        dev->stats.rx_bytes += length;
                        /* Send the packet up the stack */
-                       netif_receive_skb(skb);
+                       list_add_tail(&skb->list, &rx_list);
                }
 
                skb = get_new_skb(ugeth, bd);
@@ -2960,6 +2961,8 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 
rxQ, int rx_work_limit
                bd_status = in_be32((u32 __iomem *)bd);
        }
 
+       netif_receive_skb_list(&rx_list);
+
        ugeth->rxBd[rxQ] = bd;
        return howmany;
 }
-- 
2.54.0


Reply via email to