点击上方蓝字关注我,加个标不迷路。
各位小伙伴们大家好,我是 cxuan。
2026 年 10 月 11 日,有一个人坐在了自己的电脑前,敲下了回车键,向他的个人 Linux repo 推送了一个名为 noref-filemap-read-with-llm 的实验性分支。
这个分支有整整 8 个底层内核补丁,补丁打的是 Linux 内核中最重要的地方 --- 页面缓存(Page Cache)。
这个 commit 中有一个影子大家想必都再熟悉不过了,那就是 Claude Code。
这句话的意思是这样的:“代码、测试程序、上述问题列表背后的审查以及本文的初稿,均在我的指导下由 LLM 编程助手(Claude Code)完成的。测试数据在我的机器上跑的”。
而提交这次 commit 的人不是别人,正是 Linux 祖师爷 --- Linus Torvalds。
所以为什么一个人用 Claude Code 提交了一段代码还能被专门写一篇文章出来,这在当下的环境里是一件太正常不过的事情了。
想要知道这次 commit 的分量,得先看看他过去对 AI 的看法是怎样的。
Linus 与 AI
2024 年 9 月的维也纳欧洲开源峰会上,面对席卷硅谷的生成式 AI 狂热,Linus 曾毫不留情地泼下一盆冰水:“我认为现在的 AI 有 90% 都是营销炒作,只有 10% 是现实。”
到了 2026 年 5 月的北美开源峰会,Linus 又拿编译器打了个比方:“那些吹嘘 99% 代码由 AI 生成的人纯属搞笑,你 100% 的机器码还是编译器(Compiler)生成的呢,以前你写汇编的时候,怎么没见你天天出来吹编译器取代了程序员?”
只看批评 AI 炒作的那半句话,Linus 很容易被贴上顽固派 Old Man 的标签。
然而,其实 Linus 从来不讨厌能提升生产力的工具,他讨厌的是脱离工程实际的营销泡沫,以及用 AI 批量制造垃圾却没人负责的烂摊子。
事情仅仅才过了一年。
今年 10 月初,在布拉格举行的欧洲开源峰会上。
面对台下数千名开发者,Linus 更是彻底卸下了外界贴给他的标签,轻描淡写地扔出一句实话: “I actually really like using AI. 我非常喜欢使用 AI 。”
同时他也提醒:涉及真正重要的工作,使用 AI 必须非常谨慎。
于是几天后,所有人都在他的 commit 里看到了这句话的具象化产物。
昔日痛批 AI 行业 90% 都是营销狗屎的祖师爷,居然这次亲自带着 Claude Code 杀进来了?
困扰 18 个月的顽疾
为什么这次 Linus 选择用 Claude Code 提交代码?还有什么问题是 Linus 都解决不了的吗?
因为这次的骨头太难啃了。
事情要从 18 个月前说起。
在 Linux 内核中,页面缓存(Page Cache)负责把磁盘文件缓存到内存中,于是当一个进程去读取缓存里的文件时,为了防止这块内存页(在现代内核中称为 folio)在读取中途被其他线程释放掉,内核必须遵循一套严密的安全动作:先给这个 folio 的原子引用计数加 1,拷贝完数据,再把引用计数减 1。
在单核时代,这不会出现问题。但在今天动辄几十上百核的服务器里,灾难发生了。
当 8 个甚至更多 CPU core 同时高频、小块地读取同一个热点文件时,所有 core 都在疯狂抢着修改同一个内存地址里的引用计数变量。这在硬件底层引发了极其惨烈的跨核缓存行弹跳(Cache-line bouncing),即 CPU 的绝大部分算力根本没用在读数据上,全都浪费在各个 core 之间来回同步那个 fucking 计数器上了。
这个顽疾最早由 Oracle 传奇内核工程师 Matthew Wilcox 在 2024 年底提出。
此后整整 18 个月里,包括 Wilcox 和 Linus 本人在内的多位大神先后尝试过手写补丁,但都遇到了不同的阻力。
于是这一次,Linus 决定换一种做法:他当指挥官,让 Claude Code 当施工队长。
Linus 这次的做法很大胆,在常规缓冲读取路径上,他这次彻底砍掉了对页面引用计数的增减操作。
不加锁、不计数,那怎么保证内存页不会在读取中途被销毁?
答案是用了 Linux 内核的 RCU(Read-Copy-Update,读-拷贝-更新)机制拖底,并引入一个新的 PG_rcu_free 页面标志位。简单来说,就算某个内存页在读取中途被移出了页面缓存,内核也不会立刻把它回收清零,而是等所有正在进行的 RCU 读安全退出后,再延迟释放。
于是在 Linus 的指挥下,Claude Code 一次性干了四件力工的活:
1. 编写了整套共 8 个内核补丁的代码实现;
2. 编写了专门用于榨干多核性能的基准压测程序;
3. 对整套代码进行了自我审查,整理出一份潜在风险与未解问题清单;
4. 起草了逻辑严密的补丁说明信(Cover Letter)。
然后 Linus 用他那台自己的电脑给出了测试指标
| 测试指标(8 线程并发读取同一文件 16 字节) | 优化前(Linux 7.3-rc6 基线) | 优化后(Claude Code 辅助版) | 性能变化幅度 |
|---|---|---|---|
| 每秒读取吞吐量(Reads/sec) | 990 万 – 1040 万次 | 3000 万 – 3300 万次 | 飙升约 3 倍 |
| 每次读取耗时(Kernel cycles/read) | 2,937 – 2,975 周期 | 725 – 726 周期 | CPU 开销暴降 75% |
| 跨核缓存争用(perf c2c load HITMs) | 30,538 次 | 101 次 | 彻底抹平(下降 99.6%) |
| 单线程未映射用户页读取(负面退化) | ~4,150 周期 | ~6,550 周期 | 变慢约 58% |
Linus 用 Claude Code 向全世界演示了什么叫真正的 good taste,不吹概念,只看吞吐量。
但就当这事儿要以 Linus 用 Claude Code 告诉世人用 AI 也能写出优质代码为结束时,却被质疑代码存在极其隐蔽的幽灵 bug 。
如果故事停在这里,这将是一篇标准的“硅谷大模型征服人类最后代码堡垒”的公关爽文。
但别忘了,这里是 Linux 内核邮件列表(LKML),全地球代码审查最严格的修罗场。哪怕交卷的人叫 Linus Torvalds,哪怕他身旁站着最顶级的 Claude Code,也没有任何免死金牌。
在 10 月 13 日对 v3 的审查中,内核开发者 Kiryl Shutsemau没有客套的寒暄,直接指出 filemap_read_rcu_batch() 中存在一个竞态条件(Race Condition)。
我用通俗的语言给大家描述一下这个幽灵 bug 。
上面用 RCU 在砍掉引用计数后,读取线程完全依赖页面大小和文件大小(i_size)的检查来确保自己不读出界。Shutemov 指出,在万分之一的极端并发时序下,可能会发生这样一幕:
1. 线程 A 正在无引用计数地读取文件末尾的一页内存;
2. 就在这一瞬间,内存回收机制把这页内存踢出了缓存(由于 RCU 保护,内存没被销毁,但它的内容已经不再受该文件管辖,甚至部分区域从未被初始化过);
3. 紧接着,线程 B 对这个文件执行了截断(truncate)并瞬间再次拉长(extend)的操作,导致文件的大小(i_size)变大了;
4. 此时线程 A 终于走到了检查文件大小的步骤,它一看,“哎,文件很大啊,我没越界!” 于是傻乎乎地把旧内存页里那段根本没有有效数据的“垃圾内存”,当成正常文件内容拷贝给了位于用户态下的应用程序。
这是一个典型的、会导致静默数据损坏或内核信息泄露的高危并发漏洞。 紧接着,最初提出这个问题的 Matthew Wilcox 也表明了观点。他犀利地指出,为了这一个读取路径而专门去消耗宝贵的页面标志位(PG_rcu_free)在架构上并不优雅,并质疑了补丁在巨页(Large Folios)拆分时的边界处理。
面对两位人类顶级专家的质疑,Linus 爽快地承认了缺陷和改进意见。
随后,由于 Linus 自身的原因,由 Shutemov 直接接过了这组由 Claude Code 打下地基的补丁,在保留其核心 RCU 思路的基础上,彻底重写了页面释放与同步逻辑,将其演进为了全新的 rcu-free-v3 分支。
这一幕反转,可以当做教科书级别的典型案例了。 Claude Code 可以帮你在一天内摆平困扰 18 个月的缓存争用问题,但它算不出在千万次的并发中,一次页面踢出与文件截断导致的问题。
最终仍然靠人类把控并且补上这最关键的一步。
这一次,人类赢了。
但是让我觉得特别后怕的是,这些人可都是顶级大佬,在他们的 review 下,才耗费如此大的功夫才揪出这么个幽灵 Bug 。
换做在普通人身上呢,或许我们早就直接 yes 了吧?
57