freenode
Kernel & Low-Level

Linus rejects per-CPU page tables as general MM design

ARM64 this_cpu_* optimization RFC hits a hard architectural wall over divergent kernel page tables.

Linus Torvalds has again ruled out per-CPU kernel page tables as a general memory-management design, during review of an ARM64 RFC aimed at making this_cpu_*() operations cheaper on non-x86 hardware.

Yang Shi (Ampere) posted a second RFC that would give each CPU its own kernel page-table view so the same virtual address reaches that CPU's local per-CPU data, removing the preempt_disable critical sections that this_cpu_* paths still carry on ARM64. x86 already gets that effect via segment overrides; the series tried to approximate it with divergent page tables, reusing vmalloc mapping helpers against a per-CPU pgd. Christoph Lameter argued the win is real: no restart loops, tighter code, and a path toward per-node data, kernel text replication, and similar tricks on large ARM64 systems.

Torvalds's objection is to codifying that model in core MM. Intentional duplication, he wrote, forces software coherency and locking on updates even when the hardware already keeps TLBs coherent, and he wants no repeat of historical designs (he cited Plan 9's per-thread page tables) that baked those costs into the VM. Limited, architecture-internal use of per-CPU TLB state can be acceptable; making "this is how the VM works" is not.

MM maintainer Lorenzo Stoakes made the same cut from the other direction: the RFC either widens vmalloc beyond init_mm or duplicates kernel page-table logic, and either way core MM inherits TLB sync, KPTI, and related headaches. He and David Hildenbrand pointed at Mark Rutland's arm64-specific series, which attacks the same preempt overhead with a short restart sequence in the style of s390, without new kernel pgds. Jason Gunthorpe called Rutland's approach a neat fit for CPUs that lack x86-style addressing, while still leaving open whether carefully bounded divergent tables might matter later for text replication or multi-socket machines.

The practical fork is clear. A general per-CPU page-table framework for this_cpu_* is unwelcome in core MM; any further work needs either strong data and buy-in to a narrowly contained arch implementation, or the less invasive arm64 path Rutland has already posted.