[PATCH net-next] net: ibm: emac: size RX buffers for the MTU

DORMANTno replies

From: Rosen Penev <hidden>
Date: 2026-10-08 03:51:24
Also in: lkml
Subsystem: networking drivers, the rest · Maintainers: Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds

Any MTU above ETH_DATA_LEN selects the largest MAL buffer size of 4080
bytes. A DSA conduit always runs with a slightly larger MTU for the
switch tag (1502 for qca8k), so every received frame then uses an 8K
slab object and a 4K cache invalidate even though it is at most 1520
bytes long. Size the buffers for the MTU instead, capped at the MAL
maximum as before. Larger jumbo frames still span several descriptors.

emac_change_mtu() only resized the ring, which is also where the jumbo
mode and the APM821xx maximum jumbo size are programmed, when the RX skb
size changed. 1500 and 1502 now share a skb size, so also resize the
ring whenever the old or new MTU is a jumbo one. Otherwise jumbo mode
stays off and 1502 byte frames are dropped when the MTU is raised while
the interface is up.

Routing a single TCP stream through the qca8k switch of a Meraki MX60
(APM82181, iperf3 median of 3, A/B in the same boot):

          LAN->WAN   WAN->LAN  (Mbit/s)
  before  538        476
  after   564        498

Assisted-by: LLM
Signed-off-by: Rosen Penev <redacted>
---
 drivers/net/ethernet/ibm/emac/core.c | 7 +++++--
 drivers/net/ethernet/ibm/emac/core.h | 5 +----
 2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c
index 248bc49ba8c6..1d2668905dcf 100644
--- a/drivers/net/ethernet/ibm/emac/core.c
+++ b/drivers/net/ethernet/ibm/emac/core.c
@@ -1116,8 +1116,11 @@ static int emac_change_mtu(struct net_device *ndev, int new_mtu)
 	DBG(dev, "change_mtu(%d)" NL, new_mtu);
 
 	if (netif_running(ndev)) {
-		/* Check if we really need to reinitialize RX ring */
-		if (emac_rx_skb_size(ndev->mtu) != emac_rx_skb_size(new_mtu))
+		/* Check if we really need to reinitialize RX ring. The
+		 * jumbo frame settings are only updated by a resize.
+		 */
+		if (emac_rx_skb_size(ndev->mtu) != emac_rx_skb_size(new_mtu) ||
+		    ndev->mtu > ETH_DATA_LEN || new_mtu > ETH_DATA_LEN)
 			ret = emac_resize_rx_ring(dev, new_mtu);
 	}
 
diff --git a/drivers/net/ethernet/ibm/emac/core.h b/drivers/net/ethernet/ibm/emac/core.h
index 0e571475849e..8f8b75eaf565 100644
--- a/drivers/net/ethernet/ibm/emac/core.h
+++ b/drivers/net/ethernet/ibm/emac/core.h
@@ -56,10 +56,7 @@
 /* RX BD size for the given MTU */
 static inline int emac_rx_size(int mtu)
 {
-	if (mtu > ETH_DATA_LEN)
-		return MAL_MAX_RX_SIZE;
-	else
-		return mal_rx_size(ETH_DATA_LEN + EMAC_MTU_OVERHEAD);
+	return mal_rx_size(max(mtu, ETH_DATA_LEN) + EMAC_MTU_OVERHEAD);
 }
 
 /* Size of RX skb for the given MTU */
-- 
2.56.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help