Industry#Coding agent#Benchmark

Linus Torvalds used Claude Code on a kernel patch series: 23x on a synthetic benchmark, and a race caught in review

Linus Torvalds posted a 10-patch kernel series written with Claude Code on October 13, measuring 13.3M to 304M reads/s at 64 threads. Reviewers found a race.

A bar chart comparing reads per second before and after the patch series for 1 thread, 8 threads and 4 threads on separate cores

On October 13, Linux creator Linus Torvalds posted a page-cache patch series to the kernel mailing list under the subject “Improve page refcount scalability” — a series whose commit messages credit an LLM coding assistant. His own numbers, written into the commit log, show 16-byte pread() calls on a 32-core, 64-thread Ryzen Threadripper 3970X going from 13.3 million reads per second to 304 million, with kernel cycles per read falling from 19857–19939 to 735–736. The series has not merged: reviewers found a race condition in the read path before it could be.

Key points

  • The series is ten commits that defer a folio’s final free until after an RCU grace period. Each one carries an Assisted-by: LLM tag. The Signed-off-by lines are human: the first eight commits have Torvalds alone, and commits nine and ten have Kiryl Shutsemau above Torvalds.
  • The “23x” comes from the mail Torvalds sent to the list on October 13: “I see a 23x performance increase on my Ryzen threadripper.” It is a synthetic load, 64 threads rereading the same page, and he says in the same paragraph that any real-life impact will be “much much less.”
  • Meta kernel maintainer Kiryl Shutsemau raised the race on October 13: in filemap_read_rcu_batch(), a folio replaced underneath the reader plus an i_size extension can hand userspace data that was never written.

Background

The bottleneck had been sitting on the mailing list for more than two years. Torvalds laid out the history himself in the mail he sent to the list on October 13: Matthew Wilcox raised it in 2024 from a customer workload; Torvalds had “a very rough first draft” in that same thread that he ran locally for a year and a half “until people pointed out just how broken it was”; Shutsemau had a slightly fixed-up version almost exactly a year ago that “too had problems”; Ilya Gladyshev brought a different approach, now at version 6, which “still has some outstanding known fundamental issues.” One of the main topics at this year’s kernel maintainer summit was going to be LLM use in kernel development, so Torvalds decided to try solving it with an LLM.

The patch count differs across coverage — 8 or 10 — and both are right, at different moments. On the evening of October 11, Phoronix’s Michael Larabel was waiting for Linux 7.3-rc7 and refreshing Torvalds’ repository when a branch named noref-filemap-read-with-llm appeared, based on 7.3-rc6 with eight commits. What went to the list on October 13 was the ten-commit rcu-free-v3. The revision moved the PG_rcu_free mark from “when a folio leaves the page cache” to “when the read path sees a folio that reads keep coming back to,” and added vmstat counters plus a forced free before the OOM killer.

Torvalds’ stance on AI has moved in steps. ZDNet’s Steven Vaughan-Nichols traced the arc: in December 2023 Torvalds called AI “a tool that can help us be better at what we do” while his interest was in bug-finding; by late 2025 he described himself as “a huge believer in AI as a tool”; on October 9, 2026, in conversation with Dirk Hohndel at Open Source Summit Europe in Prague, he said “I used to think it was just not very good — but now I’m at the point where I actually really like using AI,” adding that “you need to be very careful using AI when you’re doing something real and important.”

The facts

The cost of one read() sits on a shared cache line. filemap_get_read_batch() takes a folio reference with a lock cmpxchg and filemap_read() drops it with a lock decl, so every read writes the same struct page line twice. On Torvalds’ laptop (an i7-8565U, four cores and eight threads), with eight threads doing 16-byte pread() on one page, that line accounted for 99.92% of the load HITMs. The series removes the reference from the fast path entirely: a folio leaving the page cache goes back to the allocator only after an RCU grace period, so a reader inside an RCU read-side section copies straight from the page to the user buffer — no reference, no on-stack bounce buffer, no seqcount, no check after the copy, no limit on read size.

