From: Maxime Chevallier <maxime.chevallier@bootlin.com>
To: Ovidiu Panait <ovidiu.panait.rb@renesas.com>,
andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@kernel.org,
kuba@kernel.org, pabeni@redhat.com, mcoquelin.stm32@gmail.com,
alexandre.torgue@foss.st.com, xiaoliang.yang_1@nxp.com
Cc: netdev@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH net 1/2] net: stmmac: Track the TX DMA threshold per queue
Date: Tue, 13 Oct 2026 14:45:43 +0200 [thread overview]
Message-ID: <73ae9104-a79f-4369-a3da-245db11be834@bootlin.com> (raw)
In-Reply-To: <20261013114503.57487-2-ovidiu.panait.rb@renesas.com>
Hi,
On 10/13/26 13:45, Ovidiu Panait wrote:
> Commit 3a6c12a0c6c3 ("net: stmmac: bump tc when get underflow error from
> DMA descriptor") made dwmac4 raise the DMA threshold of the queues that
> report TX underflows. This is done by incrementing a module global
> parameter 'tc' by 64 on each underflow.
>
> This leads to inconsistent TX DMA thresholds between queues and causes
> issues on platforms with multiple stmmac controllers, as 'tc' is shared
> by all of them. Once 'tc' goes over 256 the bumping stops, and queues
> that did not underflow before are left at the initial threshold.
>
> On the Renesas RZ/V2H platform, which has two dwmac4 controllers, we
> observed sporadic iperf3 TCP TX failures:
>
> iperf3 -c <server> -t5 --bind-dev end1
> ...
> [ 5] 0.00-5.00 sec 1.00 MBytes 1.68 Mbits/sec 87 sender
> [ 5] 0.00-5.00 sec 768 KBytes 1.26 Mbits/sec receiver
>
> This happens because the TX queues of end1 were underflowing on a large
> fraction of the packets, but the DMA TX threshold was never raised from
> the default of 64 bytes. The threshold was not raised because end0
> had underflowed first and had already pushed 'tc' past 256. Which
> controller is affected depends on which one underflows first.
>
> To fix this, make the TX DMA threshold per queue instead of global.
> Each time an underflow happens on a queue, its TX DMA threshold gets
> incremented, without affecting other queues or controllers. With this
> change, 'tc' is only used as the initial value, and the RX threshold
> is no longer bumped together with the TX one, as TX underflows have
> nothing to do with the RX side.
>
> Fixes: 3a6c12a0c6c3 ("net: stmmac: bump tc when get underflow error from DMA descriptor")
> Signed-off-by: Ovidiu Panait <ovidiu.panait.rb@renesas.com>
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Maxime
> ---
> drivers/net/ethernet/stmicro/stmmac/stmmac.h | 1 +
> .../net/ethernet/stmicro/stmmac/stmmac_main.c | 33 +++++++++++--------
> 2 files changed, 21 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> index 9278378407e8..85d63450693e 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> @@ -270,6 +270,7 @@ struct stmmac_priv {
> bool sph_capable;
> u32 sarc_type;
> u32 rx_riwt[MTL_MAX_RX_QUEUES];
> + u32 tx_threshold[MTL_MAX_TX_QUEUES];
> int hwts_rx_en;
> bool tsfupdt_coarse;
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index b8b4de4c5b1a..b5ee0f297df6 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -2622,7 +2622,6 @@ static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
> }
>
> if (priv->plat->force_thresh_dma_mode) {
> - txmode = tc;
> rxmode = tc;
> } else if (priv->plat->force_sf_dma_mode || priv->plat->tx_coe) {
> /*
> @@ -2636,7 +2635,6 @@ static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
> rxmode = SF_DMA_MODE;
> priv->xstats.threshold = SF_DMA_MODE;
> } else {
> - txmode = tc;
> rxmode = SF_DMA_MODE;
> }
>
> @@ -2655,8 +2653,11 @@ static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
> for (chan = 0; chan < tx_channels_count; chan++) {
> qmode = priv->plat->tx_queues_cfg[chan].mode_to_use;
>
> - stmmac_dma_tx_mode(priv, priv->ioaddr, txmode, chan,
> - txfifosz, qmode);
> + if (txmode == SF_DMA_MODE)
> + priv->tx_threshold[chan] = SF_DMA_MODE;
> +
> + stmmac_dma_tx_mode(priv, priv->ioaddr, priv->tx_threshold[chan],
> + chan, txfifosz, qmode);
> }
> }
>
> @@ -2822,17 +2823,20 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
>
> static void stmmac_bump_dma_threshold(struct stmmac_priv *priv, u32 chan)
> {
> - if (unlikely(priv->xstats.threshold != SF_DMA_MODE) && tc <= 256) {
> - tc += 64;
> + u32 thresh = priv->tx_threshold[chan];
>
> - if (priv->plat->force_thresh_dma_mode)
> - stmmac_set_dma_operation_mode(priv, tc, tc, chan);
> - else
> - stmmac_set_dma_operation_mode(priv, tc, SF_DMA_MODE,
> - chan);
> + if (unlikely(thresh == SF_DMA_MODE) || thresh > 256)
> + return;
>
> - priv->xstats.threshold = tc;
> - }
> + thresh += 64;
> +
> + if (priv->plat->force_thresh_dma_mode)
> + stmmac_set_dma_operation_mode(priv, thresh, tc, chan);
> + else
> + stmmac_set_dma_operation_mode(priv, thresh, SF_DMA_MODE, chan);
> +
> + priv->tx_threshold[chan] = thresh;
> + priv->xstats.threshold = thresh;
> }
>
> /**
> @@ -8133,6 +8137,9 @@ static int __stmmac_dvr_probe(struct device *device,
>
> priv->xstats.threshold = tc;
>
> + for (i = 0; i < MTL_MAX_TX_QUEUES; i++)
> + priv->tx_threshold[i] = tc;
> +
> /* Initialize RSS */
> rxq = priv->plat->rx_queues_to_use;
> netdev_rss_key_fill(priv->rss.key, sizeof(priv->rss.key));
next prev parent reply other threads:[~2026-10-13 12:45 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-13 11:45 [PATCH net 0/2] net: stmmac: Track and report the TX DMA threshold per queue Ovidiu Panait
2026-10-13 11:45 ` [PATCH net 1/2] net: stmmac: Track " Ovidiu Panait
2026-10-13 12:45 ` Maxime Chevallier [this message]
2026-10-13 11:45 ` [PATCH net 2/2] net: stmmac: Report " Ovidiu Panait
2026-10-13 12:44 ` [PATCH net 0/2] net: stmmac: Track and report " Maxime Chevallier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=73ae9104-a79f-4369-a3da-245db11be834@bootlin.com \
--to=maxime.chevallier@bootlin.com \
--cc=alexandre.torgue@foss.st.com \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-stm32@st-md-mailman.stormreply.com \
--cc=mcoquelin.stm32@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=ovidiu.panait.rb@renesas.com \
--cc=pabeni@redhat.com \
--cc=xiaoliang.yang_1@nxp.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox