SysadminNews

Linux 7.3 Stops MGLRU Evicting Your Hot Binaries

On this page
  1. The behaviour that was missing
  2. The number, and what it is worth
  3. The wider problem this points at
  4. What to do with this
  5. Sources and further reading

One of the last memory management batches merged into Linux 7.3 fixes a behaviour difference that has been quietly costing performance on memory constrained machines. Classical LRU protects mapped executable file pages so that hot code stays resident and the system does not thrash reading it back in. MGLRU, the newer reclaim implementation, has been less reliable about that, and reclaimed those pages more readily. A series from Baolin Wang at Alibaba promotes mapped executable folios after their first use, and on a deliberately memory starved test the system time for a 32 job kernel build dropped from 9248 seconds to 7861 seconds. That is a fifteen percent cut on a workload that was doing nothing but fighting for RAM.

The short answer

A patch series from Baolin Wang at Alibaba, merged in one of the last memory management batches of the Linux 7.3 window, makes MGLRU promote mapped executable folios after their first use. Classical LRU already protected those pages so that hot code stays resident instead of being read back from storage under pressure, and MGLRU had been less reliable about it. On a 32 core Arm server held to a 2GB memory accounting limit while running a 32 job kernel build, system time fell from 9248 seconds to 7861 seconds. No tunable to set: the behaviour applies wherever MGLRU is the active reclaim path.

15%less system time on the memory starved test
2GBthe memory limit used to force the contention
Linux 7.3the release the change was merged into
Answer card summarising the Linux 7.3 MGLRU change: a patch series from Baolin Wang at Alibaba promotes mapped executable folios after first use so that hot code resists reclaim the way classical LRU already allowed, cutting system time on a memory starved 32 job kernel build from 9248 seconds to 7861 seconds.
The MGLRU change in Linux 7.3, in short. PNG

If you have ever watched a container under a tight memory limit spend more time in the kernel than in your application, this patch is aimed at you. The mechanism behind that symptom is boring and specific, and Linux 7.3 addresses one part of it.

The behaviour that was missing

Classical LRU treats mapped executable file pages as worth protecting. That bias is deliberate. Those pages hold the code your processes are executing right now, so evicting them frees very little memory and guarantees an immediate read back from storage, which under sustained pressure turns into the thrashing loop where the machine spends its time paging code rather than running it.

MGLRU, the newer generational reclaim implementation, has not been as reliable about that protection. Executable pages were reclaimed more readily than the classical path would have allowed, and the difference showed up exactly where you would expect: on machines with no memory headroom.

Baolin Wang's series changes that by promoting mapped executable folios after their first use, so they move out of reach of the immediate reclaim scan instead of being treated like any other file backed page.

The number, and what it is worth

The measurement comes from a deliberately hostile setup: a 32 core Arm server, the memory accounting limit pinned at 2GB, and a 32 job kernel build running inside it. That is a machine configured to do nothing but fight over memory.

Comparison chart of system time for a 32 job Linux kernel build on a 32 core Arm server with a 2GB memory accounting limit: 9248 seconds before the MGLRU executable folio promotion patches and 7861 seconds after them, a reduction of about fifteen percent.
System time on the memory starved kernel build, before and after. PNG

System time went from 9248 seconds to 7861 seconds. That is roughly a fifteen percent reduction, on the part of the workload that was pure kernel overhead.

Read that as a demonstration of the mechanism, not as a forecast. On a machine with comfortable headroom, reclaim barely runs and this change does close to nothing. The setups that will feel it are the ones shaped like the test: containers with tight limits, oversubscribed virtual machines, CI runners sized to a RAM budget rather than to the workload, and anything running on hardware bought when memory prices were more forgiving than they are now.

The wider problem this points at

The interesting part is not the patch, it is why the patch was necessary at all.

The kernel currently carries two separate eviction algorithms in the same file. At the 2026 Linux Storage, Filesystem, Memory Management and BPF Summit in May, Shakeel Butt made the case that this is not sustainable: mm/vmscan.c has grown past eight thousand lines, a large share of it MGLRU specific code duplicating logic that already exists on the traditional path, and every fix, optimisation or feature either gets implemented twice or reaches only half of users. Lorenzo Stoakes suggested modularising the code as a first step toward sharing more between the two.

