git: 6c1d6d4c7ffd - main - i386: Add a leaf PTP when pmap_enter(psind=1) creates a wired mapping
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 09 Oct 2023 00:47:14 UTC
The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=6c1d6d4c7ffd81d66acd4869cfe596398df301b7 commit 6c1d6d4c7ffd81d66acd4869cfe596398df301b7 Author: Bojan Novković <bojan.novkovic@fer.hr> AuthorDate: 2023-10-09 00:32:35 +0000 Commit: Mark Johnston <markj@FreeBSD.org> CommitDate: 2023-10-09 00:40:44 +0000 i386: Add a leaf PTP when pmap_enter(psind=1) creates a wired mapping Let pmap_enter_pde() create wired mappings. In particular, allocate a leaf PTP for use during demotion. This is a step towards reverting commit 64087fd7f372. Reviewed by: alc, kib, markj Sponsored by: Google, Inc. (GSoC 2023) MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D41635 --- sys/i386/i386/pmap.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c index 2d19fc51dd53..6b839484e6c5 100644 --- a/sys/i386/i386/pmap.c +++ b/sys/i386/i386/pmap.c @@ -3973,12 +3973,11 @@ pmap_enter_pde(pmap_t pmap, vm_offset_t va, pd_entry_t newpde, u_int flags, struct spglist free; pd_entry_t oldpde, *pde; vm_page_t mt; + vm_page_t uwptpg; rw_assert(&pvh_global_lock, RA_WLOCKED); KASSERT((newpde & (PG_M | PG_RW)) != PG_RW, ("pmap_enter_pde: newpde is missing PG_M")); - KASSERT(pmap == kernel_pmap || (newpde & PG_W) == 0, - ("pmap_enter_pde: cannot create wired user mapping")); PMAP_LOCK_ASSERT(pmap, MA_OWNED); pde = pmap_pde(pmap, va); oldpde = *pde; @@ -4028,11 +4027,40 @@ pmap_enter_pde(pmap_t pmap, vm_offset_t va, pd_entry_t newpde, u_int flags, panic("pmap_enter_pde: trie insert failed"); } } + + /* + * Allocate a leaf ptpage for wired userspace pages. + */ + uwptpg = NULL; + if ((newpde & PG_W) != 0 && pmap != kernel_pmap) { + uwptpg = vm_page_alloc_noobj(VM_ALLOC_WIRED); + if (uwptpg == NULL) { + return (KERN_RESOURCE_SHORTAGE); + } + uwptpg->pindex = va >> PDRSHIFT; + if (pmap_insert_pt_page(pmap, uwptpg, true, false)) { + vm_page_unwire_noq(uwptpg); + vm_page_free(uwptpg); + return (KERN_RESOURCE_SHORTAGE); + } + pmap->pm_stats.resident_count++; + uwptpg->ref_count = NPTEPG; + } if ((newpde & PG_MANAGED) != 0) { /* * Abort this mapping if its PV entry could not be created. */ if (!pmap_pv_insert_pde(pmap, va, newpde, flags)) { + if (uwptpg != NULL) { + mt = pmap_remove_pt_page(pmap, va); + KASSERT(mt == uwptpg, + ("removed pt page %p, expected %p", mt, + uwptpg)); + pmap->pm_stats.resident_count--; + uwptpg->ref_count = 1; + vm_page_unwire_noq(uwptpg); + vm_page_free(uwptpg); + } CTR2(KTR_PMAP, "pmap_enter_pde: failure for va %#lx" " in pmap %p", va, pmap); return (KERN_RESOURCE_SHORTAGE);