* [PATCH net 0/3] net: mvneta: fix the TX queue arbitration and the mqprio teardown
@ 2026-11-02 11:28 Josef Schlehofer
2026-11-02 11:28 ` [PATCH net 1/3] net: mvneta: lift the per-queue TX rate limits Josef Schlehofer
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Josef Schlehofer @ 2026-11-02 11:28 UTC (permalink / raw)
To: netdev
Cc: marcin.s.wojtas, andrew+netdev, davem, edumazet, kuba, pabeni,
maxime.chevallier, w, linux-kernel
The NETA TX arbiter is left at its reset default, which serves the TX
queues in fixed priority. Under load a busy queue starves the others.
OpenWrt has worked around this since 2017 by sending all TX traffic
of its 32-bit boards through queue 0 [1].
Patch 3 serves the queues in weighted round robin. While testing it
with the mqprio offload, two older bugs showed up. Deleting the qdisc
never reaches the driver, and turning the shaper off leaves the
per-queue rate limits in place. Patches 1 and 2 fix them.
The series was tested on a Turris Omnia (Armada 385). The other NETA
variants were not tested, but the driver already programs registers of
the same block (MVNETA_TX_MTU and the token sizes) on all of them.
Replacing an offloaded mqprio qdisc under a new handle still loses the
new configuration, because the old qdisc is torn down after the new
one is set up. Software mqprio behaves the same way, so this series
leaves it alone.
[1] https://github.com/openwrt/openwrt/blob/a5e96c837ead549820867bb83c1ad471e39f5ace/target/linux/mvebu/patches-6.18/700-mvneta-tx-queue-workaround.patch
Josef Schlehofer (3):
net: mvneta: lift the per-queue TX rate limits
net: mvneta: fix the removal of the mqprio offload
net: mvneta: serve the TX queues in weighted round robin
drivers/net/ethernet/marvell/mvneta.c | 36 ++++++++++++++++++++++++---
1 file changed, 33 insertions(+), 3 deletions(-)
base-commit: cb284914e749388eef402938bdb3115fe1f6d337
--
2.54.0 (Apple Git-157)
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH net 1/3] net: mvneta: lift the per-queue TX rate limits
2026-11-02 11:28 [PATCH net 0/3] net: mvneta: fix the TX queue arbitration and the mqprio teardown Josef Schlehofer
@ 2026-11-02 11:28 ` Josef Schlehofer
2026-11-02 11:28 ` [PATCH net 2/3] net: mvneta: fix the removal of the mqprio offload Josef Schlehofer
2026-11-02 11:28 ` [PATCH net 3/3] net: mvneta: serve the TX queues in weighted round robin Josef Schlehofer
2 siblings, 0 replies; 4+ messages in thread
From: Josef Schlehofer @ 2026-11-02 11:28 UTC (permalink / raw)
To: netdev
Cc: marcin.s.wojtas, andrew+netdev, davem, edumazet, kuba, pabeni,
maxime.chevallier, w, linux-kernel
The per-queue rate limits set by mqprio stay in effect after the
shaper is turned off.
mvneta_disable_per_queue_rate_limit() only changes the mode bits in
MVNETA_TXQ_CMD1_REG. The token buckets keep limiting the TX queues
with that mode as well, and their refill rate still holds the old
limit.
Refill the token buckets of all TX queues at full rate when the rate
limit is disabled.
Tested on a Turris Omnia (Armada 385) with 10 Mbit/s limits on a
100 Mbit/s link. When mqprio was set up again without a shaper, each
TX queue stayed at 10 Mbit/s. With this patch the link reaches
94 Mbit/s.
Fixes: 2551dc9e398c ("net: mvneta: Add TC traffic shaping offload")
Signed-off-by: Josef Schlehofer <pepe.schlehofer@gmail.com>
---
drivers/net/ethernet/marvell/mvneta.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index ea755cf05b9e..9b9efac2846e 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -5204,9 +5204,16 @@ static int mvneta_enable_per_queue_rate_limit(struct mvneta_port *pp)
static void mvneta_disable_per_queue_rate_limit(struct mvneta_port *pp)
{
u32 val = mvreg_read(pp, MVNETA_TXQ_CMD1_REG);
+ int queue;
val |= (MVNETA_TXQ_CMD1_BW_LIM_SEL_V1 | MVNETA_TXQ_CMD1_BW_LIM_EN);
mvreg_write(pp, MVNETA_TXQ_CMD1_REG, val);
+
+ /* The token buckets still limit the queues, refill them at full rate */
+ val = (1 << MVNETA_TXQ_BUCKET_REFILL_PERIOD_SHIFT) |
+ MVNETA_TXQ_BUCKET_REFILL_VALUE_MAX;
+ for (queue = 0; queue < txq_number; queue++)
+ mvreg_write(pp, MVNETA_TXQ_BUCKET_REFILL_REG(queue), val);
}
static int mvneta_setup_queue_rates(struct mvneta_port *pp, int queue,
--
2.54.0 (Apple Git-157)
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH net 2/3] net: mvneta: fix the removal of the mqprio offload
2026-11-02 11:28 [PATCH net 0/3] net: mvneta: fix the TX queue arbitration and the mqprio teardown Josef Schlehofer
2026-11-02 11:28 ` [PATCH net 1/3] net: mvneta: lift the per-queue TX rate limits Josef Schlehofer
@ 2026-11-02 11:28 ` Josef Schlehofer
2026-11-02 11:28 ` [PATCH net 3/3] net: mvneta: serve the TX queues in weighted round robin Josef Schlehofer
2 siblings, 0 replies; 4+ messages in thread
From: Josef Schlehofer @ 2026-11-02 11:28 UTC (permalink / raw)
To: netdev
Cc: marcin.s.wojtas, andrew+netdev, davem, edumazet, kuba, pabeni,
maxime.chevallier, w, linux-kernel
Deleting an offloaded mqprio qdisc leaves its traffic classes and
per-queue rate limits in place.
mqprio_disable_offload() passes an all-zero configuration, so qopt.hw
is 0 and mvneta_setup_mqprio() returns before it reaches the teardown
code.
Check qopt.hw only when traffic classes are set up.
Tested on a Turris Omnia (Armada 385) with 10 Mbit/s limits on a
100 Mbit/s link. After the qdisc was deleted, only TX queues 0-3 were
used and the link carried 19 Mbit/s. With this patch and the previous
one, the queues above 3 are used again and the link reaches 94 Mbit/s.
Fixes: e7ca75fe6662 ("net: mvneta: Don't force-set the offloading flag")
Signed-off-by: Josef Schlehofer <pepe.schlehofer@gmail.com>
---
drivers/net/ethernet/marvell/mvneta.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 9b9efac2846e..79711a117c39 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -5251,11 +5251,12 @@ static int mvneta_setup_mqprio(struct net_device *dev,
int rxq, txq, tc, ret;
u8 num_tc;
- if (mqprio->qopt.hw != TC_MQPRIO_HW_OFFLOAD_TCS)
- return 0;
-
num_tc = mqprio->qopt.num_tc;
+ /* On removal the qdisc passes an all-zero qopt, with hw 0 */
+ if (num_tc && mqprio->qopt.hw != TC_MQPRIO_HW_OFFLOAD_TCS)
+ return 0;
+
if (num_tc > rxq_number)
return -EINVAL;
--
2.54.0 (Apple Git-157)
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH net 3/3] net: mvneta: serve the TX queues in weighted round robin
2026-11-02 11:28 [PATCH net 0/3] net: mvneta: fix the TX queue arbitration and the mqprio teardown Josef Schlehofer
2026-11-02 11:28 ` [PATCH net 1/3] net: mvneta: lift the per-queue TX rate limits Josef Schlehofer
2026-11-02 11:28 ` [PATCH net 2/3] net: mvneta: fix the removal of the mqprio offload Josef Schlehofer
@ 2026-11-02 11:28 ` Josef Schlehofer
2 siblings, 0 replies; 4+ messages in thread
From: Josef Schlehofer @ 2026-11-02 11:28 UTC (permalink / raw)
To: netdev
Cc: marcin.s.wojtas, andrew+netdev, davem, edumazet, kuba, pabeni,
maxime.chevallier, w, linux-kernel
Under load, some TX queues get no service at all. With four TCP streams
on a 100 Mbit/s link, up to three streams sent nothing for 20 seconds.
The TX queue arbiter is left at its reset default, which serves all
queues in fixed priority. The stack spreads the flows over the queues,
so a busy queue starves the others.
Give the TX queues the same WRR weight and clear the fixed priority.
Like the Marvell reference driver, use the smallest weight that is
larger than the largest packet.
The mqprio offload never configured the TX scheduling, so its traffic
classes lose the fixed priority of the reset default as well.
Tested on a Turris Omnia (Armada 385). With this patch each busy TX
queue gets an equal share of the link and no stream stalls.
Fixes: ee40a116ebf1 ("net: mvneta: fix improper tx queue usage in mvneta_tx()")
Signed-off-by: Josef Schlehofer <pepe.schlehofer@gmail.com>
---
drivers/net/ethernet/marvell/mvneta.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 79711a117c39..75d46349df37 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -253,6 +253,7 @@
#define MVNETA_TXQ_CMD1_REG 0x3e00
#define MVNETA_TXQ_CMD1_BW_LIM_SEL_V1 BIT(3)
#define MVNETA_TXQ_CMD1_BW_LIM_EN BIT(0)
+#define MVNETA_TXQ_FIXED_PRIO_REG 0x3e04
#define MVNETA_REFILL_NUM_CLK_REG 0x3e08
#define MVNETA_REFILL_MAX_NUM_CLK 0x0000ffff
#define MVNETA_TX_MTU 0x3e0c
@@ -264,6 +265,8 @@
#define MVNETA_TXQ_BUCKET_REFILL_VALUE_MAX 0x0007ffff
#define MVNETA_TXQ_TOKEN_SIZE_REG(q) (0x3e40 + ((q) << 2))
#define MVNETA_TXQ_TOKEN_SIZE_MAX 0x7fffffff
+#define MVNETA_TXQ_WRR_ARB_REG(q) (0x3e80 + ((q) << 2))
+#define MVNETA_TXQ_WRR_WEIGHT_MASK 0xff
/* The values of the bucket refill base period and refill period are taken from
* the reference manual, and adds up to a base resolution of 10Kbps. This allows
@@ -1629,6 +1632,24 @@ static void mvneta_txq_max_tx_size_set(struct mvneta_port *pp, int max_tx_size)
}
}
+/* With the default fixed priority, a busy queue starves the others */
+static void mvneta_txq_wrr_set(struct mvneta_port *pp, int max_tx_size)
+{
+ /* In units of 256 bytes, must exceed the largest packet */
+ u32 weight = max_tx_size / 256 + 1;
+ int queue;
+ u32 val;
+
+ for (queue = 0; queue < txq_number; queue++) {
+ val = mvreg_read(pp, MVNETA_TXQ_WRR_ARB_REG(queue));
+ val &= ~MVNETA_TXQ_WRR_WEIGHT_MASK;
+ val |= weight;
+ mvreg_write(pp, MVNETA_TXQ_WRR_ARB_REG(queue), val);
+ }
+
+ mvreg_write(pp, MVNETA_TXQ_FIXED_PRIO_REG, 0);
+}
+
/* Set unicast address */
static void mvneta_set_ucast_addr(struct mvneta_port *pp, u8 last_nibble,
int queue)
@@ -3760,6 +3781,7 @@ static void mvneta_start_dev(struct mvneta_port *pp)
mvneta_max_rx_size_set(pp, pp->pkt_size);
mvneta_txq_max_tx_size_set(pp, pp->pkt_size);
+ mvneta_txq_wrr_set(pp, pp->pkt_size);
/* start the Rx/Tx activity */
mvneta_port_enable(pp);
--
2.54.0 (Apple Git-157)
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-11-02 11:28 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-02 11:28 [PATCH net 0/3] net: mvneta: fix the TX queue arbitration and the mqprio teardown Josef Schlehofer
2026-11-02 11:28 ` [PATCH net 1/3] net: mvneta: lift the per-queue TX rate limits Josef Schlehofer
2026-11-02 11:28 ` [PATCH net 2/3] net: mvneta: fix the removal of the mqprio offload Josef Schlehofer
2026-11-02 11:28 ` [PATCH net 3/3] net: mvneta: serve the TX queues in weighted round robin Josef Schlehofer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®