net/sched: sch_cake: fixup cake_mq rate adjustment for diffserv config

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: 1bddd758ba ("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>
This commit is contained in:
Jonas Köppeler 2026-02-26 12:40:16 +01:00 committed by Jakub Kicinski
parent 0b3cd139be
commit 15c2715a52

View File

@ -391,8 +391,8 @@ static const u32 inv_sqrt_cache[REC_INV_SQRT_CACHE] = {
1239850263, 1191209601, 1147878294, 1108955788 1239850263, 1191209601, 1147878294, 1108955788
}; };
static void cake_set_rate(struct cake_tin_data *b, u64 rate, u32 mtu, static void cake_configure_rates(struct Qdisc *sch, u64 rate, bool rate_adjust);
u64 target_ns, u64 rtt_est_ns);
/* http://en.wikipedia.org/wiki/Methods_of_computing_square_roots /* http://en.wikipedia.org/wiki/Methods_of_computing_square_roots
* new_invsqrt = (invsqrt / 2) * (3 - count * invsqrt^2) * new_invsqrt = (invsqrt / 2) * (3 - count * invsqrt^2)
* *
@ -2040,12 +2040,9 @@ static struct sk_buff *cake_dequeue(struct Qdisc *sch)
if (num_active_qs > 1) if (num_active_qs > 1)
new_rate = div64_u64(q->config->rate_bps, num_active_qs); 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_configure_rates(sch, new_rate, true);
cake_set_rate(b, new_rate, 0, 0, 0);
q->last_checked_active = now; q->last_checked_active = now;
q->active_queues = num_active_qs; q->active_queues = num_active_qs;
q->rate_ns = b->tin_rate_ns;
q->rate_shft = b->tin_rate_shft;
} }
begin: begin:
@ -2362,12 +2359,10 @@ static void cake_set_rate(struct cake_tin_data *b, u64 rate, u32 mtu,
b->cparams.p_dec = 1 << 20; /* 1/4096 */ 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_sched_data *q = qdisc_priv(sch);
struct cake_tin_data *b = &q->tins[0]; 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; q->tin_cnt = 1;
@ -2381,12 +2376,10 @@ static int cake_config_besteffort(struct Qdisc *sch)
return 0; 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 */ /* convert high-level (user visible) parameters into internal format */
struct cake_sched_data *q = qdisc_priv(sch); 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 quantum = 256;
u32 i; u32 i;
@ -2457,7 +2450,7 @@ static int cake_config_precedence(struct Qdisc *sch)
* Total 12 traffic classes. * 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: /* Pruned list of traffic classes for typical applications:
* *
@ -2474,8 +2467,6 @@ static int cake_config_diffserv8(struct Qdisc *sch)
*/ */
struct cake_sched_data *q = qdisc_priv(sch); 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 quantum = 256;
u32 i; u32 i;
@ -2505,7 +2496,7 @@ static int cake_config_diffserv8(struct Qdisc *sch)
return 0; 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: /* Further pruned list of traffic classes for four-class system:
* *
@ -2518,8 +2509,6 @@ static int cake_config_diffserv4(struct Qdisc *sch)
*/ */
struct cake_sched_data *q = qdisc_priv(sch); struct cake_sched_data *q = qdisc_priv(sch);
u32 mtu = psched_mtu(qdisc_dev(sch));
u64 rate = q->config->rate_bps;
u32 quantum = 1024; u32 quantum = 1024;
q->tin_cnt = 4; q->tin_cnt = 4;
@ -2547,7 +2536,7 @@ static int cake_config_diffserv4(struct Qdisc *sch)
return 0; 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. /* Simplified Diffserv structure with 3 tins.
* Latency Sensitive (CS7, CS6, EF, VA, TOS4) * Latency Sensitive (CS7, CS6, EF, VA, TOS4)
@ -2555,8 +2544,6 @@ static int cake_config_diffserv3(struct Qdisc *sch)
* Low Priority (LE, CS1) * Low Priority (LE, CS1)
*/ */
struct cake_sched_data *q = qdisc_priv(sch); struct cake_sched_data *q = qdisc_priv(sch);
u32 mtu = psched_mtu(qdisc_dev(sch));
u64 rate = q->config->rate_bps;
u32 quantum = 1024; u32 quantum = 1024;
q->tin_cnt = 3; q->tin_cnt = 3;
@ -2581,32 +2568,33 @@ static int cake_config_diffserv3(struct Qdisc *sch)
return 0; 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_data *qd = qdisc_priv(sch);
struct cake_sched_config *q = qd->config; struct cake_sched_config *q = qd->config;
int c, ft; int c, ft;
switch (q->tin_mode) { switch (q->tin_mode) {
case CAKE_DIFFSERV_BESTEFFORT: case CAKE_DIFFSERV_BESTEFFORT:
ft = cake_config_besteffort(sch); ft = cake_config_besteffort(sch, rate, mtu);
break; break;
case CAKE_DIFFSERV_PRECEDENCE: case CAKE_DIFFSERV_PRECEDENCE:
ft = cake_config_precedence(sch); ft = cake_config_precedence(sch, rate, mtu);
break; break;
case CAKE_DIFFSERV_DIFFSERV8: case CAKE_DIFFSERV_DIFFSERV8:
ft = cake_config_diffserv8(sch); ft = cake_config_diffserv8(sch, rate, mtu);
break; break;
case CAKE_DIFFSERV_DIFFSERV4: case CAKE_DIFFSERV_DIFFSERV4:
ft = cake_config_diffserv4(sch); ft = cake_config_diffserv4(sch, rate, mtu);
break; break;
case CAKE_DIFFSERV_DIFFSERV3: case CAKE_DIFFSERV_DIFFSERV3:
default: default:
ft = cake_config_diffserv3(sch); ft = cake_config_diffserv3(sch, rate, mtu);
break; break;
} }
@ -2617,6 +2605,14 @@ static void cake_reconfigure(struct Qdisc *sch)
qd->rate_ns = qd->tins[ft].tin_rate_ns; qd->rate_ns = qd->tins[ft].tin_rate_ns;
qd->rate_shft = qd->tins[ft].tin_rate_shft; 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) { if (q->buffer_config_limit) {
qd->buffer_limit = q->buffer_config_limit; qd->buffer_limit = q->buffer_config_limit;