This series is a textbook case of the dynamic Butt described. A protection that classical LRU has had for years had to be built again, separately, for MGLRU, and the machines running MGLRU carried the gap in the meantime. The stated direction is unification rather than picking a winner, and this patch does not change that plan, it just illustrates why it exists.

What to do with this

Nothing, in the sense that there is no tunable to set. The behaviour is internal to MGLRU and applies once you run a kernel that has it.

Something, in the sense that it is worth knowing which reclaim path your machines are actually using before you attribute any memory behaviour to either. The runtime control is /sys/kernel/mm/lru_gen/enabled, where 0x0001 is the main MGLRU switch and the further bits govern accessed bit clearing in leaf and non-leaf page table entries. Build time it depends on CONFIG_LRU_GEN and CONFIG_LRU_GEN_ENABLED.

Linux 7.3 has been a busy release for memory and storage generally, including reduced zsmalloc and KSM lock contention, a much cheaper in-kernel zstd path, and DAX support for fabric attached memory through famfs. If you run anything memory constrained, this cycle is worth reading properly rather than skipping to the next LTS.

Sources and further reading

Frequently asked questions

What is MGLRU and how do I know whether I am using it?

MGLRU is the multi-generational LRU, a newer implementation of memory reclaim that sorts pages into generations rather than the two list active and inactive scheme used by the classical LRU. It has to be built in with CONFIG_LRU_GEN and can be enabled at build time with CONFIG_LRU_GEN_ENABLED. At runtime the control lives at /sys/kernel/mm/lru_gen/enabled, where 0x0001 is the main switch and the further bits control accessed bit clearing in leaf and non-leaf page table entries. Reading that file is the quickest way to answer the question on a running machine, and it is worth doing before attributing any reclaim behaviour to one implementation or the other.

Why do executable pages deserve special treatment during reclaim?

Because evicting them is unusually expensive relative to how little memory it frees. Mapped executable file pages are the code your processes are currently running. If reclaim takes them, the next instruction fetch has to read them back from storage, and under memory pressure that pattern repeats, which is the classic thrashing loop: the system spends its time paging code in and out rather than doing work. Classical LRU has long biased against reclaiming those pages for exactly that reason. The fix here is not a new idea, it is bringing MGLRU into line with a protection the older implementation already had.

How significant is the 9248 to 7861 second result in practice?

Treat it as a demonstration of the mechanism rather than a number you should expect. Baolin Wang produced it on a 32 core Arm server with the memory accounting limit set to 2GB while running a 32 job kernel build, which is a deliberately extreme setup designed to keep the machine permanently short of memory. The drop from 9248 to 7861 seconds of system time is about fifteen percent, and it is real, but a machine with comfortable headroom will see close to nothing because reclaim is barely running. The setups that will feel it are the ones that resemble the test: containers with tight memory limits, oversubscribed virtual machines, and build farms sized to the RAM budget rather than to the workload.

Does this mean MGLRU was a mistake?

No, but it does illustrate a real cost that kernel developers have been discussing openly. At the 2026 Linux Storage, Filesystem, Memory Management and BPF Summit, Shakeel Butt argued that shipping two separate eviction algorithms in the same file is unsustainable, since mm/vmscan.c has grown past eight thousand lines with a large share of it specific to MGLRU, and every fix has to be made twice or it only reaches half of users. This patch series is a good illustration of that dynamic: a protection that existed on one path had to be reimplemented on the other. Work is under way to unify the two rather than to pick a winner.

Do I need to change any configuration to benefit from this?

No. This is a behavioural change inside MGLRU, so it applies automatically once you run a kernel that contains it and MGLRU is the active reclaim implementation on your system. There is no new tunable, and there is nothing to enable. The only decision worth making is whether MGLRU is the right choice on a given machine at all, and that question is unchanged by this patch beyond removing one specific reason to answer no.