From 50ec0a3f976199ea27503cf7559f61c3876952f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20K=C3=B6ppeler?= Date: Fri, 6 Mar 2026 16:32:41 +0000 Subject: [PATCH] kernel: add cake_mq fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds upstreamed cake_mq fixes: - avoiding synchronization overhead when running unlimited - fixing diffServ rates scaling Signed-off-by: Jonas Köppeler Link: https://github.com/openwrt/openwrt/pull/22303 Signed-off-by: Hauke Mehrtens --- ...ke-avoid-sync-overhead-when-unlimite.patch | 32 +++ ...ke-fixup-cake_mq-rate-adjustment-for.patch | 187 ++++++++++++++++++ 2 files changed, 219 insertions(+) create mode 100644 target/linux/generic/backport-6.12/701-01-v7.0-net-sched-sch_cake-avoid-sync-overhead-when-unlimite.patch create mode 100644 target/linux/generic/backport-6.12/701-02-v7.0-net-sched-sch_cake-fixup-cake_mq-rate-adjustment-for.patch diff --git a/target/linux/generic/backport-6.12/701-01-v7.0-net-sched-sch_cake-avoid-sync-overhead-when-unlimite.patch b/target/linux/generic/backport-6.12/701-01-v7.0-net-sched-sch_cake-avoid-sync-overhead-when-unlimite.patch new file mode 100644 index 0000000000..60a003c1de --- /dev/null +++ b/target/linux/generic/backport-6.12/701-01-v7.0-net-sched-sch_cake-avoid-sync-overhead-when-unlimite.patch @@ -0,0 +1,32 @@ +From 0b3cd139be565b85f4a3579e376152b9def6256a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20K=C3=B6ppeler?= +Date: Thu, 26 Feb 2026 12:40:15 +0100 +Subject: [PATCH] net/sched: sch_cake: avoid sync overhead when unlimited +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Skip inter-instance sync when no rate limit is configured, as it serves +no purpose and only adds overhead. + +Fixes: 1bddd758bac2 ("net/sched: sch_cake: share shaper state across sub-instances of cake_mq") +Signed-off-by: Jonas Köppeler +Acked-by: Toke Høiland-Jørgensen +Link: https://patch.msgid.link/20260226-cake-mq-skip-sync-bandwidth-unlimited-v1-1-01830bb4db87@tu-berlin.de +Signed-off-by: Jakub Kicinski +--- + net/sched/sch_cake.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/sched/sch_cake.c ++++ b/net/sched/sch_cake.c +@@ -2012,7 +2012,8 @@ static struct sk_buff *cake_dequeue(stru + u64 delay; + u32 len; + +- if (q->config->is_shared && now - q->last_checked_active >= q->config->sync_time) { ++ if (q->config->is_shared && q->rate_ns && ++ now - q->last_checked_active >= q->config->sync_time) { + struct net_device *dev = qdisc_dev(sch); + struct cake_sched_data *other_priv; + u64 new_rate = q->config->rate_bps; diff --git a/target/linux/generic/backport-6.12/701-02-v7.0-net-sched-sch_cake-fixup-cake_mq-rate-adjustment-for.patch b/target/linux/generic/backport-6.12/701-02-v7.0-net-sched-sch_cake-fixup-cake_mq-rate-adjustment-for.patch new file mode 100644 index 0000000000..357f6b6736 --- /dev/null +++ b/target/linux/generic/backport-6.12/701-02-v7.0-net-sched-sch_cake-fixup-cake_mq-rate-adjustment-for.patch @@ -0,0 +1,187 @@ +From 15c2715a52645fd8e6e18b7abc3449292d118c7c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20K=C3=B6ppeler?= +Date: Thu, 26 Feb 2026 12:40:16 +0100 +Subject: [PATCH] net/sched: sch_cake: fixup cake_mq rate adjustment for + diffserv config +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +cake_mq's rate adjustment during the sync periods did not adjust the +rates for every tin in a diffserv config. This lead to inconsistencies +of rates between the tins. Fix this by setting the rates for all tins +during synchronization. + +Fixes: 1bddd758bac2 ("net/sched: sch_cake: share shaper state across sub-instances of cake_mq") +Signed-off-by: Jonas Köppeler +Acked-by: Toke Høiland-Jørgensen +Link: https://patch.msgid.link/20260226-cake-mq-skip-sync-bandwidth-unlimited-v1-2-01830bb4db87@tu-berlin.de +Signed-off-by: Jakub Kicinski +--- + net/sched/sch_cake.c | 50 ++++++++++++++++++++------------------------ + 1 file changed, 23 insertions(+), 27 deletions(-) + +--- a/net/sched/sch_cake.c ++++ b/net/sched/sch_cake.c +@@ -391,8 +391,8 @@ static const u32 inv_sqrt_cache[REC_INV_ + 1239850263, 1191209601, 1147878294, 1108955788 + }; + +-static void cake_set_rate(struct cake_tin_data *b, u64 rate, u32 mtu, +- u64 target_ns, u64 rtt_est_ns); ++static void cake_configure_rates(struct Qdisc *sch, u64 rate, bool rate_adjust); ++ + /* http://en.wikipedia.org/wiki/Methods_of_computing_square_roots + * new_invsqrt = (invsqrt / 2) * (3 - count * invsqrt^2) + * +@@ -2039,12 +2039,9 @@ static struct sk_buff *cake_dequeue(stru + if (num_active_qs > 1) + new_rate = div64_u64(q->config->rate_bps, num_active_qs); + +- /* mtu = 0 is used to only update the rate and not mess with cobalt params */ +- cake_set_rate(b, new_rate, 0, 0, 0); ++ cake_configure_rates(sch, new_rate, true); + q->last_checked_active = now; + q->active_queues = num_active_qs; +- q->rate_ns = b->tin_rate_ns; +- q->rate_shft = b->tin_rate_shft; + } + + begin: +@@ -2361,12 +2358,10 @@ static void cake_set_rate(struct cake_ti + b->cparams.p_dec = 1 << 20; /* 1/4096 */ + } + +-static int cake_config_besteffort(struct Qdisc *sch) ++static int cake_config_besteffort(struct Qdisc *sch, u64 rate, u32 mtu) + { + struct cake_sched_data *q = qdisc_priv(sch); + struct cake_tin_data *b = &q->tins[0]; +- u32 mtu = psched_mtu(qdisc_dev(sch)); +- u64 rate = q->config->rate_bps; + + q->tin_cnt = 1; + +@@ -2380,12 +2375,10 @@ static int cake_config_besteffort(struct + return 0; + } + +-static int cake_config_precedence(struct Qdisc *sch) ++static int cake_config_precedence(struct Qdisc *sch, u64 rate, u32 mtu) + { + /* convert high-level (user visible) parameters into internal format */ + struct cake_sched_data *q = qdisc_priv(sch); +- u32 mtu = psched_mtu(qdisc_dev(sch)); +- u64 rate = q->config->rate_bps; + u32 quantum = 256; + u32 i; + +@@ -2456,7 +2449,7 @@ static int cake_config_precedence(struct + * Total 12 traffic classes. + */ + +-static int cake_config_diffserv8(struct Qdisc *sch) ++static int cake_config_diffserv8(struct Qdisc *sch, u64 rate, u32 mtu) + { + /* Pruned list of traffic classes for typical applications: + * +@@ -2473,8 +2466,6 @@ static int cake_config_diffserv8(struct + */ + + struct cake_sched_data *q = qdisc_priv(sch); +- u32 mtu = psched_mtu(qdisc_dev(sch)); +- u64 rate = q->config->rate_bps; + u32 quantum = 256; + u32 i; + +@@ -2504,7 +2495,7 @@ static int cake_config_diffserv8(struct + return 0; + } + +-static int cake_config_diffserv4(struct Qdisc *sch) ++static int cake_config_diffserv4(struct Qdisc *sch, u64 rate, u32 mtu) + { + /* Further pruned list of traffic classes for four-class system: + * +@@ -2517,8 +2508,6 @@ static int cake_config_diffserv4(struct + */ + + struct cake_sched_data *q = qdisc_priv(sch); +- u32 mtu = psched_mtu(qdisc_dev(sch)); +- u64 rate = q->config->rate_bps; + u32 quantum = 1024; + + q->tin_cnt = 4; +@@ -2546,7 +2535,7 @@ static int cake_config_diffserv4(struct + return 0; + } + +-static int cake_config_diffserv3(struct Qdisc *sch) ++static int cake_config_diffserv3(struct Qdisc *sch, u64 rate, u32 mtu) + { + /* Simplified Diffserv structure with 3 tins. + * Latency Sensitive (CS7, CS6, EF, VA, TOS4) +@@ -2554,8 +2543,6 @@ static int cake_config_diffserv3(struct + * Low Priority (LE, CS1) + */ + struct cake_sched_data *q = qdisc_priv(sch); +- u32 mtu = psched_mtu(qdisc_dev(sch)); +- u64 rate = q->config->rate_bps; + u32 quantum = 1024; + + q->tin_cnt = 3; +@@ -2580,32 +2567,33 @@ static int cake_config_diffserv3(struct + return 0; + } + +-static void cake_reconfigure(struct Qdisc *sch) ++static void cake_configure_rates(struct Qdisc *sch, u64 rate, bool rate_adjust) + { ++ u32 mtu = likely(rate_adjust) ? 0 : psched_mtu(qdisc_dev(sch)); + struct cake_sched_data *qd = qdisc_priv(sch); + struct cake_sched_config *q = qd->config; + int c, ft; + + switch (q->tin_mode) { + case CAKE_DIFFSERV_BESTEFFORT: +- ft = cake_config_besteffort(sch); ++ ft = cake_config_besteffort(sch, rate, mtu); + break; + + case CAKE_DIFFSERV_PRECEDENCE: +- ft = cake_config_precedence(sch); ++ ft = cake_config_precedence(sch, rate, mtu); + break; + + case CAKE_DIFFSERV_DIFFSERV8: +- ft = cake_config_diffserv8(sch); ++ ft = cake_config_diffserv8(sch, rate, mtu); + break; + + case CAKE_DIFFSERV_DIFFSERV4: +- ft = cake_config_diffserv4(sch); ++ ft = cake_config_diffserv4(sch, rate, mtu); + break; + + case CAKE_DIFFSERV_DIFFSERV3: + default: +- ft = cake_config_diffserv3(sch); ++ ft = cake_config_diffserv3(sch, rate, mtu); + break; + } + +@@ -2616,6 +2604,14 @@ static void cake_reconfigure(struct Qdis + + qd->rate_ns = qd->tins[ft].tin_rate_ns; + qd->rate_shft = qd->tins[ft].tin_rate_shft; ++} ++ ++static void cake_reconfigure(struct Qdisc *sch) ++{ ++ struct cake_sched_data *qd = qdisc_priv(sch); ++ struct cake_sched_config *q = qd->config; ++ ++ cake_configure_rates(sch, qd->config->rate_bps, false); + + if (q->buffer_config_limit) { + qd->buffer_limit = q->buffer_config_limit;