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. A replacement qdisc is set up before the old one is torn down. Replacing an offloaded mqprio qdisc under a new handle with another qdisc that sets traffic classes therefore loses them, as with software mqprio. A taprio qdisc left without traffic classes sends nothing. 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 Reviewed-by: Maxime Chevallier --- 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)