sched discussion
[PATCH 0/2] sched/cpufreq: Fix schedutil's boost frequency handling
LLM 分析
sched/cpufreq: 修复 schedutil 的 boost 频率处理
系列概况
- 标题:[PATCH 0/2] sched/cpufreq: Fix schedutil's boost frequency handling
- 作者:Sibi Sankar(patch 2 与 cover letter);Ananthu C V(patch 1)
- 版本:v1(无显式版本号)
- 规模:2 patches,2 files changed,+11/-9
- 修改文件:
drivers/cpufreq/freq_table.c、kernel/sched/cpufreq_schedutil.c - 代码统计:
freq_table.c+1/-6;cpufreq_schedutil.c+10/-3 - Message-ID:
20260806044230.909961-1-sibi.sankar@oss.qualcomm.com - 完整性:15 封邮件(3 封 patch + 12 封 reply),base-commit
0f6da28aab51b16762ed82e8fdeaa5042da45b08
补丁目的
解决 schedutil governor 与 cpufreq boost 联动的两处语义错误:
- 开启 boost 后,
cpuinfo.max_freq被钉死在 boost 天花板;再次关闭 boost 后scaling_max_freq降不下来,policy 级 boost 开关形同虚设。 - 即便
policy->max已被 boost 抬高,schedutil 的 util->freq 映射在固定的capacity_freq_ref处封顶,DVFS 请求永远到不了 boost 频率区间。
旧流程的问题
boost=0 -> cpuinfo.max = 4454400
boost=1 -> cpuinfo.max = 4723200 (policy->max raised by boost)
boost=0 -> cpuinfo.max = 4723200 (NOP: guard only allows increases)
schedutil DVFS request:
util -> map_util_freq(util, ref=capacity_freq_ref=4454400, max=4454400)
-> saturates at ref, never reaches 4723200
新流程
boost=0 -> cpuinfo.max = 4454400
boost=1 -> cpuinfo.max = 4723200
boost=0 -> cpuinfo.max = 4454400 (patch 1: drop guard)
schedutil DVFS request:
ref = max(capacity_freq_ref, READ_ONCE(policy->max))
util -> map_util_freq(util, ref, max)
-> ref tracks policy->max, util can reach boost freqs
Patch 概览
- [PATCH 1/2]
cpufreq: allow cpuinfo max to decrease when boost is disabled(Ananthu C V) - [PATCH 2/2]
sched/cpufreq: Update schedutil's DVFS request to reach the boost frequencies(Sibi Sankar)
关键实现
Patch 1:drivers/cpufreq/freq_table.c
int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy)
{
...
- /*
- * If the driver has set its own cpuinfo.max_freq above max_freq, leave
- * it as is.
- */
- if (policy->cpuinfo.max_freq < max_freq)
- policy->cpuinfo.max_freq = max_freq;
+ policy->cpuinfo.max_freq = max_freq;
...
}
直接把 policy->cpuinfo.max_freq 设为 freq table 扫描得到的 max_freq,去掉原先 "只升不降" 的逻辑。修复 commit 538b0188da46("cpufreq: ACPI: Set cpuinfo.max_freq directly if max boost is known")带来的副作用。
Patch 2:kernel/sched/cpufreq_schedutil.c
static unsigned int get_next_freq(struct sugov_policy *sg_policy,
unsigned long util, unsigned long max)
{
struct cpufreq_policy *policy = sg_policy->policy;
- unsigned int freq;
+ unsigned int freq, ref;
- freq = get_capacity_ref_freq(policy);
- freq = map_util_freq(util, freq, max);
+ ref = get_capacity_ref_freq(policy);
+
+ /*
+ * That fixed anchor governs how utilization is interpreted, but
+ * the DVFS request is free to target the current policy ceiling.
+ * Using ref alone would saturate the util->freq map at ref so
+ * use policy->max to reach boost frequencies.
+ */
+ freq = map_util_freq(util, max(ref, READ_ONCE(policy->max)), max);
...
}
把固定的 capacity_freq_ref 改成 max(ref, policy->max),让 util->freq 映射的 "上限" 跟着 boost 状态动态抬升。capacity_freq_ref 仍用于 utilization 解释,不会改变 PELT / EAS 的尺度。
类比
把 cpuinfo.max_freq 想成公寓楼的 "封顶租金"。原合约规定只能涨价不能降价,房东把租金抬到 "boost 楼层" 后,即使关闭 boost(楼层优惠结束),租金也回不到普通层。新合约允许随市场上下浮动,boost 关闭后租金自然能回到常规档。
schedutil 的 anchor 问题更像用水龙头的物理刻度(最大只能到 70%)当 "标准尺" 决定该开多猛的水压。即使水龙头实际最大刻度已经被 boost 拓宽到 100%,尺子说只能到 70%,水压就永远跑不到 boost 段。换成 "取尺子和实际刻度的较大值",水压就能冲上 boost。
Highlight:风险与注意点
- 维护者分歧:Christian Loehle(mail #4)和 Vincent Guittot(mail #10 / #14)都引用了 Dietmar Eggemann 的上游系列
20250626093018.106265-1-dietmar.eggemann@arm.com,说明 schedutil 的 frequency-ref 路径上游正在做更完整的重构,本系列可能与上游方案冲突或重复,需要协调 merge 顺序。 - Dmitry 的反问(mail #5 / #8):"cpuinfo.max 因 boost 关闭而下降" 和 "因热压力临时不可用" 在 sysfs 上表现相同,作者在 #11 中只重申 cover letter 的 logs,没有从语义层面进一步区分这两条路径。
- policy 级 boost 失效:patch 1 修复后,依赖
cpufreq_policy->boost来做 "局部 boost" 的 driver 行为会改变,需要回归cpufreq_stats的time_in_state分布。 - DVFS 回归:patch 2 让
ref = max(ref, policy->max),boost 关闭后 ref 与 policy->max 同时回落;若 driver 在 boost 关闭后仍把policy->max临时抬高(例如 thermal-related),util->freq 会随之放大,需用真实负载跑性能回归。 - 签名链:patch 1 由 Ananthu 提交、Sibi 转发,签名链
Signed-off-by: Ananthu C V+Signed-off-by: Sibi Sankar完整;patch 2 仅 Sibi 自签。
版本变化
本系列目前仅 v1 一版,无 vN -> vN+1 演进;后续可能需要根据 Dietmar 系列与 Vincent / Christian 的反馈重新出 v2。
一句话总结
两枚 patch 分别修 "cpuinfo.max_freq 关闭 boost 后无法回落" 和 "schedutil 在 boost 下永远到不了 boost 频率" 两个 cpufreq <-> schedutil 的语义错误,但需要先与 Dietmar 上游 series 对齐再合入。
sysfs boost flag -> cpufreq driver -> cpuinfo.max_freq
|
v scaling_max_freq
|
v schedutil get_next_freq()
|
v
DVFS request
|
v target freq in [policy->min, policy->max]
^ before fix: <= ref (boost never reached)
^ after fix: can reach boost frequencies