mcpField
K
kernel-internals

kernel-internals

github.com/mohitmishra786开发269319 次安装18 周前更新
代码仓库

关于 kernel-internals

kernel-internals 是面向 Agent 的 Linux 内核内部知识技能,涵盖调度、内存管理、VFS、页缓存和 OOM。它将子系统概念与诊断命令及常见排查路径结合。

主要功能

  1. 01CFS 与 EEVDF 调度原理
  2. 02伙伴分配器与 SLUB 分析
  3. 03kmalloc 与 vmalloc 用法
  4. 04VFS 与页缓存机制
  5. 05/proc/meminfo 与 OOM 诊断

适用场景

  1. 01排查调度延迟或 CPU 分配不均
  2. 02分析内核内存分配失败
  3. 03检查页缓存与预读行为
  4. 04诊断内存压力和 OOM 选择

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mohitmishra786/low-level-dev-skills --skill kernel-internals

安装后在 Claude Code 中输入/kernel-internals确认已加载。

详细介绍

内核内部机制

用途

指导 Agent 了解 Linux 内核内部机制:CFS 和 EEVDF 调度器、运行队列和 vruntime、伙伴分配器和 SLUB、vmalloc 与 kmalloc、VFS dentry/inode/file 对象、页缓存和预读、内存区域、OOM killer 启发式算法,以及 /proc/meminfo 解读。

适用场景

  • 诊断调度延迟或 CPU 分配不公平
  • 了解大型内核分配中 kmalloc 失败与 vmalloc 的区别
  • 分析页缓存行为和预读效果
  • 在内存压力期间解读 /proc/meminfo
  • 调试 OOM killer 的受害进程选择
  • 阅读 kernel/sched/、mm/ 或 fs/ 中的内核源码

工作流

1. 调度器 — CFS 和 EEVDF

Linux 对 CFS 类调度使用 EEVDF(最早合格虚拟截止时间优先)。EEVDF 于 6.6(2023)作为一个选项合入;CFS→EEVDF 的逐步迁移已于 6.12(2024 年 11 月)完成。对于较旧的 6.6–6.11 内核,请确认当前启用的是哪个调度器。核心概念(运行队列、vruntime/lag)仍然适用:

Per-CPU runqueue (struct rq)
├── cfs_rq — fair-class tasks sorted by vruntime/deadline
├── rt_rq  — real-time tasks (FIFO/RR)
└── dl_rq  — SCHED_DEADLINE tasks

关键指标:

# Task scheduling info
chrt -p <pid>
cat /proc/<pid>/sched

# Runqueue latency (scheduler debugging)
cat /sys/kernel/debug/sched/debug  # requires debugfs

# Trace scheduler events
perf sched record -a -- sleep 5
perf sched latency

vruntime — 跟踪已消耗 CPU 时间的虚拟运行时间;vruntime 越低,越有资格获得 CPU。

# CFS tunables
sysctl kernel.sched_latency_ns
sysctl kernel.sched_min_granularity_ns
sysctl kernel.sched_wakeup_granularity_ns
2. EEVDF 具体机制

EEVDF 会选择合格任务中虚拟截止时间最早的任务,从而改善短时间片任务的延迟公平性。lag 为正的任务符合资格;调度器会在符合资格的任务中选择虚拟截止时间最早的任务。

# Check kernel version (EEVDF transition complete in 6.12+)
uname -r

# Scheduler documentation
# docs.kernel.org/scheduler/sched-eevdf.html
3. 内存子系统 — 伙伴分配器

物理页按 2 的幂次序分配(order 0 = 4KB,order 1 = 8KB,……)。

ZONE_DMA / ZONE_DMA32 / ZONE_NORMAL / ZONE_MOVABLE
└── free_area[MAX_ORDER] — buddy lists per order
# Buddy allocator stats
cat /proc/buddyinfo

# Per-zone page counts
cat /proc/zoneinfo | head -80
4. SLUB 分配器

默认的 kmalloc 后端——为常用大小维护每 CPU 缓存(slab)。

