On October 13, 2026, Linus Torvalds, who leads Linux development, published a file-read speedup patch he had developed with the help of a large language model (LLM) as "rcu-free-v3," a series of 10 patches. In a synthetic benchmark in which many CPUs repeatedly read the same data, throughput improved by roughly 23x. However, code review after publication uncovered a race condition: even with the mechanism that prevents memory from being freed, a read could return data that had not actually been written. A proposed fix followed on October 14, and a handoff of the work was agreed, so verification toward practical use continues.

The initial version, released on October 10, was a prototype that showed roughly a 3x improvement with 8-thread reads on a laptop. The new multi-core measurements reveal the conditions under which the speedup is especially large. They also highlight a challenge: how to guarantee data safety in a design that skips conventional reference counting.

AD

About 23x at 64 threads, only a small gain at 1 thread

The results Torvalds published in the read-path change commit were measured on a 32-core, 64-thread AMD Ryzen Threadripper 3970X. In the test, each thread used its own file descriptor to repeatedly read 16 bytes at a time from the start of the same one-page file on btrfs, using pread(). Each run lasted 5 seconds, and each condition was run three times.

Threads used for reads Before (million reads/sec) After (million reads/sec)
1 thread 7.4–7.6 7.7–7.8
1 thread on each of 8 cores 16.7 60.5
1 thread on each of 32 cores 13.4–13.7 236–237
64 threads 13.3 304

At 64 threads, reads rose from 13.3 million to 304 million per second, a gain of about 22.9x. The improvement at 1 thread is much smaller, about 1.01–1.05x. These ratios were calculated from the values measured in the commit published on October 13: 304÷13.3 for 64 threads and 7.7÷7.6 to 7.8÷7.4 for 1 thread. Note that the 1-thread range combines the maximum and minimum of the listed measurements arithmetically; it is not a statistical confidence interval.

In the old implementation, adding more reader CPUs hit a performance ceiling, and the number of reads at 32 and 64 threads was actually lower than at 8 threads. After the change, performance rises substantially up to 32 cores. In other words, the improvement does not so much make each individual read dramatically faster as reduce contention when many CPUs access the same data, which is where it has its large effect.

That said, this measurement is a synthetic benchmark under extreme conditions that deliberately concentrate access on the same small region of data. Torvalds himself explained in his post accompanying the patch that gains in real workloads would be far smaller. It does not mean that entire applications such as databases or web servers would become 23x faster.

The comparison conditions also deserve caution. The "before" measurement used Linux 7.3-rc6, while the "after" measurement applied the full patch set on top of it with the same kernel configuration, using an early-stage implementation. The code at the time of measurement also differs in part from the published code in where conditions are checked. The result does not guarantee final performance after the fixes are complete, and it cannot be directly compared with the "roughly 3x" result recorded on the earlier laptop to conclude that the improvement has grown by some further multiple.

Skipping reference counts and delaying memory reuse with RCU

In Linux's conventional read path, when copying data out of the page cache, the kernel increments the reference count of the "folio," the unit of memory management, and decrements it once the copy finishes. This mechanism prevents the target memory from being freed mid-read. However, even a read that does not modify file contents must update a shared reference count.

When many CPUs read the same folio, this reference count becomes a performance bottleneck. The cache line holding the counter has to be passed between CPUs as each updates it, so the cost of updating bookkeeping data exceeds that of copying just 16 bytes. In the 64-thread measurement, the number of in-kernel instructions per read dropped from 1,094–1,101 to 959, while CPU cycles consumed fell sharply from 19,857–19,939 to 735–736. The effect of eliminating contention between CPUs was far greater than that of the reduction in instruction count.

The proposal introduces a mechanism for frequently read folios that waits until the RCU (Read-Copy-Update) grace period has elapsed before actually freeing the memory. As explained in the official Linux documentation, RCU is a technique that separates removing an item from a data structure from actually reclaiming its memory. Memory reuse is delayed until readers that were already reading at the moment the item was removed have left their protected read-side section.

With this mechanism, reads that meet the conditions can copy data directly into the user-space buffer without acquiring the folio's reference count. Rather than making the reference-count update itself faster, the design removes the update from the frequently used read path. This avoids the situation in which multiple CPUs fight over the same bookkeeping data.

Not every read can use the new fast path, however. If the target data is not in the page cache, or if the folio is not subject to deferred freeing, the read falls back to the conventional path. The same applies when the destination user-space memory is not yet available and a page fault must be handled, because waiting associated with page-fault handling is not permitted inside an RCU read-side section.

Falling back to the conventional path comes at a performance cost. In the Threadripper measurements, the CPU cycles for a 16-byte read that triggers a page fault at the destination rose from 4,397–4,428 before the change to 6,022–6,296 after it, because the read must fail on the fast path, return to the conventional path, and handle the page fault again. While reading shared data from many CPUs becomes much faster, under some conditions the processing load is higher than before.

AD

A race condition that RCU-protected memory did not prevent

Linux developer Kiryl Shutsemau pointed out on October 13 that a race condition exists in filemap_read_rcu_batch(), and laid out the specific sequence of operations that triggers the problem. The issue is that even when old memory is kept from being freed by RCU, the consistency between the data being read and the file size can be lost.

