Re: [v8 PATCH] arm64: mm: show direct mapping use in /proc/meminfo

From: Yang Shi

Date: Mon Jul 27 2026 - 15:51:18 EST




On 7/22/26 4:31 AM, Will Deacon wrote:
On Tue, Jun 09, 2026 at 05:06:31PM -0700, Yang Shi wrote:

On 6/9/26 2:42 PM, Yang Shi wrote:
Since commit a166563e7ec3 ("arm64: mm: support large block mapping when
rodata=full"), the direct mapping may be split on some machines instead
keeping static since boot. It makes more sense to show the direct mapping
use in /proc/meminfo than before.
This patch will make /proc/meminfo show the direct mapping use like the
below (4K base page size):
DirectMap4K: 94792 kB
DirectMap64K: 134208 kB
DirectMap2M: 1173504 kB
DirectMap32M: 5636096 kB
DirectMap1G: 529530880 kB

Although just the machines which support BBML2_NOABORT can split the
direct mapping, show it on all machines regardless of BBML2_NOABORT so
that the users have consistent view in order to avoid confusion.

Although ptdump also can tell the direct map use, but it needs to dump
the whole kernel page table. It is costly and overkilling. It is also
in debugfs which may not be enabled by all distros. So showing direct
map use in /proc/meminfo seems more convenient and has less overhead.

Signed-off-by: Yang Shi <yang@xxxxxxxxxxxxxxxxxxxxxx>
---
arch/arm64/mm/mmu.c | 200 +++++++++++++++++++++++++++++++++++++++-----
1 file changed, 179 insertions(+), 21 deletions(-)

v8: * Fixed the double accounting per Sashiko
* Responded the review comments from Sashiko
v7: * Rebased to v7.1-rc4
* Changed "dm" to "lm" to follow ARM convention per Will
* Used __is_lm_alias() instead of reinventing a new helper per Will
v6: * Rebased to v7.0-rc3
* Rebased on top of Anshuman's v5 "arm64/mm: Enable batched TLB flush
in unmap_hotplug_range()"
* Used const for direct map type array per Will
* Defined PUD size for 16K/64K even though it is not used per Will
* Removed the misleading comment in init_pmd() per Will
v5: * Rebased to v6.19-rc4
* Fixed the build error for !CONFIG_PROC_FS
v4: * Used PAGE_END instead of _PAGE_END(VA_BITS_MIN) per Ryan
* Used shorter name for the helpers and variables per Ryan
* Fixed accounting for memory hotunplug
v3: * Fixed the over-accounting problems per Ryan
* Introduced helpers for add/sub direct map use and #ifdef them with
CONFIG_PROC_FS per Ryan
* v3 is a fix patch on top of v2
v2: * Counted in size instead of the number of entries per Ryan
* Removed shift array per Ryan
* Use lower case "k" per Ryan
* Fixed a couple of build warnings reported by kernel test robot
* Fixed a couple of poential miscounts
Aha, Sashiko is so fast. 2 comments this time.

#1
Will these updates suffer from data races?
The lm_meminfo array tracks direct mapping statistics and is updated using
non-atomic += and -= operations. These updates are invoked from multiple
independent code paths that do not share a common lock.
For example, runtime page permission changes call
split_kernel_leaf_mapping_locked() which executes under
pgtable_split_lock,
while memory hotplug operations like arch_remove_memory() execute under
mem_hotplug_lock. Because these paths can run concurrently on different
CPUs,
the non-atomic arithmetic could result in data races and lost updates.
Yes, it may race with memory hotplug. I missed memory hotplug for v7
Sashiko. Two options to solve it:

1. Use atomic variables. Make lm_meminfo[NR_LM_TYPE] atomic_long_t, then
manipulate it with atomic ops.
2. Protect it with a spin lock.

The contention for the cache line or the spin lock should be rare since
memory hotplug should happen rarely. Any preference?
I'd vote for keeping it simple and using a lock. Might be worth looking
at the ongoing work from Lorenzo:

https://lore.kernel.org/all/20260717-series-vmap-race-fix-v5-0-606a0ac6d3e5@xxxxxxxxxx/

Thanks, Will. Took a look at Lorenzo's work. IIUC he used init_mm mmap_lock to protect vmalloc area and linear mapping collapse on x86 in order to serialize against ptdump. I don't think we should use init_mm mmap_lock. We want to serialize linear mapping counter update between split and memory hotplug, but neither of them takes init_mm mmap_lock. We can let them take init_mm mmap_lock, but it sounds too overkilling.

So a dedicated spin lock may be better IMHO, which just protects linear mapping counter.

Yang


Will