BenchmarkBeforeAfter
64 threads, reads/s13.3 M304 M
64 threads, cycles/read19857–19939735–736
32 threads, one per core, reads/s13.4–13.7 M236–237 M
8 threads on 8 cores, reads/s16.7 M60.5 M
1 thread, cycles/read503–505479–492

Every row above is from the Numbers section of the mm/filemap: read from the page cache without folio references commit on rcu-free-v3: Threadripper 3970X, one socket, btrfs, a one-page file, one file descriptor per thread, three five-second runs each, “before” being 7.3-rc6. Torvalds’ reading of the 64-thread row is that a read of a shared file now costs the same with a thread on each of 32 cores as it does alone, where before it cost twenty times as much.

The laptop figures (i7-8565U, ext4, mitigations off, CONFIG_HARDENED_USERCOPY off) come from the eight-patch commit: eight threads went from 9.9–10.4 M to 30–33 M reads/s with cycles per read dropping from 2937–2975 to 725–726; one thread went from 452–454 to 408–409; perf c2c load HITMs fell from 30538 to 101. The cost is recorded in the same place: a read into a user page that is not yet mapped takes one extra failed exception, so a 16-byte single-thread read goes from 4117–4188 cycles to 6543–6593. The rcu-free-v3 commit gives a different pairing for the same regression, 4397–4428 to 6022–6296 — the two builds are not the same measurement, and secondhand coverage that prints “about 4,150 to 6,550” mixes them.

The Tools section is why this became news. It sits at the end of the eight-patch commit: “The code, the test programs, the review behind the list above and the first draft of this text were done with an LLM coding assistant (Claude Code) under my direction. The measurements were run on my machine.” So the code, the tests, the review behind the known-problems list and the first draft of the text came from Claude Code; the measurements, the judgment and the signature did not. Every commit on rcu-free-v3 carries an Assisted-by: LLM tag; the first eight have only Torvalds in Signed-off-by, while commits nine and ten (mm: count the pages waiting for a grace period and free them before OOM and mm: count the runs of the expedite work) put Kiryl Shutsemau above him. Documentation/process/coding-assistants.rst says AI agents must not add Signed-off-by tags because only a human can certify the Developer Certificate of Origin, and lays out a nine-step procedure for AI-assisted bug finding and fixing.

What others say

On October 13, Shutsemau sent one mail with the full interleaving and a patch: CPU0 runs filemap_read_rcu_batch(), gets folio A from xas_load(), confirms PG_rcu_free, sees xas_reload() still returns A; CPU1 meanwhile evicts A with fadvise(FADV_DONTNEED) (its free is deferred, so A stays valid), then a write() repopulates the page cache and extends i_size; CPU0 only now reads i_size, so copy_page_to_iter(A) hands over data from the old folio “that user never wrote.” Torvalds replied the same day suggesting the i_size read move up and the two folio-validity checks merge, and asked the more consequential question in the same mail: “Would you be willing to take this whole series over? I’m going to be on vacation starting Friday and do the merge window next week, and realistically won’t have time for it.” On October 14, Shutsemau explained why i_size could not move up before (the uptodate bit only means something after the reload), agreed to the change, and insisted the uptodate check in filemap_read_rcu_can_copy() stay: “The flag only says the folio was uptodate when it was marked. Some filesystems clear PG_uptodate on a folio that stays in the page cache, and that can happen after the folio got the flag.”

