Page MenuHomeFreeBSD

RISC-V superpage support, part 1/6.
ClosedPublic

Authored by markj on Jan 17 2019, 2:52 AM.
Tags
None
Referenced Files
Unknown Object (File)
Thu, Nov 21, 6:08 PM
Unknown Object (File)
Oct 22 2024, 10:52 AM
Unknown Object (File)
Oct 18 2024, 12:27 PM
Unknown Object (File)
Oct 17 2024, 8:07 PM
Unknown Object (File)
Oct 5 2024, 4:50 AM
Unknown Object (File)
Oct 4 2024, 10:04 PM
Unknown Object (File)
Oct 4 2024, 5:55 AM
Unknown Object (File)
Oct 2 2024, 9:26 PM
Subscribers

Details

Summary

The change adds routines to promote and demote 2MB superpages. It also
adds support for pmap_enter(psind = 1), described in the commit log
message for r321378. A subsequent commit modifies all of the pmap
routines to handle large mappings appropriately.

The changes are largely adopted from amd64. arm64 has more stringent
requirements around superpage mappings in order to avoid TLB conflict
aborts, and these requirements do not apply to RISC-V, which like amd64
permits TLBs to simultaneously cache 4KB and 2MB translations of a given
page. RISC-V only supports 2 software-defined PTE bits, already used
for PTE_SW_MANAGED and PTE_SW_WIRED, so we do not have an analogue to
amd64's PG_PROMOTED; instead, pmap_remove_l2() always invalidates the
entire 2MB range.

Unlike pmap_remove_pde(), RISC-V's pmap_remove_l2() handles TLB
invalidation.

Note that unlike amd64, RISC-V still has the pvh_global_lock.

Diff Detail

Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 22095
Build 21319: arc lint + arc unit

Event Timeline

sys/riscv/riscv/pmap.c
2616

Is pmap_enter_l2() allowed to fail when PMAP_ENTER_NOSLEEP is not specified ?

I am asking because vm_fault_populate() is not ready for it, and I have a WIP where I needed to add the following diff:

diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index e095ccc69ed..c3246e4a3b7 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -479,8 +479,20 @@ vm_fault_populate(struct faultstate *fs, vm_prot_t prot, int fault_type,
 			    fault_flags, true);
 		}
 		VM_OBJECT_WUNLOCK(fs->first_object);
-		pmap_enter(fs->map->pmap, vaddr, m, prot, fault_type | (wired ?
-		    PMAP_ENTER_WIRED : 0), psind);
+		rv = pmap_enter(fs->map->pmap, vaddr, m, prot, fault_type |
+		    (wired ? PMAP_ENTER_WIRED : 0), psind);
+#if defined(__amd64__)
+		if (psind > 0 && rv == KERN_FAILURE) {
+			for (i = 0; i < npages; i++) {
+				rv = pmap_enter(fs->map->pmap, vaddr + ptoa(i),
+				    &m[i], prot, fault_type |
+				    (wired ? PMAP_ENTER_WIRED : 0), 0);
+				MPASS(rv == KERN_SUCCESS);
+			}
+		}
+#else
+		MPASS(rv == KERN_SUCCESS);
+#endif
 		VM_OBJECT_WLOCK(fs->first_object);
 		m_mtx = NULL;
 		for (i = 0; i < npages; i++) {
sys/riscv/riscv/pmap.c
2616

No, it should not fail for any other reason. (The NOREPLACE flag may cause it to fail upon discovering an existing mapping, but this is not used by pmap_enter().) So your diff doesn't need an update.

IMO it is kind of weird for pmap_enter(psind > 0) to have distinct failure modes from pmap_enter(psind = 0). I'd be interested to hear about it if you feel like describing the WIP here.

sys/vm/vm_fault.c
273

We really need a proper predicate for this. Note that platforms may define VM_NRESERVLEVEL > 0 without implementing transparent superpages. sparc64 does this. Should we define a new constant in machine/vmparam.h?

kib added inline comments.
sys/riscv/riscv/pmap.c
2616
This revision is now accepted and ready to land.Jan 20 2019, 10:59 AM
sys/riscv/riscv/pmap.c
1853

s/entires/entries/

markj marked an inline comment as done.

Fix typo.

This revision now requires review to proceed.Jan 23 2019, 9:16 PM
This revision was not accepted when it landed; it landed in state Needs Review.Feb 13 2019, 5:20 PM
This revision was automatically updated to reflect the committed changes.