From: Josef Schlehofer <pepe.schlehofer@gmail.com>
To: netdev@vger.kernel.org
Cc: marcin.s.wojtas@gmail.com, andrew+netdev@lunn.ch,
davem@davemloft.net, edumazet@kernel.org, kuba@kernel.org,
pabeni@redhat.com, maxime.chevallier@bootlin.com, w@1wt.eu,
linux-kernel@vger.kernel.org
Subject: [PATCH net v3 5/5] net: mvneta: serve the TX queues in weighted round robin
Date: Wed, 4 Nov 2026 23:45:18 +0100 [thread overview]
Message-ID: <20261104224518.66487-6-pepe.schlehofer@gmail.com> (raw)
In-Reply-To: <20261104224518.66487-1-pepe.schlehofer@gmail.com>
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.
Use the smallest weight that is larger than the largest packet.
Keep the fixed priority while an mqprio offload is set up, as its
traffic classes may rely on it. Clear it when the offload is removed or
its setup fails. Starting the port sets the mode again. The fixed
priority is set per queue, so the queues of one traffic class still
starve each other.
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. With an
mqprio offload, a higher queue still has priority over a lower one.
Fixes: ee40a116ebf1 ("net: mvneta: fix improper tx queue usage in mvneta_tx()")
Suggested-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Signed-off-by: Josef Schlehofer <pepe.schlehofer@gmail.com>
---
drivers/net/ethernet/marvell/mvneta.c | 41 ++++++++++++++++++++++++++-
1 file changed, 40 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 2f8c134a921e..6fff17a3e4de 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -253,6 +253,8 @@
#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_TXQ_FIXED_PRIO_ALL 0xff
#define MVNETA_REFILL_NUM_CLK_REG 0x3e08
#define MVNETA_REFILL_MAX_NUM_CLK 0x0000ffff
#define MVNETA_TX_MTU 0x3e0c
@@ -264,6 +266,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
@@ -518,6 +522,8 @@ struct mvneta_port {
*/
spinlock_t lock;
bool is_stopped;
+ /* An mqprio offload keeps the TX queues in fixed priority */
+ bool txq_fixed_prio;
u32 cause_rx_tx;
struct napi_struct napi;
@@ -1632,6 +1638,29 @@ 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);
+ }
+}
+
+/* Only the traffic classes of an mqprio offload keep the fixed priority */
+static void mvneta_txq_fixed_prio_set(struct mvneta_port *pp)
+{
+ mvreg_write(pp, MVNETA_TXQ_FIXED_PRIO_REG,
+ pp->txq_fixed_prio ? MVNETA_TXQ_FIXED_PRIO_ALL : 0);
+}
+
/* Set unicast address */
static void mvneta_set_ucast_addr(struct mvneta_port *pp, u8 last_nibble,
int queue)
@@ -3765,6 +3794,8 @@ 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);
+ mvneta_txq_fixed_prio_set(pp);
mvneta_restore_per_queue_rate_limit(pp);
/* start the Rx/Tx activity */
@@ -5358,9 +5389,17 @@ err:
static int mvneta_setup_tc(struct net_device *dev, enum tc_setup_type type,
void *type_data)
{
+ struct mvneta_port *pp = netdev_priv(dev);
+ struct tc_mqprio_qopt_offload *mqprio;
+ int ret;
+
switch (type) {
case TC_SETUP_QDISC_MQPRIO:
- return mvneta_setup_mqprio(dev, type_data);
+ mqprio = type_data;
+ ret = mvneta_setup_mqprio(dev, mqprio);
+ pp->txq_fixed_prio = !ret && mqprio->qopt.num_tc;
+ mvneta_txq_fixed_prio_set(pp);
+ return ret;
default:
return -EOPNOTSUPP;
}
--
2.54.0 (Apple Git-157)
prev parent reply other threads:[~2026-11-04 22:45 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-04 22:45 [PATCH net v3 0/5] net: mvneta: fix the TX queue arbitration and the mqprio offload Josef Schlehofer
2026-11-04 22:45 ` [PATCH net v3 1/5] net: mvneta: lift the per-queue TX rate limits Josef Schlehofer
2026-11-04 22:45 ` [PATCH net v3 2/5] net: mvneta: fix the removal of the mqprio offload Josef Schlehofer
2026-11-04 22:45 ` [PATCH net v3 3/5] net: mvneta: unwind a failed mqprio setup Josef Schlehofer
2026-11-04 22:45 ` [PATCH net v3 4/5] net: mvneta: keep the TX rate limits across open and MTU change Josef Schlehofer
2026-11-04 22:45 ` Josef Schlehofer [this message]
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=20261104224518.66487-6-pepe.schlehofer@gmail.com \
--to=pepe.schlehofer@gmail.com \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=marcin.s.wojtas@gmail.com \
--cc=maxime.chevallier@bootlin.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=w@1wt.eu \
/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
all inboxes | Powered by JetHome®