# SLUB debug (requires CONFIG_SLUB_DEBUG)
cat /sys/kernel/slab/*/objects 2>/dev/null | head

# kmalloc size classes visible in /proc/slabinfo
cat /proc/slabinfo | head -20
API适用场景
kmalloc(size, GFP_KERNEL)≤ ~128KB(取决于架构),物理连续
kzalloc(size, flags)清零的 kmalloc
vmalloc(size)大块、虚拟连续(物理上可能不连续)
get_free_pages()直接分配页面
// Kernel module allocation example
void *buf = kmalloc(4096, GFP_KERNEL);
if (!buf)
    return -ENOMEM;
kfree(buf);
5. 高端内存

在 32 位系统或特定配置中,ZONE_HIGHMEM 保存未永久映射到内核虚拟地址空间的页面。在 64 位 x86/arm64 上,几乎所有 RAM 都位于 ZONE_NORMAL。

grep -i highmem /proc/zoneinfo
6. VFS 层
Path lookup: /home/user/file.txt
├── dentry cache (dcache) — directory entry tree
├── inode — metadata (permissions, size, ops)
└── file — per-open-file state (offset, flags)
# Mounted filesystems
cat /proc/mounts

# Inode/dentry cache pressure
sysctl vm.vfs_cache_pressure   # higher = reclaim caches sooner

# File descriptor usage
ls /proc/<pid>/fd | wc -l
7. 页缓存和预读
# Drop caches (testing only — destructive to perf)
sync && echo 3 | sudo tee /proc/sys/vm/drop_caches

# Readahead tuning
blockdev --getra /dev/sda
blockdev --setra 4096 /dev/sda

# Per-file cache status
cat /proc/<pid>/smaps_rollup

页缓存页面会显示在 meminfo 的 Cached 中。脏页会等待回写。

8. 解读 /proc/meminfo
cat /proc/meminfo
字段含义
MemTotal可用 RAM 总量
MemFree完全未使用的页面
MemAvailable可分配内存的估算值(包括可回收缓存)
Cached页缓存 + tmpfs
Buffers块设备元数据缓存
SwapTotal / SwapFree交换空间
Dirty等待回写的页面
AnonPages匿名(堆/栈)页面
Slab内核对象缓存
SReclaimable可回收的 slab
SUnreclaim内核结构(不易回收)
Memory pressure diagnosis
├── MemAvailable low + Cached high → page cache reclaim candidate
├── AnonPages high + SwapFree low → OOM risk
├── Slab huge → kernel object leak; check /proc/slabinfo
└── Dirty high → slow writeback; check I/O scheduler
9. OOM killer
# OOM score per process (higher = more likely victim)
cat /proc/<pid>/oom_score
cat /proc/<pid>/oom_score_adj   # -1000 to 1000, admin adjustment

# OOM events in kernel log
dmesg | grep -i "out of memory"
journalctl -k | grep -i oom

OOM killer 会根据 oom_score 进行选择,并考虑内存用量、子进程和 oom_score_adj。保护关键守护进程:

# Protect process from OOM (requires root)
echo -1000 | sudo tee /proc/<pid>/oom_score_adj

常见问题

症状原因修复方法
kmalloc: allocation failed内存碎片化或分配大小过大使用 vmalloc;降低内存压力;仅在需要时使用 GFP_ATOMIC
iowait 高,MemAvailable 低页缓存抖动增加 RAM;调整 vfs_cache_pressure
OOM 杀死了错误的进程内存用量高但 adj 值低设置 oom_score_adj;使用 cgroups memory.max
调度不公平RT 任务导致 CFS 饥饿检查 chrt;使用 isolcpus 隔离 CPU
SLUB 损坏模块中存在释放后使用问题启用 KASAN;使用 slub_debug 进行审查
文件读取缓慢预读量过小增加预读量;检查后端设备

相关技能

  • skills/kernel/device-drivers — 使用这些子系统的字符设备/平台驱动
  • skills/kernel/kernel-debugging — 使用 ftrace、kgdb 调查内核内部
  • skills/low-level-programming/linux-kernel-modules — LKM 开发基础
  • skills/kernel/kernel-testing — 使用 KUnit 编写子系统单元测试
  • skills/profilers/linux-perf — 使用 perf sched 进行性能和内存分析
  • skills/observability/ebpf — 从用户空间跟踪调度器和内存事件

评论

支持 Markdown