Re: [PATCH v3 06/22] mm: Always use page table accessor functions

From: Christophe Leroy (CS GROUP)

Date: Wed Nov 26 2025 - 06:08:27 EST




Le 13/11/2025 à 02:45, Samuel Holland a écrit :
Some platforms need to fix up the values when reading or writing page
tables. Because of this, the accessors must always be used; it is not
valid to simply dereference a pXX_t pointer.

Fix all of the instances of this pattern in generic code, mostly by
applying the below coccinelle semantic patch, repeated for each page
table level. Some additional fixes were applied manually, mostly to
macros where type information is unavailable.

In a few places, a `pte_t *` or `pmd_t *` is actually a pointer to a PTE
or PMDE value stored on the stack, not a pointer to a page table. In
those cases, it is not appropriate to use the accessors, because the
value is not globally visible, and any transformation from pXXp_get()
has already been applied. Those places are marked by naming the pointer
`ptentp` or `pmdvalp`, as opposed to `ptep` or `pmdp`.

...


Signed-off-by: Samuel Holland <samuel.holland@xxxxxxxxxx>
---
This commit covers some of the same changes as an existing series from
Anshuman Khandual[1]. Unlike that series, this commit is a purely
mechanical conversion to demonstrate the RISC-V changes, so it does not
insert local variables to avoid redundant calls to the accessors. A
manual conversion like in that series could improve performance.

And this commit has the same problem as the series from Anshuman, see [2]:

Before the patch, as an exemple on powerpc/32 mm_find_pmd() was:

00001860 <mm_find_pmd>:
1860: 80 63 00 18 lwz r3,24(r3)
1864: 54 84 65 3a rlwinm r4,r4,12,20,29
1868: 7c 63 22 14 add r3,r3,r4
186c: 4e 80 00 20 blr

Now it is:

00001860 <mm_find_pmd>:
1860: 81 23 00 18 lwz r9,24(r3)
1864: 54 84 65 3a rlwinm r4,r4,12,20,29
1868: 7d 49 20 2e lwzx r10,r9,r4 <== Pointless read
186c: 7c 69 22 14 add r3,r9,r4
1870: 7d 49 20 2e lwzx r10,r9,r4 <== Pointless read
1874: 7d 29 20 2e lwzx r9,r9,r4 <== Pointless read
1878: 4e 80 00 20 blr

To avoid it you need something like:

diff --git a/mm/rmap.c b/mm/rmap.c
index aafefc1d7955..0c61153f4ea9 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -819,15 +819,15 @@ pmd_t *mm_find_pmd(struct mm_struct *mm, unsigned long address)
pmd_t *pmd = NULL;

pgd = pgd_offset(mm, address);
- if (!pgd_present(pgdp_get(pgd)))
+ if (!mm_p4d_folded(mm) && !pgd_present(pgdp_get(pgd)))
goto out;

p4d = p4d_offset(pgd, address);
- if (!p4d_present(p4dp_get(p4d)))
+ if (!mm_pud_folded(mm) && !p4d_present(p4dp_get(p4d)))
goto out;

pud = pud_offset(p4d, address);
- if (!pud_present(pudp_get(pud)))
+ if (!mm_pmd_folded(mm) && !pud_present(pudp_get(pud)))
goto out;

pmd = pmd_offset(pud, address);


[2] https://lore.kernel.org/linux-mm/f40ea8bf-0862-41a7-af19-70bfbd838568@xxxxxxxxxx/


[1]: https://lore.kernel.org/linux-mm/20240917073117.1531207-1-anshuman.khandual@xxxxxxx/


Christophe