Memory reclamation is the second argument. Matthew Wilcox wrote “I don’t like the PG_rcu_free flag,” proposing a page type instead, or making inactive-list folios immediately freeable after one RCU generation; Torvalds rejected both on October 13, arguing the flag has to be set while a folio can still be mapped into userspace and that reclaiming only from the inactive list would not cover truncate and hole punch — “truncate() actually will be the common case in some situations.” Wilcox also credited Shutsemau with finding a workload that “confirmed my fears.” Shutsemau then proposed restricting the flag to 64-bit systems, which Arm’s David Hildenbrand backed (“limiting this functionality to 64bit makes a lot of sense”). Harry Yoo’s concern was that the kernel must bound how much memory the page cache submits to RCU; Torvalds answered that his first approach was to throttle the places that set the bit, but that he worried about slowing down truncation of large files — the very operation freeing pages — so he ended up expediting RCU when many pages are in flight, and measured the pgfree_rcu* counters after a desktop boot with Chrome open on 18 tabs and after a full make allmodconfig -j60.

LWN (Jonathan Corbet, October 14) filed it as a brief calling it “an order-of-magnitude speedup for a read()-heavy benchmark” and noted review had already found a race condition. On Hacker News that LWN link drew 122 points and 108 comments, and the reaction split in two directions. tombert wrote “I use AI like most software people do nowadays, but I have to admit that I’m a little surprised that Linus is onboard with it.” Separately, a top-level comment from vatsachak read “So many people’s take away from this story is that Linus used Claude to improve the Kernel therefore anyone can,” and atniomn answered him “Don’t know why you’re getting hammered here. There’s a clear skill factor in piloting LLMs.” mono442 attacked the LLM-drafted prose directly (“That llm yapping is annoying to read”). In Chinese, InfoQ published the only write-up we found (author Tina, October 16); oschina, Zhihu and ITHome have not followed.

Our take

What matters here is that a long-standing concurrency problem got solved. The bottleneck was raised in 2024, Torvalds ran his own broken version for 18 months, and human effort was not converging on it — the LLM appears to have compressed two years of engineering into one series. It also leaves an unusually complete record: the Tools section names exactly what the assistant did (code, tests, review, first draft of the text) and what it did not (measurements, final judgment, signature). That same eight-patch commit message lists ten known problems, among them that the allocator cannot see pages waiting on a grace period (their refcount is 0, they are not PageBuddy, and they sit on no pcp list and in no counter), that alloc_contig_range() now returns -EBUSY for a range that held page cache, that s390’s __make_folio_secure() freezes the refcount where a reference would stop it and an RCU reader does not, and that xfstests and KASAN were never run. That level of self-reporting is rare in a pre-merge series, and it is why the review could be efficient. The ten-item list lives in the eight-patch commit; the matching rcu-free-v3 commit carries only the Numbers table and the trailers.

There are two things a working developer can take from it. The mechanism: move the atomic reference-count traffic off the hot path and trade deferred freeing for lockless reads. That shape is not specific to the page cache — any “many cores read one object, take and drop a reference, and thrash one cache line” problem can be pulled apart the same way. And the process: separating Assisted-by: LLM from Signed-off-by means the signer owns the content, and the DCO rule that an agent may not sign puts the responsibility back on a person. This site has covered the opposite policy twice — QGIS moving from a ban to a ban on all repo text and Google freezing its OSS bounty over AI report spam. The kernel series sketches a third path: use the tool, sign it yourself, review it in public.

The limits deserve the same space. The 23x is synthetic — 64 threads rereading one page, which no real workload resembles, and at the end of the October 13 mail Torvalds wrote “that’s not a real number in the sense that no real load will ever see it.” Single-thread reads on his laptop improved about 10%, reads into unmapped user pages got slower, and in the eight-patch commit message he calls the memory pinned by deferred frees “the part of this series that is least solved.” As of October 16, rcu-free-v3 still sits in Torvalds’ own tree: master’s mm/filemap.c and include/linux/page-flags.h contain no rcu_free or PG_rcu_free, so nothing has merged. Torvalds has asked Shutsemau to take the series over, with the Linux 7.4 merge window as the target. The New Stack reported that “Torvalds has handed further development to Kiryl Shutsemau”; his actual mail asks “Would you be willing to take this whole series over?” — a question, not a handoff.