mirror of
https://github.com/openwrt/openwrt.git
synced 2026-06-17 12:40:16 +04:00
9cf794cff1
Changelog: https://cdn.kernel.org/pub/linux/kernel/v6.x/ChangeLog-6.12.91
Remove upstreamed patches:
- airoha/patches-6.12/017-v6.13-net-airoha-Implement-BQL-support.patch[1]
- airoha/patches-6.12/138-v7.1-net-airoha-Add-missing-RX_CPU_IDX-configuration-in-a.patch[2]
- airoha/patches-6.12/149-v7.1-net-airoha-Move-ndesc-initialization-at-end-of-airoh.patch[3]
- generic/backport-6.12/940-v7.1-net-dsa-realtek-rtl8365mb-fix-mode-mask-calculation.patch[5]
Manually rebased patches:
- airoha/patches-6.12/048-01-v6.15-net-airoha-Move-airoha_eth-driver-in-a-dedicated-fol.patch[1]
- ath79/patches-6.12/800-leds-add-reset-controller-based-driver.patch[4]
- bcm27xx/patches-6.12/950-0122-bcmgenet-Better-coalescing-parameter-defaults.patch[6]
We also backported four patches to fix perf tool regression:
- generic/backport-6.12/216-01-revert-perf-cgroup-update-metric-leader-in-evlist__e.patch
- generic/backport-6.12/216-02-revert-perf-tool_pmu-fix-aggregation-on-duration_tim.patch
- generic/backport-6.12/216-03-revert-perf-python-add-parse_events-function.patch
- generic/backport-6.12/216-04-revert-perf-tool_pmu-factor-tool-events-into-their-o.patch
All other patches are automatically refreshed.
[1] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v6.12.91&id=ca24fcac1daaa5e8a667981d81986a3eb4b9fb04
[2] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v6.12.91&id=f00037a99bc2332ef59dc85298b98b20af165904
[3] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v6.12.91&id=d36be272adda7f313e39dd118086955d993bf6a7
[4] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v6.12.91&id=07d3611389ba7d78b80ea360a42ce32ab2521fbc
[5] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v6.12.91&id=3354d6c62fd4baa7b32cbd80cc5a8aa3f2bd0656
[6] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v6.12.91&id=b84351dcc359667bc952131c1424b692ec83dce2
Signed-off-by: Shiji Yang <yangshiji66@outlook.com>
Link: https://github.com/openwrt/openwrt/pull/23444
(cherry picked from commit 8f638f9366)
Link: https://github.com/openwrt/openwrt/pull/23538
[Adapted to patches in 25.12]
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
176 lines
5.5 KiB
Diff
176 lines
5.5 KiB
Diff
From 090dde0780266eb80126fa970870bafdb4e937c3 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Jonas=20K=C3=B6ppeler?= <j.koeppeler@tu-berlin.de>
|
|
Date: Fri, 9 Jan 2026 14:15:34 +0100
|
|
Subject: [PATCH 5/7] net/sched: sch_cake: share shaper state across
|
|
sub-instances of cake_mq
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
This commit adds shared shaper state across the cake instances beneath a
|
|
cake_mq qdisc. It works by periodically tracking the number of active
|
|
instances, and scaling the configured rate by the number of active
|
|
queues.
|
|
|
|
The scan is lockless and simply reads the qlen and the last_active state
|
|
variable of each of the instances configured beneath the parent cake_mq
|
|
instance. Locking is not required since the values are only updated by
|
|
the owning instance, and eventual consistency is sufficient for the
|
|
purpose of estimating the number of active queues.
|
|
|
|
The interval for scanning the number of active queues is set to 200 us.
|
|
We found this to be a good tradeoff between overhead and response time.
|
|
For a detailed analysis of this aspect see the Netdevconf talk:
|
|
|
|
https://netdevconf.info/0x19/docs/netdev-0x19-paper16-talk-paper.pdf
|
|
|
|
Reviewed-by: Jamal Hadi Salim <jhs@mojatatu.com>
|
|
Signed-off-by: Jonas Köppeler <j.koeppeler@tu-berlin.de>
|
|
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
|
|
Link: https://patch.msgid.link/20260109-mq-cake-sub-qdisc-v8-5-8d613fece5d8@redhat.com
|
|
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|
---
|
|
Documentation/netlink/specs/tc.yaml | 3 ++
|
|
include/uapi/linux/pkt_sched.h | 1 +
|
|
net/sched/sch_cake.c | 51 +++++++++++++++++++++++++++++
|
|
3 files changed, 55 insertions(+)
|
|
|
|
--- a/Documentation/netlink/specs/tc.yaml
|
|
+++ b/Documentation/netlink/specs/tc.yaml
|
|
@@ -2161,6 +2161,9 @@ attribute-sets:
|
|
-
|
|
name: blue-timer-us
|
|
type: s32
|
|
+ -
|
|
+ name: active-queues
|
|
+ type: u32
|
|
-
|
|
name: tc-cake-tin-stats-attrs
|
|
attributes:
|
|
--- a/include/uapi/linux/pkt_sched.h
|
|
+++ b/include/uapi/linux/pkt_sched.h
|
|
@@ -1034,6 +1034,7 @@ enum {
|
|
TCA_CAKE_STATS_DROP_NEXT_US,
|
|
TCA_CAKE_STATS_P_DROP,
|
|
TCA_CAKE_STATS_BLUE_TIMER_US,
|
|
+ TCA_CAKE_STATS_ACTIVE_QUEUES,
|
|
__TCA_CAKE_STATS_MAX
|
|
};
|
|
#define TCA_CAKE_STATS_MAX (__TCA_CAKE_STATS_MAX - 1)
|
|
--- a/net/sched/sch_cake.c
|
|
+++ b/net/sched/sch_cake.c
|
|
@@ -202,6 +202,7 @@ struct cake_sched_config {
|
|
u64 rate_bps;
|
|
u64 interval;
|
|
u64 target;
|
|
+ u64 sync_time;
|
|
u32 buffer_config_limit;
|
|
u32 fwmark_mask;
|
|
u16 fwmark_shft;
|
|
@@ -258,6 +259,11 @@ struct cake_sched_data {
|
|
u16 max_adjlen;
|
|
u16 min_netlen;
|
|
u16 min_adjlen;
|
|
+
|
|
+ /* mq sync state */
|
|
+ u64 last_checked_active;
|
|
+ u64 last_active;
|
|
+ u32 active_queues;
|
|
};
|
|
|
|
enum {
|
|
@@ -384,6 +390,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);
|
|
/* http://en.wikipedia.org/wiki/Methods_of_computing_square_roots
|
|
* new_invsqrt = (invsqrt / 2) * (3 - count * invsqrt^2)
|
|
*
|
|
@@ -2003,6 +2011,40 @@ 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) {
|
|
+ struct net_device *dev = qdisc_dev(sch);
|
|
+ struct cake_sched_data *other_priv;
|
|
+ u64 new_rate = q->config->rate_bps;
|
|
+ u64 other_qlen, other_last_active;
|
|
+ struct Qdisc *other_sch;
|
|
+ u32 num_active_qs = 1;
|
|
+ unsigned int ntx;
|
|
+
|
|
+ for (ntx = 0; ntx < dev->num_tx_queues; ntx++) {
|
|
+ other_sch = rcu_dereference(netdev_get_tx_queue(dev, ntx)->qdisc_sleeping);
|
|
+ other_priv = qdisc_priv(other_sch);
|
|
+
|
|
+ if (other_priv == q)
|
|
+ continue;
|
|
+
|
|
+ other_qlen = READ_ONCE(other_sch->q.qlen);
|
|
+ other_last_active = READ_ONCE(other_priv->last_active);
|
|
+
|
|
+ if (other_qlen || other_last_active > q->last_checked_active)
|
|
+ num_active_qs++;
|
|
+ }
|
|
+
|
|
+ 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);
|
|
+ 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:
|
|
if (!sch->q.qlen)
|
|
return NULL;
|
|
@@ -2202,6 +2244,7 @@ retry:
|
|
|
|
b->tin_ecn_mark += !!flow->cvars.ecn_marked;
|
|
qdisc_bstats_update(sch, skb);
|
|
+ WRITE_ONCE(q->last_active, now);
|
|
|
|
/* collect delay stats */
|
|
delay = ktime_to_ns(ktime_sub(now, cobalt_get_enqueue_time(skb)));
|
|
@@ -2302,6 +2345,9 @@ static void cake_set_rate(struct cake_ti
|
|
b->tin_rate_ns = rate_ns;
|
|
b->tin_rate_shft = rate_shft;
|
|
|
|
+ if (mtu == 0)
|
|
+ return;
|
|
+
|
|
byte_target_ns = (byte_target * rate_ns) >> rate_shft;
|
|
|
|
WRITE_ONCE(b->cparams.target,
|
|
@@ -2769,6 +2815,7 @@ static void cake_config_init(struct cake
|
|
*/
|
|
q->rate_flags |= CAKE_FLAG_SPLIT_GSO;
|
|
q->is_shared = is_shared;
|
|
+ q->sync_time = 200 * NSEC_PER_USEC;
|
|
}
|
|
|
|
static int cake_init(struct Qdisc *sch, struct nlattr *opt,
|
|
@@ -2840,6 +2887,9 @@ static int cake_init(struct Qdisc *sch,
|
|
qd->avg_peak_bandwidth = q->rate_bps;
|
|
qd->min_netlen = ~0;
|
|
qd->min_adjlen = ~0;
|
|
+ qd->active_queues = 0;
|
|
+ qd->last_checked_active = 0;
|
|
+
|
|
return 0;
|
|
err:
|
|
kvfree(qd->config);
|
|
@@ -2972,6 +3022,7 @@ static int cake_dump_stats(struct Qdisc
|
|
PUT_STAT_U32(MAX_ADJLEN, q->max_adjlen);
|
|
PUT_STAT_U32(MIN_NETLEN, q->min_netlen);
|
|
PUT_STAT_U32(MIN_ADJLEN, q->min_adjlen);
|
|
+ PUT_STAT_U32(ACTIVE_QUEUES, q->active_queues);
|
|
|
|
#undef PUT_STAT_U32
|
|
#undef PUT_STAT_U64
|