Linux has been able to give a process a guaranteed slice of video memory through the device memory cgroup for a while, and it has quietly failed to honour it. If unprotected applications got there first and filled the VRAM, a protected allocation would give up and land in slower system memory instead of pushing anyone out. Natalie Vock of Valve's Linux graphics team spent eight rounds of review fixing that, and the result is queued for Linux 7.3. TTM now evicts unprotected buffers to make room. The change touches AMDGPU, Xe and Nouveau, and it matters most on the machines with the least VRAM to spare.
The short answer
Linux can already hand a cgroup a protected amount of video memory through the device memory controller, but until now the guarantee was not enforced. When VRAM filled with unprotected buffers, a protected allocation would fall back to system memory rather than displacing anything. Natalie Vock of Valve's Linux graphics team changed TTM so it evicts unprotected buffers to make room, with care taken to avoid buffers ping-ponging across the bus. It is queued for Linux 7.3, applies to AMDGPU, Xe and Nouveau, and only does anything if you actually set a protection.
A guarantee the system records but declines to enforce is worse than no guarantee, because you plan around it. That is roughly the state the device memory cgroup has been in: you could tell the kernel that a workload was entitled to a floor of video memory, the accounting would agree with you, and when the moment arrived to act on it the kernel would find a reason not to. The series Valve has landed for Linux 7.3 closes that gap.
The polite fallback that quietly cost you VRAM
TTM is the shared memory manager underneath the DRM drivers, and one of its jobs is deciding whether a buffer lives in VRAM or in GTT, the system memory a GPU reaches across the bus. Falling back from the first to the second is normal and usually correct, because an allocation that succeeds slowly beats one that fails.
The defect was that the fallback did not distinguish between an allocation with a claim and one without. Unprotected buffers would fill the card. A protected allocation would arrive, find no room, and take the slow path rather than displacing anything, even though the memory occupying the space had no entitlement to it at all. Natalie Vock's description of the fix is that applications can now actually use all the memory protection awarded to them by the system, which is a polite way of noting that previously they could not.
The new behaviour is direct: when a protected allocation cannot fit, TTM tries evicting unprotected buffers from the domain to make space, instead of backing off immediately.
Why it took eight revisions
Because the naive version of this patch makes things worse. If a protected allocation evicts an unprotected buffer, and the unprotected workload immediately touches that buffer and pulls it back, you have not resolved contention. You have converted it into bus traffic, and both workloads now run slower than they did under the old behaviour that at least left things where they were. That is the ping-pong the series had to design around, and it is the sort of problem that only shows up under review by people who have watched it happen.
The other reason for the long cycle is blast radius. TTM is common code. A change to how it decides to evict is a change that AMDGPU, Xe and Nouveau all inherit, across every card those drivers support, which is a good deal of the Linux graphics install base. Getting that reviewed properly is slower than getting a driver specific workaround merged, and it is also the right call, because the alternative is three divergent implementations of the same policy.
A smaller item travelled with the series: an artificial 64 megabyte limit in the UDMABUF code is removed. Unrelated to the eviction work, but in the same set.
Who this actually helps
Nobody with plenty of VRAM and one workload. That is worth stating up front, because the shape of this change is easy to over read. If your card is not under memory pressure, no allocation ever fails to fit, and the new eviction path never runs.
Where it matters is the opposite end: an 8 gigabyte GPU running a game while a browser holds a pile of GPU backed surfaces, or a handheld where the system and the graphics unit share one pool and contention is simply the resting state. That is Valve's territory, which explains who wrote the patches. It also matters for anyone partitioning a GPU across tenants, where selling a guarantee the kernel does not honour is a support ticket waiting to happen.
The condition on all of it is configuration. The eviction path only triggers for allocations that carry a protection, and allocations only carry a protection if you set one through the device memory cgroup. A stock desktop with no GPU cgroup policy sees nothing change. If you have been avoiding that knob because it did not appear to do much, Linux 7.3 is the release where it starts doing what it says.
Sources and further reading
- TTM memory management for graphics to be more aggressive with Linux 7.3, Phoronix, August 7, 2026
- Discussion thread on the TTM 7.3 changes, Linux.org
- Phoronix coverage archive for TTM
Frequently asked questions
What is the device memory cgroup actually for?
It is the video memory equivalent of the memory controller you already use for RAM. The device memory cgroup, usually written DMEMCG, lets you carve a GPU's memory into accounted pools and give a cgroup a protected amount, so that a workload you care about has a floor it can rely on rather than competing on a first come basis. The use cases are the obvious ones: a game or a compositor that must not stutter, an inference service sharing a card with batch work, a container platform that sold someone a quantity of VRAM and would like to deliver it. The trouble until now was that protection was advisory in the worst sense. The accounting was correct, the guarantee was recorded, and when the moment came to enforce it the kernel declined. Fixing that is what makes the knob worth setting.
What exactly was broken before this patch series?
The fallback path was too polite. TTM manages the relationship between VRAM and GTT, the system memory the GPU can reach across the bus, and it is designed to fall back from the first to the second when video memory runs out. That fallback is normally the right behaviour, because a slow allocation beats a failed one. The problem was that it fired even when the allocation had a protection guarantee and the memory sitting in VRAM did not. Unprotected buffers would fill the card, a protected allocation would arrive, find no space, and quietly take the slow path rather than displacing anything. As Natalie Vock put it, the change means applications can actually use all the memory protection awarded to them by the system, which is a diplomatic way of saying they previously could not. The accounting had always been right. It was the enforcement that never happened.
What does the kernel do differently now?
When a protected allocation cannot fit, TTM attempts to evict unprotected buffers from the domain to make space instead of backing off immediately. That is the whole change in one sentence, and the subtlety is in avoiding the failure mode it could easily create. Naive eviction produces ping-ponging: the protected allocation pushes an unprotected buffer to system memory, the unprotected workload touches it again and pulls it back, and the two spend more time moving memory across the bus than either spends computing. The series is careful about when eviction is attempted precisely to keep that from happening, which is a large part of why it took eight revisions to land rather than two. The series also removes an artificial 64 megabyte limit in the UDMABUF code, which is unrelated housekeeping that happened to travel with it.
Which drivers and which hardware does this affect?
TTM is shared infrastructure rather than a driver, so the change lands once and applies across the drivers built on it: AMDGPU for AMD graphics, Xe for Intel's newer discrete and integrated parts, and Nouveau for NVIDIA hardware on the open driver. That breadth is the argument for fixing it in TTM rather than in one driver, and it is also why the review was slow, because a behavioural change in common memory management code has to be defensible for every consumer of it. The practical impact is concentrated where VRAM is scarce rather than spread evenly. On a card with 24 gigabytes running one workload, nothing here will ever fire. On an 8 gigabyte GPU, or a handheld with memory shared between the system and the graphics unit, contention is the normal state and the guarantee is the entire point.
Do I need to configure anything to benefit from this?
Yes, and that is worth being clear about, because this is not a free performance patch. The eviction behaviour only applies to allocations that carry a protection guarantee, and nothing has a guarantee unless you configured the device memory cgroup to give it one. If you run a stock desktop with no cgroup policy for GPU memory, your allocations are all unprotected and the change is invisible. Where it pays off is on systems that already partition a GPU on purpose: a gaming handheld image that protects the game's cgroup, a container host that allocates VRAM per tenant, a workstation that guarantees a compositor its working set so the desktop stays responsive while something heavy runs. For those, the sequence is now the sensible one: set the protection, and expect the kernel to enforce it rather than record it.