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

【操作系统百科】调度延迟分析:是不是调度器的锅?

文章导航

分类入口
os
标签入口
#sched-latency#runqlat#perf-sched#bpftrace#psi#throttle

目录

服务延迟上涨,运维第一反应”机器不够”——但常常不是。真相可能是:CPU 够用,但任务排队等 CPU 等久了。本文介绍怎样把”调度延迟”从总延迟里分离出来,以及生产中调度相关的常见故障与诊断手法。

一、先看图:三种延迟

flowchart LR
    EV[事件到来<br/>例如 I/O 完成] --> W[wakeup<br/>task 入 runqueue]
    W -->|runqueue 等待| S[schedule<br/>task 被选中]
    S -->|CPU 跑| E[处理完成]
    W -.wakeup latency.-> S
    classDef sig fill:#f0883e22,stroke:#f0883e,color:#adbac7;
    classDef run fill:#3fb95022,stroke:#3fb950,color:#adbac7;
    class EV,W sig
    class S,E run

三个指标:

总响应时间 ≈ block time + runq latency + 运行时间。前者是”外部依赖”,后者是”调度器 + CPU 占用率”。

二、wakeup / runq latency 测量

2.1 bpftrace runqlat

bpftrace -e '
tracepoint:sched:sched_wakeup,
tracepoint:sched:sched_wakeup_new {
    @qt[args->pid] = nsecs;
}
tracepoint:sched:sched_switch /@qt[args->next_pid]/ {
    @usecs = hist((nsecs - @qt[args->next_pid]) / 1000);
    delete(@qt[args->next_pid]);
}'

输出直方图:runq latency (μs) 分布。

bcc-tools 里有现成的 runqlat.pyrunqlen.py

2.2 perf sched

perf sched record -- sleep 30
perf sched latency          # 每 task avg/max 等待
perf sched timehist         # 时间线
perf sched map              # 每 CPU 运行图

perf sched latency 的关键列:

max delay > 10ms 就值得关注

2.3 schedviz

Google 开源可视化工具,把 perf sched 数据画成彩带图,一眼看出某 CPU 空转而其他排队。

三、block time 的分离

bpftrace 抓 sched_switchprev_state = D 或 S 即 block。

bpftrace -e '
tracepoint:sched:sched_switch /args->prev_state == 2/ {  // D state
    @block[args->prev_pid] = nsecs;
}
tracepoint:sched:sched_wakeup {
    if (@block[args->pid]) {
        @blocktime = hist((nsecs - @block[args->pid]) / 1000);
        delete(@block[args->pid]);
    }
}'

block time 高一般是 I/O / 锁。C-26 不深入,但用 offcputime、perf record -e sched:sched_switch -g 可抓 off-CPU 火焰图。

四、PSI:系统级延迟压力

cgroup v2 的 PSI 给出 CPU/IO/MEM 的 “some/full” 压力。

/proc/pressure/cpu
some avg10=0.12 avg60=0.08 avg300=0.05 total=...

含义:“过去 10 秒里 12% 时间至少有一个 runnable 任务在等 CPU”。

生产告警阈值:某 cgroup cpu.pressure some avg10 > 30% → CPU 不足或节流。

systemd-oomd 也读 PSI 做 OOM 预判。

五、生产故障模板

5.1 CFS quota throttle

cgroup v2 cpu.max = 100000 1000000(0.1 核)。任务用完额度 → 被 throttle 到下周期。

症状:延迟 > 100ms 且周期性

诊断cat /sys/fs/cgroup/.../cpu.statnr_throttledthrottled_usec

解决:放宽 quota 或 period 调小(100ms → 10ms 可降 worst case)

5.2 NUMA 迁移抖动

症状:进程间歇延迟飙,numastat 显示 remote 访问

诊断perf stat -e migrationsbpftrace sched_migrate_task

解决numactl --cpunodebind --membind 固定

5.3 RT 饿死

SCHED_FIFO 任务死循环,SCHED_OTHER 全饿。

症状:ssh 不响应;top 看 RT 任务占 100%

救命echo 950000 > /proc/sys/kernel/sched_rt_runtime_us(恢复节流);手动 chrt -o 降级

5.4 HT / LLC 争用

同 core 两 HT 争 L1/L2;同 socket LLC miss 高。

诊断perf stat -e cpu-cycles,instructions,cache-misses 看 IPC 降;perf c2c 看 false sharing

解决:isolate CPU、禁用 HT(或 nosmt)、cache partitioning (Intel RDT)

5.5 autogroup 意外

桌面用户并行 compile + 浏览器共 session → autogroup 相同 → 没拉开

诊断cat /proc/<pid>/autogroup

解决systemd-run --scope 开单独 scope

六、方法论:三问

Q1: 真实运行时 vs 等待时?

cat /proc/<pid>/schedstat/proc/<pid>/schedsum_exec_runtime vs wait_sum。wait_sum 大 = 等 CPU。

Q2: 等 CPU 是因为 CPU 忙还是被 throttle?

PSI cpu some;cgroup cpu.stat nr_throttled。

Q3: 迁移/cache miss 占多少?

perf stat 看 IPC、migrations;若 IPC 低但 CPU 不忙,怀疑 cache。

按顺序排查能解大多数”CPU 不忙但服务慢”的案子。

七、工具对照表

目标 首选工具
runq latency 分布 bpftrace runqlat.bt / bcc runqlat
off-CPU 时间 bcc offcputime + flamegraph
事件时间线 perf sched timehist / schedviz
系统压力 /proc/pressure/ + dashboard
cgroup throttle cpu.stat + bpftrace
迁移 sched_migrate_task tracepoint
cache perf stat + perf c2c

八、从 trace 到 flamegraph

perf record -F 99 -g -- ./app
perf script | stackcollapse-perf.pl | flamegraph.pl > cpu.svg

off-CPU flamegraph(Brendan Gregg 首倡):

bcc/tools/offcputime -f -p <pid> 30 > out.stacks
flamegraph.pl --color io < out.stacks > offcpu.svg

on-CPU 看哪里在跑;off-CPU 看哪里在等——两条合起来”时间都花哪了”一目了然。

九、观测成本

经验:tracepoint + bpftrace 聚合是生产推荐;perf record 用于深度调查。

十、常见误诊

十一、小结

下一篇 C-27 讲 idle governors——“什么都不做”怎样省电又不丢响应。


参考文献

工具


上一篇big.LITTLE / Intel P+E 下一篇idle governors:空闲管理

同主题继续阅读

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

2026-04-18 · os

【操作系统百科】cgroup v2:资源控制的统一模型

cgroup v2 把 v1 的多 hierarchy 统一成单一树。本文讲 unified hierarchy、controller 清单、cpu.weight/io.weight/memory.max、PSI 压力指标、systemd slice/scope/service 层级、cgroup delegation 与 rootless、以及 cgroup v2 的诊断姿势。

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 .