Linux mm series reworks folio refcounts for read scalability
Optimistic increments replace CAS loops under contended IO; Linus has acked the core change while free-path races stay open.
A sixth revision of a memory-management series aims to lift a scalability bottleneck in how the Linux kernel tracks folio reference counts during contended file reads.
Ilya Gladyshev, with co-development from Ivan Gorbunov, targets the path used when many threads or processes repeatedly try to pin the same page. Today that path must run a compare-and-swap loop so a caller never revives a folio already at zero and headed for free. Under heavy parallel load the loop becomes a serialization point and a source of cache-line bouncing, especially across NUMA nodes.
The redesign splits the counter: negative values mark a frozen or dead folio, zero is only a transient state, and positive values are ordinary live references. With a dedicated frozen bit available, try-get can perform a single optimistic atomic increment and handle failure afterward instead of looping on CAS. Supporting work consolidates the page_ref API behind higher-level helpers, adds frozen-state checks and debug asserts, and trims Google's GVE driver from an INT_MAX pagecnt bias down to the more common USHRT_MAX range so the narrower counter still has headroom.
Gladyshev's earlier will-it-scale numbers on a dual-socket Haswell system (Linux 6.15) showed little change at one thread, roughly 25 percent gains at full socket occupancy, and more than 80 percent when the load crossed sockets. Andrew Morton noted the wins look similar in magnitude to an earlier, abandoned short-read fast path that attacked the same CAS contention; Gladyshev agreed the approaches overlap, though his still leaves some cache-line traffic on the refcount itself.
Linus Torvalds has acked the core reallocation. Correctness of free paths remains under discussion. David Hildenbrand and Zi Yan argue that a race can let one CPU finish a folio while another has already reallocated it, so the final free must be decided from the page's current state rather than the caller's earlier view, and that every free path must go through a common dispatcher. Special cases such as compaction returning unused migration pages to an isolated freelist and virtio-mem fake-offline drops also use the last-reference test and would need conversion. Torvalds concurred that the free logic has to be generic for all pages.
The series is still under review on the linux-kernel list.