* [PATCH net-next] net: stmmac: fix .ndo_fix_features() @ 2026-02-23 11:24 Russell King (Oracle) 2026-02-25 1:30 ` Jakub Kicinski 0 siblings, 1 reply; 7+ messages in thread From: Russell King (Oracle) @ 2026-02-23 11:24 UTC (permalink / raw) To: Andrew Lunn Cc: Alexandre Torgue, Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, linux-arm-kernel, linux-stm32, netdev, Paolo Abeni netdev features documentation requires that .ndo_fix_features() is stateless: it shouldn't modify driver state. Yet, stmmac_fix_features() does exactly that, changing whether GSO frames are processed by the driver. Move this code to stmmac_set_features() instead, which is the correct place for it. We don't need to check whether TSO is supported; this is already handled via the setup of netdev->hw_features, and we are guaranteed that if netdev->hw_features indicates that a feature is not supported, .ndo_set_features() won't be called with it set. Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 82375d34ad57..a2a0985e8c37 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -6105,14 +6105,6 @@ static netdev_features_t stmmac_fix_features(struct net_device *dev, if (priv->plat->bugged_jumbo && (dev->mtu > ETH_DATA_LEN)) features &= ~NETIF_F_CSUM_MASK; - /* Disable tso if asked by ethtool */ - if ((priv->plat->flags & STMMAC_FLAG_TSO_EN) && (priv->dma_cap.tsoen)) { - if (features & NETIF_F_TSO) - priv->tso = true; - else - priv->tso = false; - } - return features; } @@ -6144,6 +6136,8 @@ static int stmmac_set_features(struct net_device *netdev, else priv->hw->hw_vlan_en = false; + priv->tso = !!(features & NETIF_F_TSO); + phylink_rx_clk_stop_block(priv->phylink); stmmac_set_hw_vlan_mode(priv, priv->hw); phylink_rx_clk_stop_unblock(priv->phylink); -- 2.47.3 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH net-next] net: stmmac: fix .ndo_fix_features() 2026-02-23 11:24 [PATCH net-next] net: stmmac: fix .ndo_fix_features() Russell King (Oracle) @ 2026-02-25 1:30 ` Jakub Kicinski 2026-02-25 8:24 ` Russell King (Oracle) 0 siblings, 1 reply; 7+ messages in thread From: Jakub Kicinski @ 2026-02-25 1:30 UTC (permalink / raw) To: Russell King (Oracle) Cc: Andrew Lunn, Alexandre Torgue, Andrew Lunn, David S. Miller, Eric Dumazet, linux-arm-kernel, linux-stm32, netdev, Paolo Abeni On Mon, 23 Feb 2026 11:24:51 +0000 Russell King (Oracle) wrote: > netdev features documentation requires that .ndo_fix_features() is > stateless: it shouldn't modify driver state. Yet, stmmac_fix_features() > does exactly that, changing whether GSO frames are processed by the > driver. > > Move this code to stmmac_set_features() instead, which is the correct > place for it. We don't need to check whether TSO is supported; this > is already handled via the setup of netdev->hw_features, and we are > guaranteed that if netdev->hw_features indicates that a feature is > not supported, .ndo_set_features() won't be called with it set. No lies detected, but is this enough? The whole TSO enablement looks quite wobbly (as you mentioned in another email IIRC). Only stmmac_hw_setup() actually calls stmmac_enable_tso(). And stmmac_set_features() does not call stmmac_hw_setup(). IDK what the cost of having TSO enabled is for this IP, it's entirely possible that there is no cost. So maybe we should set the TSO feature in features but not in hw_features which will make it "fixed" to be always enabled? And not bother with handling the changes? > Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> > --- > drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 10 ++-------- > 1 file changed, 2 insertions(+), 8 deletions(-) > > diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c > index 82375d34ad57..a2a0985e8c37 100644 > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c > @@ -6105,14 +6105,6 @@ static netdev_features_t stmmac_fix_features(struct net_device *dev, > if (priv->plat->bugged_jumbo && (dev->mtu > ETH_DATA_LEN)) > features &= ~NETIF_F_CSUM_MASK; > > - /* Disable tso if asked by ethtool */ > - if ((priv->plat->flags & STMMAC_FLAG_TSO_EN) && (priv->dma_cap.tsoen)) { > - if (features & NETIF_F_TSO) > - priv->tso = true; > - else > - priv->tso = false; > - } > - > return features; > } > > @@ -6144,6 +6136,8 @@ static int stmmac_set_features(struct net_device *netdev, > else > priv->hw->hw_vlan_en = false; > > + priv->tso = !!(features & NETIF_F_TSO); extra nit, I think you're inserting this in the middle of a section of code handling vlan config. > phylink_rx_clk_stop_block(priv->phylink); > stmmac_set_hw_vlan_mode(priv, priv->hw); > phylink_rx_clk_stop_unblock(priv->phylink); -- pw-bot: cr ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH net-next] net: stmmac: fix .ndo_fix_features() 2026-02-25 1:30 ` Jakub Kicinski @ 2026-02-25 8:24 ` Russell King (Oracle) 2026-02-25 10:27 ` Russell King (Oracle) 2026-02-25 13:26 ` Andrew Lunn 0 siblings, 2 replies; 7+ messages in thread From: Russell King (Oracle) @ 2026-02-25 8:24 UTC (permalink / raw) To: Jakub Kicinski Cc: Andrew Lunn, Alexandre Torgue, Andrew Lunn, David S. Miller, Eric Dumazet, linux-arm-kernel, linux-stm32, netdev, Paolo Abeni On Tue, Feb 24, 2026 at 05:30:37PM -0800, Jakub Kicinski wrote: > On Mon, 23 Feb 2026 11:24:51 +0000 Russell King (Oracle) wrote: > > netdev features documentation requires that .ndo_fix_features() is > > stateless: it shouldn't modify driver state. Yet, stmmac_fix_features() > > does exactly that, changing whether GSO frames are processed by the > > driver. > > > > Move this code to stmmac_set_features() instead, which is the correct > > place for it. We don't need to check whether TSO is supported; this > > is already handled via the setup of netdev->hw_features, and we are > > guaranteed that if netdev->hw_features indicates that a feature is > > not supported, .ndo_set_features() won't be called with it set. > > No lies detected, but is this enough? The whole TSO enablement > looks quite wobbly (as you mentioned in another email IIRC). > > Only stmmac_hw_setup() actually calls stmmac_enable_tso(). > And stmmac_set_features() does not call stmmac_hw_setup(). Looking deeper, dwmac4_enable_tso() has two paths depending on the "en" flag, both of which are commented as "enable TSO". Then, looking at the "Enable TSO" block of code in stmmac_hw_setup(), it looks to me like we can end up with some queues that have TSO enabled, and others which don't (because TBS has been enabled on the queue.) As far as I'm aware, the network layer doesn't support per-queue TSO. We can't call stmmac_hw_setup() from any path that we care about any state being preserved - it issues a software reset which causes everything, including the PTP clock, to be reset and all state then needs to be reloaded. Lastly, we don't need to disable the TSE bit (via stmmac_enable_tso() when we disable TSO, because there's a bit in the descriptors that also needs to be set for the packet to undergo TSO. However, if the system undergoes a suspend/resume with TSO disabled by the user, we'll call stmmac_hw_setup(), which as I note in the previous paragraph will reset all state, including the TSE bit. stmmac_enable_tso() won't be called, and thus the TSE bit will remain clear. If the user subsequently re-enables TSO, then we'll queue packets for TSO but the hardware won't have that enabled... That's a problem today. So, while you're right to point this out (I had missed it) it's a separate problem to the one being addressed in this patch. In fact, I think there's two new issues that have now been identified here. 1. The lack of setting TSE on resume if TSO is supported but but has been disabled by the user. 2. The interaction of TBS and TSO feature where some channels can support TSO and others not, which I don't think can be supported. So, I think if we have _any_ channel with TBS enabled, we have to disable TSO on the entire netdev. I think these need to be separate patches, and this one is still valid on its own. -- RMK's Patch system: https://www.armlinux.org.uk/developer/patches/ FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last! ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH net-next] net: stmmac: fix .ndo_fix_features() 2026-02-25 8:24 ` Russell King (Oracle) @ 2026-02-25 10:27 ` Russell King (Oracle) 2026-02-26 0:27 ` Jakub Kicinski 2026-02-25 13:26 ` Andrew Lunn 1 sibling, 1 reply; 7+ messages in thread From: Russell King (Oracle) @ 2026-02-25 10:27 UTC (permalink / raw) To: Jakub Kicinski Cc: Andrew Lunn, Alexandre Torgue, Andrew Lunn, David S. Miller, Eric Dumazet, linux-arm-kernel, linux-stm32, netdev, Paolo Abeni On Wed, Feb 25, 2026 at 08:24:10AM +0000, Russell King (Oracle) wrote: > On Tue, Feb 24, 2026 at 05:30:37PM -0800, Jakub Kicinski wrote: > > On Mon, 23 Feb 2026 11:24:51 +0000 Russell King (Oracle) wrote: > > > netdev features documentation requires that .ndo_fix_features() is > > > stateless: it shouldn't modify driver state. Yet, stmmac_fix_features() > > > does exactly that, changing whether GSO frames are processed by the > > > driver. > > > > > > Move this code to stmmac_set_features() instead, which is the correct > > > place for it. We don't need to check whether TSO is supported; this > > > is already handled via the setup of netdev->hw_features, and we are > > > guaranteed that if netdev->hw_features indicates that a feature is > > > not supported, .ndo_set_features() won't be called with it set. > > > > No lies detected, but is this enough? The whole TSO enablement > > looks quite wobbly (as you mentioned in another email IIRC). > > > > Only stmmac_hw_setup() actually calls stmmac_enable_tso(). > > And stmmac_set_features() does not call stmmac_hw_setup(). > > Looking deeper, dwmac4_enable_tso() has two paths depending on the "en" > flag, both of which are commented as "enable TSO". > > Then, looking at the "Enable TSO" block of code in stmmac_hw_setup(), > it looks to me like we can end up with some queues that have TSO > enabled, and others which don't (because TBS has been enabled on the > queue.) As far as I'm aware, the network layer doesn't support > per-queue TSO. > > We can't call stmmac_hw_setup() from any path that we care about any > state being preserved - it issues a software reset which causes > everything, including the PTP clock, to be reset and all state then > needs to be reloaded. > > Lastly, we don't need to disable the TSE bit (via stmmac_enable_tso() > when we disable TSO, because there's a bit in the descriptors that > also needs to be set for the packet to undergo TSO. However, if the > system undergoes a suspend/resume with TSO disabled by the user, we'll > call stmmac_hw_setup(), which as I note in the previous paragraph will > reset all state, including the TSE bit. stmmac_enable_tso() won't be > called, and thus the TSE bit will remain clear. If the user > subsequently re-enables TSO, then we'll queue packets for TSO but > the hardware won't have that enabled... > > That's a problem today. So, while you're right to point this out (I > had missed it) it's a separate problem to the one being addressed > in this patch. In fact, I think there's two new issues that have now > been identified here. > > 1. The lack of setting TSE on resume if TSO is supported but but has > been disabled by the user. > 2. The interaction of TBS and TSO feature where some channels can > support TSO and others not, which I don't think can be supported. > So, I think if we have _any_ channel with TBS enabled, we have to > disable TSO on the entire netdev. With the assumption that TBS + TSO is not supported, then the following drivers have a problem: dwmac-intel.c: intel_mgbe_common_data() sets TBS for tx queues other than the first, but also sets STMMAC_FLAG_TSO_EN. dwmac-qcom-ethqos.c: same as dwmac-intel for TBS, but TSO depends on a DT property. dwmac-socfpga.c: always sets STMMAC_FLAG_TSO_EN, but configures queues 6 and 7 for TBS. stmmac_pci.c: snps_gmac5_default_data() sets STMMAC_FLAG_TSO_EN and enables TBS for tx queues other than the first. In each of these cases, we end up with some transmit queues that can support TSO, and others that can't (because TBS is enabled.) What a nice can of worms... The options as I see it are: 1. scan the transmit queue configuration, if any have TBS enabled, disable TSO support for the entire interface. or 2. rip out TSO support, making the code simpler, and thereby removing the need to try and fix the problems here, and making this patch unnecessary. -- RMK's Patch system: https://www.armlinux.org.uk/developer/patches/ FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last! ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH net-next] net: stmmac: fix .ndo_fix_features() 2026-02-25 10:27 ` Russell King (Oracle) @ 2026-02-26 0:27 ` Jakub Kicinski 0 siblings, 0 replies; 7+ messages in thread From: Jakub Kicinski @ 2026-02-26 0:27 UTC (permalink / raw) To: Russell King (Oracle) Cc: Andrew Lunn, Alexandre Torgue, Andrew Lunn, David S. Miller, Eric Dumazet, linux-arm-kernel, linux-stm32, netdev, Paolo Abeni On Wed, 25 Feb 2026 10:27:09 +0000 Russell King (Oracle) wrote: > The options as I see it are: > 1. scan the transmit queue configuration, if any have TBS enabled, > disable TSO support for the entire interface. > > or > > 2. rip out TSO support, making the code simpler, and thereby removing > the need to try and fix the problems here, and making this patch > unnecessary. normally corner cases like this TSO + TBS thing are handled in .ndo_features_check. The driver can selectively clear the TSO feature for a single packet it sees heading down the stack towards its TBS queue. The stack will then run GSO and feed it segments one by one. FWIW Andrew's suggestion to do the GSO in the driver is very much legit, but I agree that its orthogonal if you're trying to simply fix brokenness. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH net-next] net: stmmac: fix .ndo_fix_features() 2026-02-25 8:24 ` Russell King (Oracle) 2026-02-25 10:27 ` Russell King (Oracle) @ 2026-02-25 13:26 ` Andrew Lunn 2026-02-25 14:28 ` Russell King (Oracle) 1 sibling, 1 reply; 7+ messages in thread From: Andrew Lunn @ 2026-02-25 13:26 UTC (permalink / raw) To: Russell King (Oracle) Cc: Jakub Kicinski, Alexandre Torgue, Andrew Lunn, David S. Miller, Eric Dumazet, linux-arm-kernel, linux-stm32, netdev, Paolo Abeni > Then, looking at the "Enable TSO" block of code in stmmac_hw_setup(), > it looks to me like we can end up with some queues that have TSO > enabled, and others which don't (because TBS has been enabled on the > queue.) As far as I'm aware, the network layer doesn't support > per-queue TSO. There is a software implementation of TSO. See for example: commit 3ae8f4e0b98b640aadf410c21185ccb6b5b02351 Author: Ezequiel Garcia <ezequiel.garcia@free-electrons.com> Date: Mon May 19 14:00:00 2014 -0300 net: mv643xx_eth: Implement software TSO You might be able to use this to fill in the gaps. Andrew ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH net-next] net: stmmac: fix .ndo_fix_features() 2026-02-25 13:26 ` Andrew Lunn @ 2026-02-25 14:28 ` Russell King (Oracle) 0 siblings, 0 replies; 7+ messages in thread From: Russell King (Oracle) @ 2026-02-25 14:28 UTC (permalink / raw) To: Andrew Lunn Cc: Jakub Kicinski, Alexandre Torgue, Andrew Lunn, David S. Miller, Eric Dumazet, linux-arm-kernel, linux-stm32, netdev, Paolo Abeni On Wed, Feb 25, 2026 at 02:26:42PM +0100, Andrew Lunn wrote: > > Then, looking at the "Enable TSO" block of code in stmmac_hw_setup(), > > it looks to me like we can end up with some queues that have TSO > > enabled, and others which don't (because TBS has been enabled on the > > queue.) As far as I'm aware, the network layer doesn't support > > per-queue TSO. > > There is a software implementation of TSO. See for example: > > commit 3ae8f4e0b98b640aadf410c21185ccb6b5b02351 > Author: Ezequiel Garcia <ezequiel.garcia@free-electrons.com> > Date: Mon May 19 14:00:00 2014 -0300 > > net: mv643xx_eth: Implement software TSO > > You might be able to use this to fill in the gaps. That'll likely need some major rework to the descriptor handling, which is also buggy, certainly in the non-TSO path. stmmac_xmit() does this: if (unlikely(stmmac_tx_avail(priv, queue) < nfrags + 1)) { if (!netif_tx_queue_stopped(netdev_get_tx_queue(dev, queue))) { netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, queue)); /* This is a hard error, log it. */ netdev_err(priv->dev, "%s: Tx Ring full when queue awake\n", __func__); } return NETDEV_TX_BUSY; } Then it sets the descriptors, which are consumed as per: - 1 descriptor if priv->dma_cap.vlins && skb has a vlan - for non-jumbo: - 1 descriptor for skb head (with sarc & tbs) - for jumbo: - if headlen > 8KiB: - 1 descriptor for first bmax (2 or 8 KiB) of skb head (sets buffer2 of descriptor to data + 4KiB) - 1 descriptor for remainder of skb head (sets buffer2 of descriptor to data + 4KiB) - otherwise: - 1 descriptor for skb head (sets buffer2 of descriptor to data + 4KiB) - 1 descriptor per skb fragment So, the number of descriptors used is 1 + nfrags + overhead, where overhead is: overhead += 1 if jumbo > 8KiB is supported overhead += 1 if priv->dma_cap.vlins To put it another way: - if we have a non-jumbo non-vlan skb, then 1 + nfrags descriptors will be used. - if we have a jumbo vlan skb, then 3 + nfrags descriptors will be used. However, the decision to stop the queue is: if (unlikely(stmmac_tx_avail(priv, queue) <= (MAX_SKB_FRAGS + 1))) { netif_dbg(priv, hw, priv->dev, "%s: stop transmitted packets\n", __func__); netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, queue)); } So it doesn't account for the extra descriptor for vlan insertion, nor does it account for the extra descriptor for a jumbo frame. In the existing TSO path, the same problem exists - its the same check for the last test, although the first test is different: /* Desc availability based on threshold should be enough safe */ if (unlikely(stmmac_tx_avail(priv, queue) < (((skb->len - proto_hdr_len) / TSO_MAX_BUFF_SIZE + 1)))) { This doesn't deal with vlan insertion by the hardware, nor I think jumbo frames (I may be wrong on that) but it does use an extra descriptor each time the MSS (as the driver calls it, actually skb_shinfo(skb)->gso_size) changes on this specific queue. So, it can be one extra descriptor on top of that +1 above. The implications of this is that if the descriptors are almost full, there is the possibility to overwrite the tail descriptor (that the hardware has yet to process) as, when setting up the descriptors, the insertion index is merely incremented, and not individually checked to see whether it's caught up with the tail. I think the only thing which saves the driver from this is that the transmit descriptor ring is large (512 entries by default) and probably never fills up in a way that we hit the boundary condition that allows descriptor overwrite to occur. However, there is this comment: /* TX and RX Descriptor Length, these need to be power of two. * TX descriptor length less than 64 may cause transmit queue timed out error. * RX descriptor length less than 64 may cause inconsistent Rx chain error. */ in drivers/net/ethernet/stmicro/stmmac/common.h, which hints at the problem here: if we do overflow the tail, the hardware may have already processed that descriptor, but we haven't yet reaped it. The driver will be expecting to write to the following descriptor. However, when we real the tail, the driver will clear it. This results in following packets being added after a descriptor with the hardware OWN bit clear, so transmission will stop when the hardware gets to that descriptor, eventually causing a transmit timeout. With this driver, it's really a case of "which of its many problems do we address first" because the more I look at it, the more problems I'm finding. The next problem which can be seen in my analysis of the descriptor usage is - take a close look at the jumbo processing. In some configurations, the length fields are 11 bits. The jumbo code seems to know this because it calculates bmax accordingly. However, the rest of the code just assumes that - even though we can only describe up to 2KiB (actually 4KiB-1) bytes in the length field and it limits the length of the first descriptor to that, it then promptly maps the bytes from 4KiB to the total length to the second buffer in the descriptor. What happens to the 2KiB..4KiB part of the data in this case?!?! I have a huge pile of cleanups to this driver that have helped to uncover these problems by making the code more readable than it currently is - and one of the problems is, I'm generating cleanups and finding problems faster than I can get the changes merged. During the last cycle, I tried to avoid adding to my set of patches for this driver during the -rc phase. That hasn't helped. It also meant that I didn't get any chance to post much else, such as the Marvell PTP changes. I was thinking that, when I get stmmac's phylink mess sorted out, (essentially a few more patches beyond the part 3 RFC I posted today) I'll stop hacking on stmmac, but stmmac just seems to be far too broken. It needs someone to be a proper maintainer, someone who is prepared to say "no" to patches that increase the messy complexity in the driver that I think has led to a lot of these problems... to say no to patches that introduce e.g. TBS without first thinking about its interaction with TSO and whether the upper networking layers can cope with some but not all queues being TSO capable... etc. I do feel that, having got involved with stmmac to try and sort out its bloody abuse of phylink, it's now become a huge mill stone, and I don't have time to look at phylink / sfp related stuff (which is why I've hardly been able to look at Maxime's patches.) Can't we just delete stmmac to put it out of its misery? :D -- RMK's Patch system: https://www.armlinux.org.uk/developer/patches/ FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last! ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-02-26 0:27 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-02-23 11:24 [PATCH net-next] net: stmmac: fix .ndo_fix_features() Russell King (Oracle) 2026-02-25 1:30 ` Jakub Kicinski 2026-02-25 8:24 ` Russell King (Oracle) 2026-02-25 10:27 ` Russell King (Oracle) 2026-02-26 0:27 ` Jakub Kicinski 2026-02-25 13:26 ` Andrew Lunn 2026-02-25 14:28 ` Russell King (Oracle)
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox