Linux 内核 6.12 中的 sched_ext:基于 BPF 的动态调度器
Linux 内核 6.12 版本引入了 sched_ext 调度器类,允许通过 BPF 程序动态替换任务调度逻辑。这消除了实验算法时打补丁和重建内核的需求。策略从用户空间加载,内核通过在失败时回退到 SCHED_NORMAL 的机制来确保安全性。
sched_ext 类划分了职责:内核负责调度队列 (DSQ)、任务迁移和状态管理,而 BPF 策略则决定分类、排序和时间片。在任务唤醒时,会调用 enqueue() 钩子;在内核调度时,会调用 dispatch()。
sched_ext 中的任务生命周期
任务通过 try_to_wake_up() 唤醒,策略会分析其特性:唤醒模式、CPU/I/O 使用情况、cgroup 以及是否存在实时策略 (SCHED_FIFO、SCHED_RR)。策略会将任务置入全局或本地队列,使用虚拟时间进行优先级排序。
在 dispatch() 中,任务从队列中取出,并通过 scx_bpf_dispatch() 连同以纳秒为单位的时间片交给内核。负载均衡或缓存局部性会通过 scx_bpf_kick_cpu() 触发迁移。
DSQ 队列根据插入方式以 FIFO 或优先级模式运行:
- scx_bpf_dispatch() — FIFO 语义。
- scx_bpf_dispatch_vtime() — 按 vtime 排序。
策略的内部排序(分数)不会影响内核优先级(nice、prio)。
示例:scx_horoscope 展示其能力
scx_horoscope 项目使用占星数据调整时间片,展示了 sched_ext 的模式。每 60 秒,它计算行星位置、逆行和月相来生成系数。
任务分类依据:
- 实时策略。
- 唤醒模式。
- CPU/I/O 使用情况。
- cgroup。
基础时间片通过乘数调整:黄道十二宫为任务类型增减时间片,逆行施加 50% 惩罚,圆月为交互任务提供奖励。时间片受 min_slice_ns 和 max_slice_ns 限制。
这是一个教育性示例:计算稳定运行,但无生产使用科学依据。
sched_ext 上的实用调度器
scx 生态包括面向生产的策略:
- scx_lavd(延迟感知虚拟截止期):基于唤醒模式的虚拟截止期,在桌面端将 99 百分位延迟相比 CFS 降低 15–30%。
- scx_rusty:NUMA 优化、最小化迁移,并对服务器热限制敏感。
- scx_flash:通过共享内存从用户空间进行机器学习预测。
开发周期缩短至数小时:构建、加载、指标、迭代——无需重启。
基准测试工具
评估通过以下方式:
/sys/kernel/sched_ext/— 调度和迁移指标。- bpftrace — 事件追踪。
- perf sched — 上下文切换延迟。
- cyclictest — 尾部延迟。
关注百分位,而非平均值:尾部对响应性至关重要。
使用场景:
- 游戏服务器:为游戏逻辑保证时间片,与后台任务隔离。
- 嵌入式系统:任务分组减少切换频率。
- 云环境:超出 cgroup 的带宽保证。
- 音视频:核心预留、最小化抖动。
限制与开发
高切换率下,调度调用开销会增加。逻辑错误会导致性能下降,而不会触发恐慌。API 仍在演进,此功能仍为实验性。
关键点:
- 6.12 中的 sched_ext,启用 CONFIG_SCHED_CLASS_EXT。
- BPF 策略用于快速原型开发。
- 失败时回退到 SCHED_NORMAL。
- 基准测试关注百分位。
- 适用于延迟敏感和 NUMA 场景。
— Editorial Team
暂无评论。