[PATCH net-next v2] net: stmmac: improve TSO/GSO queue selection

Lorenzo Bianconi lorenzo.bianconi at oss.qualcomm.com
Sat Aug 8 10:22:01 PDT 2026


GSO (TSO/USO) frames are currently always sent through queue 0 since
the driver assumed there was no way to determine which queues are TSO
capable. This unconditionally pins all GSO traffic to queue 0, bypassing
the per-flow queue distribution and any XPS setup.

Instead, pick the queue through netdev_pick_tx() and fall back to queue 0
only when the selected queue cannot provide hardware checksumming (COE
disabled) or, for the GSO types offloaded by hardware, cannot run TSO
(TBS enabled), since TSO and TBS cannot coexist on the same channel (see
stmmac_tso_channel_permitted()).

While at it, base the TSO capability check on priv->gso_enabled_types
rather than a hardcoded GSO type mask, so it matches the TSO/USO
capability actually used by the transmit path (e.g. UDP segmentation is
only offloaded on GMAC4).

Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi at oss.qualcomm.com>
---
Changes in v2:
- Take into account when checksum offload is not supported.
- Link to v1: https://lore.kernel.org/r/20260807-stmmac_select_queue-tso-fix-v1-1-4c4787bad02b@oss.qualcomm.com
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index b2b7d0242dd3..7a4bd0292966 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -6445,19 +6445,21 @@ static int stmmac_setup_tc(struct net_device *ndev, enum tc_setup_type type,
 static u16 stmmac_select_queue(struct net_device *dev, struct sk_buff *skb,
 			       struct net_device *sb_dev)
 {
-	int gso = skb_shinfo(skb)->gso_type;
+	u32 queue = netdev_pick_tx(dev, skb, NULL) % dev->real_num_tx_queues;
+	struct stmmac_priv *priv = netdev_priv(dev);
 
-	if (gso & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6 | SKB_GSO_UDP_L4)) {
-		/*
-		 * There is no way to determine the number of TSO/USO
-		 * capable Queues. Let's use always the Queue 0
-		 * because if TSO/USO is supported then at least this
-		 * one will be capable.
+	if (skb_is_gso(skb) &&
+	    (priv->plat->tx_queues_cfg[queue].coe_unsupported ||
+	     ((skb_shinfo(skb)->gso_type & priv->gso_enabled_types) &&
+	      !stmmac_tso_channel_permitted(priv, queue)))) {
+		/* GSO frames need hardware checksumming. Moreover, hardware
+		 * TSO/USO can't run on COE-less or TBS queues. In this case
+		 * fall back to the queue reserved for TSO (queue 0).
 		 */
 		return 0;
 	}
 
-	return netdev_pick_tx(dev, skb, NULL) % dev->real_num_tx_queues;
+	return queue;
 }
 
 static int stmmac_set_mac_address(struct net_device *ndev, void *addr)

---
base-commit: 8ac4255c1e0c83d2e1559a18b8918673116fc8d6
change-id: 20260807-stmmac_select_queue-tso-fix-06cc586d4022

Best regards,
-- 
Lorenzo Bianconi <lorenzo.bianconi at oss.qualcomm.com>




More information about the linux-arm-kernel mailing list