tc_setup_dwmac510_mqprio() computes the number of real TX queues as the sum of the per-TC queue counts. mqprio_validate_queue_counts() only rejects out-of-bounds or overlapping ranges, so layouts with gaps or a non-zero first offset are accepted, and in those cases the sum is smaller than the highest queue referenced by the netdev TC map. netif_set_real_num_tx_queues() then passes this too-small count to netif_setup_tc(). However stmmac_set_ndev_tcs() has already zeroed dev->prio_tc_map() through netdev_reset_tc(), so when netif_setup_tc() runs every priority maps to TC0 and only the TC0 range is checked. A layout whose TC0 range fits but where a later TC references a queue beyond the new real_num_tx_queues is left with num_tc set and its TC map pointing at queues that are no longer real, without any warning; only when TC0 itself is out of range is the mapping disabled. The real prio_tc_map is programmed later by the qdisc, after this call, so the driver cannot rely on netif_setup_tc() to catch those cases. Compute num_tx_queues as the maximum of offset[i] + count[i] instead of the sum of the counts, so real_num_tx_queues always covers the highest queue referenced by the TC map. This is a no-op for the contiguous channel-mode layouts where offset[i] == i and count[i] == 1. The issue has been reported by sashiko and the patch has been tested on Qualcomm RB3-Gen2 board. Fixes: 195e4f409a40 ("net: stmmac: support fp parameter of tc-mqprio") Signed-off-by: Lorenzo Bianconi --- drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c index 42a00446e9b4..1aa80d51ab33 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c @@ -1303,7 +1303,8 @@ static int tc_setup_dwmac510_mqprio(struct stmmac_priv *priv, .count = qopt->count[i], .offset = qopt->offset[i], }; - num_tx_queues += qopt->count[i]; + num_tx_queues = max(num_tx_queues, + qopt->offset[i] + qopt->count[i]); } err = stmmac_set_ndev_tcs(ndev, qopt->num_tc, tc_to_txq); -- 2.55.0