Linus Torvalds Had Claude Code Speed Up Linux File Reads by Up to 23x. A Human Found the Critical Bug It Missed

torvalds-claude-code-linux

Linux kernel developers are still debating how far to trust code written by AI. Meanwhile, Linux creator Linus Torvalds asked Anthropic’s AI agent Claude Code to tackle a problem that kernel developers had been unable to solve for more than two years: under his direction, the agent wrote experimental patches for the page cache, the part of RAM where the kernel keeps file data. If the patches are merged, Linux will serve data faster to programs that read the same file from many threads, and the more CPU cores a machine has, the bigger the gain. In a synthetic test on a powerful workstation, the patches made reads of a single file up to 23 times faster. But just four hours after the series was posted, Linux kernel developer Kiryl Shutsemau of Meta found a bug in it: a race condition that the tests written by Claude Code had missed. The story is a telling one: AI helped move a problem that people had been stuck on for years, but it is still too early to trust AI with kernel development entirely.

Key takeaways

  • Torvalds gave Claude Code a problem that kernel developers had failed to solve for two and a half years: the model wrote the code and the tests, while Torvalds chose the approach, directed the work and ran the benchmarks himself.
  • The speedup was about 23× in a synthetic test on an AMD Ryzen Threadripper workstation with 64 reader threads and about 3× on a Core i7-8565U laptop with eight. With the CPU’s default security mitigations enabled, the same test on the reworked version shows about 4.5× on ext4, and real workloads will gain even less.
  • Four hours after the series was posted, Shutsemau found a race condition in it that the tests written by Claude Code had missed. Torvalds then handed the series over to him.
  • The patches are experimental: the first version is in the noref-filemap-read-with-llm branch, while the rcu-free-v3 series and its discussion are on the LKML mailing list. Shutsemau posted a reworked version on October 19; the code has not been merged and will not make it into Linux 7.4.

Reading a file came down to a single counter

For two and a half years, Linux developers could not fix one problem: when many threads read the same file at once, the kernel slows down. Matthew Wilcox, a Linux kernel developer at Oracle, raised the issue in 2024. According to Wilcox, a small customer had a program that read a file in 64-byte chunks, and at such small sizes a single bookkeeping counter noticeably slowed it down.

When file data is already in the page cache, the kernel does not need to read it from disk. But before copying the data, the kernel increments the reference count on the folio – a block of one or more memory pages – and decrements it afterwards. That is how the kernel marks the memory as still in use and not yet safe to free.

With a single reader, this costs almost nothing. But when many threads read the same file, the CPU cores keep passing this counter back and forth and spend more time waiting than reading. These transfers show up as load HITM events: one core needs data that another core has just modified in its own cache. Torvalds later measured the scale of the problem: in his eight-thread test, the cache line holding the counter accounted for 99.92% of these events.

Simply dropping the counter is not an option: the page could then be freed and reused for other data in the middle of a copy. Torvalds, who has led kernel development since 1991, posted a rough draft fix to the developers’ mailing list back then. The draft worked well enough that, as Torvalds writes, he used it on his own machine for a year and a half, until other developers showed how broken it was. In the fall of 2025, Shutsemau tried to finish that draft and Ilya Gladyshev took a completely different approach, but both, according to Torvalds, still had problems.

According to The New Stack, earlier solutions copied data without taking the counter and checked afterwards that the copy was still valid. But the check missed some races – for example, when a page was freed and a new one took its place in the cache. That is where every attempt stalled.

How Torvalds tackled the problem with Claude Code

In the end, Torvalds came back to the problem himself – and this time he did not work alone. Until then, he had treated AI as a useful tool and nothing more: in May he admitted that he gets angry when he hears that AI writes “99% of code”; in July he wrote that Linux is not an anti-AI project, although no one is required to use such tools; and in August AI helped him debug a driver. The trigger was the kernel Maintainers Summit in Prague on October 8: LLM use in kernel development was one of its main topics, and Torvalds decided to see whether a model could help him finally get the job done.

He came at it from a different angle: instead of catching the race after the copy, he decided to remove its cause. Pages that are read this way are no longer freed right away but with a delay: the RCU mechanism waits until every read that has already started is finished. Since the memory cannot be given to other data in the middle of a copy, the fast read path no longer needs the counter.

Torvalds handed the implementation to Claude Code: the model produced the code, the test programs, a review of the open problems and a first draft of the cover letter. Torvalds made no secret of it. He named the branch noref-filemap-read-with-llm, and in the commit message he wrote that the code, the test programs and the first draft of the text “were done with an LLM coding assistant (Claude Code) under my direction.” He ran the benchmarks himself, on his own machine.

Michael Larabel of Phoronix spotted the first version – eight patches in the noref-filemap-read-with-llm branch – in Torvalds’ repository on October 11. Two days later, Torvalds brought a reworked series of ten patches to LKML – the rcu-free-v3 branch.

Benchmarks and their limits

Torvalds tested the first version on a laptop with a Core i7-8565U and the reworked one on a workstation with an AMD Ryzen Threadripper 3970X, a many-core workstation CPU that runs 64 threads at once. The more cores fight over a single counter, the more each read costs: before the patches, a read took about 3,000 CPU cycles on the laptop and about 20,000 on the workstation; after the patches, about 730 on both machines. That is why the workstation saw a much bigger gain.

