Linux内核CFS完全公平调度器深度实战

1. CFS核心理念

完全公平调度器(Completely Fair Scheduler)自Linux 2.6.23版本起成为默认的普通进程调度器。与O(1)调度器使用时间片不同,CFS的核心思想是:不分配固定时间片,而是让每个进程公平分享CPU时间。

CFS的目标很简单:让所有可运行进程获得完全相等的CPU时间。在理想的多任务系统中,N个进程应各自获得1/N的CPU时间。现实中由于进程休眠、I/O等待等原因,实际实现需要对vruntime进行精细管理。

CFS引入了一个关键概念——虚拟运行时间(vruntime),它度量每个进程已经在CPU上运行了多少"加权"时间。vruntime最小的下一个获得CPU,保证公平性。

2. 红黑树数据结构

CFS使用红黑树(Red-Black Tree)作为可运行进程队列,O(log n)查找效率。红黑树的键值为进程的vruntime。内核数据结构:

struct cfs_rq {
    struct load_weight load;
    unsigned long runnable_weight;
    unsigned int nr_running;
    u64 min_vruntime;
    struct rb_root_cached tasks_timeline;
    struct sched_entity *curr, *next, *last, *skip;
};

3. vruntime计算与权重体系

vruntime核心公式:vruntime += delta_exec * (NICE_0_LOAD / weight)

nice值越高权重越小,vruntime增长越快,越早被抢占。nice值之间CPU份额按1.25倍等比换算。

nice值权重相对CPU比例
-2088761最高优先级
01024基准值
10110约为基准的1/9
1915最低优先级

4. 调度延迟与粒度控制

  • sched_latency_ns(默认6ms):调度周期
  • min_granularity_ns(默认0.755ms):最小时间片
  • wakeup_granularity_ns(默认1ms):唤醒抢占粒度

时间片 = sched_latency / nr_running(不低于min_granularity)。

5. 调度策略体系

  • SCHED_NORMAL:普通分时进程
  • SCHED_BATCH:批处理进程
  • SCHED_IDLE:极低优先级
  • SCHED_FIFO/SCHED_RR:实时策略
  • SCHED_DEADLINE:EDF最早截止时间优先

调度类优先级:dl_sched_class → rt_sched_class → fair_sched_class → idle_sched_class

6. SMP负载均衡

CFS通过sched domain层级结构实现多核负载均衡:调度域分组CPU覆盖NUMA节点/Die/Package等粒度,负载均衡时机包括IDLE(空闲拉取)、BALANCE_FORK、BALANCE_WAKE。AutoNUMA Balancing自动将进程迁移至内存所在节点。

7. 内核抢占与上下文切换

  • 用户态抢占:返回用户态时检查TIF_NEED_RESCHED
  • 内核态抢占(CONFIG_PREEMPT):安全切入点允许抢占
  • Voluntary Preemption:cond_resched()主动让出
  • Full Preemption(CONFIG_PREEMPT_RT):中断线程化

核心流程:schedule() → pick_next_task() → context_switch(switch_mm + switch_to)

8. 组调度与cgroup CPU控制器

  • cpu.weight:组间份额(默认100,1-10000)
  • cpu.max:带宽限制"50000 100000"
  • cpu.max.burst:短时爆发量
  • cpu.pressure:PSI压力指标
  • CFS Bandwidth Control:严格配额限制

9. NUMA感知调度

NUMA Balancing自动将进程迁移到内存所在节点。工具:numactl绑定策略,numastat查看统计,/proc/zoneinfo查看节点状态。

10. 调试与调优工具

/proc/sched_debug:每CPU详细调度状态

cat /proc/sched_debug | head -40

perf sched:调度延迟分析

perf sched record -- sleep 5
perf sched latency   # 延迟分布
perf sched map       # CPU时间线
perf sched script    # 原始事件

/proc/[pid]/sched:单进程调度信息

cat /proc/self/sched | head -20
# 字段:vruntime、exec_start、sum_exec_runtime、nr_migrations

关键参数:sched_min_granularity_ns、sched_wakeup_granularity_ns、sched_migration_cost_ns、sched_autogroup_enabled

11. 实战案例

场景1:低延迟服务——nice -n -10提升优先级,或SCHED_FIFO,降低min_granularity_ns

场景2:批处理隔离——nice -n 19或chrt -b 0设为SCHED_BATCH

场景3:限制后台CPU——cgroup cpu.max"50000 100000"限制为单核50%

12. 总结

CFS通过红黑树+vruntime的精妙组合实现高效公平调度。理解核心机制(vruntime、权重、调度粒度、负载均衡)对性能调优至关重要。合理设置nice值、cgroup隔离、SMP负载均衡和NUMA策略,可使系统在各类负载下保持最佳表现。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿
网站二维码

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部