Step Reading CPU Another CPU
1 Obtains source folio A and confirms it is in the page cache
2 Removes folio A via a notification that the cache is no longer needed; actual freeing is deferred by RCU
3 Places a new folio through a write and extends the file size
4 Obtains the extended file size
5 Copies data from the old folio A based on the obtained file size

When processing follows this sequence, the reader combines the old folio A with the updated file size. RCU has not allowed folio A's memory to be reused for another purpose, but the newly written data does not exist there. As a result, the reader may copy content that was never written. In other words, what RCU guarantees is the lifetime of memory during a read, not that the data in that memory matches the current file contents.

The first proposed fix was to re-check, after obtaining the file size, that the source folio still exists at the same position in the page cache. Torvalds responded with a proposal to avoid duplicate checks by also changing where the file size is read. In the revised proposal published the next day, the 14th, the state is checked in the order of the flag indicating deferred freeing, the file size, and then the copy source in the cache, with the necessary memory-ordering controls added.

The code also retains a check on whether the data about to be read is still valid, because even if the target folio meets the conditions for deferred freeing, the filesystem side may change its state afterward. Even though the fix itself is small, confirming its correctness requires considering cases in which page cache replacement and file updates happen concurrently.

This review served as another reminder that a performance gain in a benchmark cannot guarantee concurrency safety. There is, however, no evidence to conclude that the race condition arose because an LLM was used. What matters is that putting the proposal through public review made the problem concrete and moved the discussion toward a fix.

Three-part safeguard for memory reclamation; effect under real loads unverified

In this design, in exchange for reducing reference-count updates during reads, memory reuse must wait until the RCU grace period has elapsed. If a large amount of memory awaiting release accumulates, it could in turn harm memory allocation. In a reply explaining the countermeasures for memory awaiting release, Torvalds said the latest version combines the following three mechanisms:

  • Only frequently read folios are subject to deferred freeing, which prevents the mere truncation of a large file from generating a large amount of memory awaiting release.
  • When memory awaiting release grows on a given CPU, the system prompts the RCU grace period to end early.
  • The side allocating memory also recognizes memory awaiting release and waits for its reclamation to complete before judging that memory is exhausted.

Simply slowing down file truncation would not solve the problem. Torvalds explained that throttling the process that is trying to free memory could instead interfere with dealing with memory shortages. What is needed is a mechanism that properly tracks memory that will soon become reusable and waits for its reclamation when necessary. Because the design extends memory lifetimes for speed, its impact on overall memory management must be evaluated carefully.

Discussion also continues on how frequently a folio should be read to qualify, and how much of a performance gain real workloads would see. In a review on October 14, developer Pedro Falcato questioned the validity of the criterion for deciding a folio is read frequently, and asked for confirmation of how many pages would qualify under realistic loads. He also expressed the view that, unless a large effect can be confirmed outside synthetic benchmarks, the change would not be worth making such a large modification to virtual memory management.

Future evaluation will therefore need to measure not just simple read counts but how much CPU contention is actually reduced in real applications. It must then confirm that the performance benefit outweighs the waiting time for memory reclamation and the additional processing load. At this point, it is not appropriate either to treat problems pointed out in the initial version as defects of the latest version, or to judge them resolved simply because countermeasures were added.

AD

Disclosure of AI use and responsibility for code correctness

In the description of the initial version, Torvalds disclosed that he used Claude Code in this work. He said it was used not only to write code and test programs but also for review to sort out problems and for drafting the explanatory text. All work, he explained, was done under his own direction, and he ran the performance measurements on his own machine. It has not been made clear how much the use of an LLM shortened development time, or how much it contributed to individual changes.

The problem this speedup targets was in fact raised in 2024, prompted by a real user's workload. Multiple Linux developers have since tried to improve it in different ways, and this effort is an extension of that. The sequence of events, in which a prototype built with an LLM showed promising performance, experts found a race condition after publication, and a fix was then considered, cannot be treated as a result of AI alone solving the problem.

On October 13, Torvalds asked Shutsemau to take over the entire patch series, saying that vacation and the following week's merge work would leave him without enough time. Shutsemau accepted the request the next day, the 14th, while presenting a fix. Even when an LLM helps write code, developers are the ones who explain that the change is correct, respond to review, and maintain it over time. The episode shows that the efficiency of generating code and the process of ensuring software reliability are separate matters.

Around the same time, the way AI use is disclosed in Linux kernel development was also revisited. In response to the second version of a patch from Sasha Levin proposing removal of the Assisted-by tag, which indicates AI assistance, documentation maintainer Jonathan Corbet replied on October 14 that he had applied it. However, this is a documentation change for docs-next, and does not mean it was immediately reflected in all published documentation or in stable kernels.

Handling of the tag that discloses AI assistance is also a separate matter from responsibility for submitted code. Linux's guidelines on tool-generated content require submitters to understand the entire change and be able to answer questions raised in review. They also emphasize explaining the tools used, the parts the tools influenced, and the testing performed, and state that changes the submitter cannot explain should not be submitted. Removal of the Assisted-by tag cannot be interpreted as relieving submitters of that responsibility.

As of October 17, the mainline Linux file-read code had not yet incorporated this speedup. Going forward, the implementation with the race condition fixed will be tested to see whether real workloads gain enough performance, and whether it can maintain consistency with memory reclamation and concurrent file updates. If it meets these conditions, the proposal could become a strong way to remove the ceiling on shared-file read performance in multi-core environments.