Test Before After Result
Threadripper 3970X workstation, 64 threads, rcu-free-v3, btrfs, synthetic test 13.3M reads/s; ≈20,000 cycles per read 304M reads/s; 735 cycles per read ≈23× faster
Core i7-8565U laptop, 8 threads, first version, ext4, synthetic test ≈10M reads/s; ≈2,950 cycles per read Up to 33M reads/s; 725 cycles per read ≈3× faster
Core i7-8565U laptop, first version: 1 thread, 16-byte read into a buffer whose page is not yet in memory ≈4,150 cycles per read ≈6,550 cycles per read ≈1.6× slower

The 23× figure needs a caveat. In the workstation test, all 64 threads read the same small part of a page over and over – the worst case for the old code, and one that almost never happens in real work. That is why Torvalds himself warns that “no real load will ever see it.”

“Cycles per read” is how many CPU cycles the kernel spends on a single read. Torvalds recommended comparing this number because the laptop throttled as it heated up, so reads per second varied from run to run. The laptop ran ext4 with CPU vulnerability mitigations turned off.

The speedup has a cost, too: if the page of the buffer the data is copied into is not yet in memory, the fast attempt triggers an extra CPU exception and the kernel falls back to the old path. Such a read costs more than it did without the patches.

The bug Claude Code’s tests missed

The real test for the patches came not from benchmarks but from code review. Just four hours after the series was posted, Shutsemau, who works on the Linux memory-management subsystem, found a bug in it: a race condition in the read function filemap_read_rcu_batch(). The bug was in code that Claude Code wrote under Torvalds’ direction, and the tests written by the same model missed it. Torvalds himself did not catch it before posting either.

One thread picks a page to read while, at the same moment, another thread replaces that page in the cache and appends to the file. The first thread sees the new file size but reads the old page – including a region the file’s data was never written to. Deferred freeing does not help here: it guarantees that the page will not be handed over to someone else’s data, but not that it still belongs to the file. In essence, it is the same page-replacement trap that tripped up earlier attempts, just in a new form.

The tests did not cover this scenario. In the benchmarks, threads kept reading the same unchanging file, while the bug only shows up if, at that very moment, the page is evicted from the cache and the file is appended to. To catch such a coincidence, you have to know in advance which sequence of events to check.

This time the bug was caught before the code reached the kernel because Shutsemau knew where to look: a year earlier he had tried to finish Torvalds’ draft himself and had seen where earlier solutions broke. Without a reviewer who knows the subsystem this well, the bug could have made it into the kernel.

And the cost of such a bug is high. Linux runs most of the world’s servers and every Android phone, and almost every file read goes through the page cache. Had the patches been merged as they were, a program reading a file that was being appended to – a log or a database, for example – would, in rare cases, receive data that was never in the file, with no way of knowing. Such failures are nearly impossible to reproduce and very hard to track down in production systems.

Shutsemau attached a fix right away: after reading the file size, the kernel checks once more that the page is still in the cache. Torvalds replied in less than an hour, suggesting reading the size earlier and getting by with a single check, and asked Shutsemau to take over the whole series: Torvalds was going on vacation that Friday and had the merge window the following week. Shutsemau agreed and the next day sent a reworked fix in which memory barriers enforce the order of the checks for the CPU.

Meanwhile, reviewers argued about the design of the mechanism itself – the PG_rcu_free flag that marks pages whose freeing is deferred. Wilcox proposed replacing it with a separate page type, but Torvalds objected: a page is marked long before it is freed, including while it is still mapped into a program’s memory, and a page type does not work for that. Shutsemau suggested a compromise: keep the flag for 64-bit systems only, where page flags are less scarce. David Hildenbrand of Arm backed the idea, and in the new version of the series the flag and the whole mechanism are 64-bit only.

When the patches could land in Linux

Shutsemau reworked the series in five days. Linux 7.3 was released on October 18, opening the 7.4 merge window, and the next day Shutsemau posted the new version: 18 patches, seven of them written by Torvalds. The test was the same synthetic one, but Shutsemau ran it with the CPU’s default mitigations enabled: on his machine they add about 400 ns to every read call. With them, 64-thread reads on ext4 got about 4.5 times faster (from 15 to 70 million reads per second), reads on XFS less than twice as fast, and with a single thread there was no difference. Without the mitigations, the ext4 gain grows to 13×. The series is still a request for comments (RFC), with no target kernel version. It will not make it into Linux 7.4: the merge window only takes code that maintainers have already accepted, so the earliest realistic chance is Linux 7.5, which will come out in 2027.

What it means in practice

This story does not settle the debate over AI-written code, but it shows clearly where the line runs today. The roles were telling: Torvalds chose the approach, set the task for the model and ran the benchmarks himself; Claude Code wrote the code and the tests; Shutsemau found the bug and took the series forward; and the memory-management developers will decide whether it goes into the kernel. That matches Torvalds’ own view: anyone who uses AI has to understand the final code, not only the instructions given to the model, otherwise that code cannot be maintained over time.

Hence the lesson for users of Claude Code, Codex and other code generation tools. AI managed to write a solution but did not see all of its weak spots: the bug its own tests missed was found and fixed by people deeply immersed in the kernel code. So you cannot fully trust an AI agent – even when the person giving it the task is Torvalds himself. But the benefit is just as clear: with its help, a problem that had been stuck for two and a half years was quickly turned into a solution that people are now refining.

Torvalds, who is annoyed by talk of AI writing “99% of code,” ended up showing why that number means little: a model can write the code, but a human still has to answer for it.


bnr2mob
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted