]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
kernel: add cake_mq fixes 22303/head
authorJonas Köppeler <j.koeppeler@tu-berlin.de>
Fri, 6 Mar 2026 16:32:41 +0000 (16:32 +0000)
committerHauke Mehrtens <hauke@hauke-m.de>
Sun, 8 Mar 2026 18:43:33 +0000 (19:43 +0100)
This adds upstreamed cake_mq fixes:
- avoiding synchronization overhead when running unlimited
- fixing diffServ rates scaling

Signed-off-by: Jonas Köppeler <j.koeppeler@tu-berlin.de>
Link: https://github.com/openwrt/openwrt/pull/22303
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
target/linux/generic/backport-6.12/701-01-v7.0-net-sched-sch_cake-avoid-sync-overhead-when-unlimite.patch [new file with mode: 0644]
target/linux/generic/backport-6.12/701-02-v7.0-net-sched-sch_cake-fixup-cake_mq-rate-adjustment-for.patch [new file with mode: 0644]

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 (file)
index 0000000..60a003c
--- /dev/null
@@ -0,0 +1,32 @@
+From 0b3cd139be565b85f4a3579e376152b9def6256a Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jonas=20K=C3=B6ppeler?= <j.koeppeler@tu-berlin.de>
+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 <j.koeppeler@tu-berlin.de>
+Acked-by: Toke Høiland-Jørgensen <toke@toke.dk>
+Link: https://patch.msgid.link/20260226-cake-mq-skip-sync-bandwidth-unlimited-v1-1-01830bb4db87@tu-berlin.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ 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 (file)
index 0000000..357f6b6
--- /dev/null
@@ -0,0 +1,187 @@
+From 15c2715a52645fd8e6e18b7abc3449292d118c7c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jonas=20K=C3=B6ppeler?= <j.koeppeler@tu-berlin.de>
+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 <j.koeppeler@tu-berlin.de>
+Acked-by: Toke Høiland-Jørgensen <toke@toke.dk>
+Link: https://patch.msgid.link/20260226-cake-mq-skip-sync-bandwidth-unlimited-v1-2-01830bb4db87@tu-berlin.de
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ 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;