土法炼钢兴趣小组的算法知识备份

【操作系统百科】SCHED_DEADLINE:EDF + CBS 的落地

文章导航

分类入口
os
标签入口
#sched-deadline#edf#cbs#admission-control#sched-setattr

目录

FIFO/RR 给了优先级,但没”量化时间”。SCHED_DEADLINE(3.14,2014 年)是 Linux 第一个以保证带宽为核心的调度类。它回答一个问题:“我每 20ms 必须跑够 5ms,能保证吗?”

本文讲 DEADLINE 的数学模型、内核实现、API、以及生产部署中真正能用的场景与避坑。

一、先看图:三元组与准入

flowchart TB
    U[用户 sched_setattr<br/>runtime=5ms<br/>deadline=20ms<br/>period=20ms] --> K[内核 admission control]
    K -->|Σ runtime/period > 1?| R[reject EBUSY]
    K -->|OK| ADD[加入 dl_rq]
    ADD --> EDF[全局 EDF 选最早 deadline]
    EDF --> RUN[运行]
    RUN --> CBS[CBS 监控:<br/>runtime 耗完则 throttle<br/>等下周期再给]
    CBS --> REFILL[period 到 → 重填 runtime,<br/>deadline += period]
    REFILL --> EDF
    classDef k fill:#388bfd22,stroke:#388bfd,color:#adbac7;
    classDef g fill:#3fb95022,stroke:#3fb950,color:#adbac7;
    classDef w fill:#f0883e22,stroke:#f0883e,color:#adbac7;
    class U,K k
    class EDF,RUN,CBS,REFILL,ADD g
    class R w

关键:

二、EDF 与 CBS 的双重角色

2.1 EDF:选择策略

每次选”最近 deadline”的任务。单核 EDF 已证明最优——只要任务集 schedulable,EDF 就不 miss deadline。

2.2 CBS:隔离机制

纯 EDF 有个致命弱点:一个任务多跑,会连累其他(deadline 未到但它在跑,真正紧急的被顶)。CBS(Abeni-Buttazzo 1998)给每任务一个”带宽服务器”:

Linux 的 DEADLINE 实现是 EDF + CBS,两者缺一不可。

三、API:sched_setattr

#include <linux/sched/types.h>
struct sched_attr attr = {
    .size = sizeof(attr),
    .sched_policy = SCHED_DEADLINE,
    .sched_flags = 0,
    .sched_runtime  = 5 * 1000 * 1000,   // 5 ms
    .sched_deadline = 20 * 1000 * 1000,  // 20 ms
    .sched_period   = 20 * 1000 * 1000,  // 20 ms
};
if (sched_setattr(0, &attr, 0) < 0) perror("setattr");

没 glibc 包装,用 syscall(SYS_sched_setattr, ...)

命令行:chrt -d -T 5000000 -D 20000000 -P 20000000 ./app

四、准入控制

Linux 每 CPU 的 DL 带宽上限默认是 95%(0.95):

/proc/sys/kernel/sched_rt_runtime_us   # 和 RT 共享 5%
/proc/sys/kernel/sched_rt_period_us

Σ(runtime/period) 超 0.95 则 sched_setattr 返回 EBUSY。这是硬保证——内核拒绝进入无法满足的状态。

多 CPU 情况下,每加入一个 DL 任务,内核会尝试在各 CPU 的剩余带宽里放得下。

五、与 cpuset/cgroup 互斥

DL 需要全系统视角做准入,跟 cpuset、cpu controller 冲突。常见现象:

Linux 的处理:DL 任务不能进入 cpu cgroup controller(会报错);cpuset 内部要保证 Σ 带宽可行。

实践上:把 DL 系统独立跑,不要混 cgroup CPU 限流。

六、典型应用

6.1 视频播放

每 16.6ms(60fps)要渲染一帧。设 runtime=10ms、period=16ms、deadline=16ms。保证”不掉帧”。

6.2 机器人控制

PLC 控制回路 1kHz。runtime=200μs、period=1000μs。配合 PREEMPT_RT 延迟可控。

6.3 无人机飞控

PX4、ArduPilot 在 NuttX / Linux 上用类似策略。DL + busy loop 兜底。

6.4 音频 DAW

JACK、PipeWire 的 RT 线程:period = buffer_size / sample_rate。DL 保证 period 内完成 mix & encode。

七、为什么生产环境 DL 还不算主流?

主要在专用节点 / 嵌入式 / 实时工作站 用。通用云服务鲜用。

八、诊断

cat /proc/<pid>/sched | grep dl_
# dl.dl_runtime, dl.dl_deadline, dl.dl_period
# dl.runtime (剩余本周期)

/sys/kernel/debug/sched/dl_bw 看每 CPU 带宽使用。

trace-cmd record -e sched_switch,sched:sched_process_exit + DL task 可以看 throttle 事件。

九、常见坑

坑 Asched_setattr EBUSY 原因:全系统或目标 CPU 带宽已满 解决:减小 runtime 或增大 period

坑 B:DL 任务 throttle 过频 原因:runtime 估小,实际需要更多 解决:测量真实 WCET 再设 runtime(留 20% 余量)

坑 C:迁移后 deadline 丢失 原因:跨 CPU 迁移需重新准入;高负载下失败 解决SCHED_FLAG_RECLAIM 允许借空闲带宽;或固定 CPU

坑 D:DL 任务跟 isolcpus 冲突 原因:isolcpus 限制了 DL 可用 CPU,Σbw 算不过来 解决:调 isolcpus 范围 或 显式绑定

十、与 FIFO 的选择

DEADLINE 更现代、更数学、更可预测;但 API 不如 FIFO 普及,工具链少。

十一、小结

下一篇 C-24 讲多核负载均衡——调度域、NUMA、big.LITTLE 的骨架是怎样搭起来的。


参考文献

工具


上一篇SCHED_FIFO/RR 与 PREEMPT_RT 下一篇多核负载均衡

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。

2026-04-18 · os

【操作系统百科】调度理论:为什么『完美调度器』不存在

调度是在有限 CPU 上分配无限需求的艺术。本文从 FCFS/SJF/RR/MLFQ/Fair-share/Lottery/Stride 一路讲到 EDF/CBS,梳理响应-吞吐-公平三难;给出 Mutexpriority inversion、Multi-level feedback、starvation 的定义,以及为什么任何调度目标都不能同时最优。

2026-04-27 · os

【操作系统百科】内存回收

Linux 内存回收是 VM 最复杂的子系统之一。本文讲 active/inactive LRU、kswapd 与 direct reclaim、watermark 三线、swappiness 的真实含义、MGLRU 改造、memcg 回收与 PSI。

2026-04-28 · os

【操作系统百科】交换

swap 还值得开吗?本文讲 swap area 基础、swap cache、zram 压缩内存、zswap 前端压缩池、swappiness 的真实含义、容器里的 swap 策略,以及为什么现代 Android 全靠 zram 不靠磁盘。

2026-05-03 · os

【操作系统百科】Slab/SLUB 分配器

buddy 只管页粒度(4K+),内核大多数对象只有几十到几百字节。slab/SLUB 在 buddy 之上做对象级缓存。本文讲 slab 历史、SLUB 接手、SLOB 退场、kmem_cache、per-CPU cache、KASAN 集成。


By .