[PATCH v2 08/15] riscv/mm: avoid redundant Svnapot A/D aggregation
Yunhui Cui <[email protected]> Thu, 16 Jul 2026 20:41:43 +0800
| Newsgroups | org.kernel.vger.linux-efi,org.infradead.lists.kvm-riscv,org.infradead.lists.linux-arm-kernel,org.infradead.lists.linux-riscv,org.kernel.vger.kvm,org.kernel.vger.linux-arch,org.kernel.vger.linux-kernel,org.kernel.vger.linux-perf-users,org.kvack.linux-mm |
|---|---|
| Message-ID | <66e43057442a0f37e0c7348016ccef382387898d.1784201104.git.cuiyunhui@bytedance.com> |
Svnapot mappings encode a 64KB range as a NAPOT PTE block, while the public getter returns a logical base-page PTE. To preserve that PTE view, the getter folds accessed and dirty information from the whole NAPOT block into the returned PTE. This aggregation is an OR-style operation. Once the returned PTE has both accessed and dirty state set, later entries in the block cannot change the result. Avoid reading the rest of the block in that case. The lockless getter still validates each entry before consuming its A/D state, so it preserves the self-consistent range requirement while also avoiding reads that cannot affect the returned PTE. Signed-off-by: Yunhui Cui <[email protected]> --- arch/riscv/mm/contpte.c | 60 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 4 deletions(-) diff --git a/arch/riscv/mm/contpte.c b/arch/riscv/mm/contpte.c index 9ffdffdc2b0c0..70f9a0668b50c 100644 --- a/arch/riscv/mm/contpte.c +++ b/arch/riscv/mm/contpte.c @@ -309,10 +309,34 @@ pte_t napotpte_ptep_get(pte_t *ptep, pte_t orig_pte) cur = READ_ONCE(start[i]); if (!napotpte_is_consistent(cur, orig_pte)) return napotpte_subpte(ptep, orig_pte); - if (pte_dirty(cur)) + if (pte_dirty(cur)) { pte = riscv_pte_mkhwdirty(pte); - if (pte_young(cur)) + for (; i < nr; i++) { + cur = READ_ONCE(start[i]); + if (!napotpte_is_consistent(cur, orig_pte)) + return napotpte_subpte(ptep, orig_pte); + if (pte_young(cur)) { + pte = pte_mkyoung(pte); + break; + } + } + break; + } + + if (pte_young(cur)) { pte = pte_mkyoung(pte); + i++; + for (; i < nr; i++) { + cur = READ_ONCE(start[i]); + if (!napotpte_is_consistent(cur, orig_pte)) + return napotpte_subpte(ptep, orig_pte); + if (pte_dirty(cur)) { + pte = riscv_pte_mkhwdirty(pte); + break; + } + } + break; + } } return napotpte_subpte(ptep, pte); @@ -343,11 +367,39 @@ pte_t napotpte_ptep_get_lockless(pte_t *orig_ptep) if (!napotpte_is_consistent(pte, orig_pte)) goto retry; - if (pte_dirty(pte)) + if (pte_dirty(pte)) { orig_pte = riscv_pte_mkhwdirty(orig_pte); + for (; i < nr; i++, ptep++) { + pte = READ_ONCE(*ptep); + + if (!napotpte_is_consistent(pte, orig_pte)) + goto retry; - if (pte_young(pte)) + if (pte_young(pte)) { + orig_pte = pte_mkyoung(orig_pte); + break; + } + } + break; + } + + if (pte_young(pte)) { orig_pte = pte_mkyoung(orig_pte); + i++; + ptep++; + for (; i < nr; i++, ptep++) { + pte = READ_ONCE(*ptep); + + if (!napotpte_is_consistent(pte, orig_pte)) + goto retry; + + if (pte_dirty(pte)) { + orig_pte = riscv_pte_mkhwdirty(orig_pte); + break; + } + } + break; + } } return napotpte_subpte(orig_ptep, orig_pte); -- 2.39.5