The branch main has been updated by markj:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=6c2e9f4c32a44f3c239aba346322d871097eaed0

commit 6c2e9f4c32a44f3c239aba346322d871097eaed0
Author:     Mark Johnston <ma...@freebsd.org>
AuthorDate: 2022-09-24 13:20:29 +0000
Commit:     Mark Johnston <ma...@freebsd.org>
CommitDate: 2022-09-24 13:28:41 +0000

    amd64: Handle 1GB mappings in pmap_enter_quick_locked()
    
    This code path can be triggered by applying MADV_WILLNEED to a 1GB
    mapping.
    
    Reviewed by:    alc, kib
    MFC after:      1 week
    Differential Revision:  https://reviews.freebsd.org/D36674
---
 sys/amd64/amd64/pmap.c | 39 ++++++++++++++++++++++-----------------
 1 file changed, 22 insertions(+), 17 deletions(-)

diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index 9a33298944cc..358d016676d2 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -7545,8 +7545,9 @@ pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, 
vm_page_t m,
         * resident, we are creating it here.
         */
        if (va < VM_MAXUSER_ADDRESS) {
+               pdp_entry_t *pdpe;
+               pd_entry_t *pde;
                vm_pindex_t ptepindex;
-               pd_entry_t *ptepa;
 
                /*
                 * Calculate pagetable page index
@@ -7555,31 +7556,35 @@ pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, 
vm_page_t m,
                if (mpte && (mpte->pindex == ptepindex)) {
                        mpte->ref_count++;
                } else {
-                       /*
-                        * Get the page directory entry
-                        */
-                       ptepa = pmap_pde(pmap, va);
-
                        /*
                         * If the page table page is mapped, we just increment
                         * the hold count, and activate it.  Otherwise, we
-                        * attempt to allocate a page table page.  If this
-                        * attempt fails, we don't retry.  Instead, we give up.
+                        * attempt to allocate a page table page, passing NULL
+                        * instead of the PV list lock pointer because we don't
+                        * intend to sleep.  If this attempt fails, we don't
+                        * retry.  Instead, we give up.
                         */
-                       if (ptepa && (*ptepa & PG_V) != 0) {
-                               if (*ptepa & PG_PS)
+                       pdpe = pmap_pdpe(pmap, va);
+                       if (pdpe != NULL && (*pdpe & PG_V) != 0) {
+                               if ((*pdpe & PG_PS) != 0)
                                        return (NULL);
-                               mpte = PHYS_TO_VM_PAGE(*ptepa & PG_FRAME);
-                               mpte->ref_count++;
+                               pde = pmap_pdpe_to_pde(pdpe, va);
+                               if ((*pde & PG_V) != 0) {
+                                       if ((*pde & PG_PS) != 0)
+                                               return (NULL);
+                                       mpte = PHYS_TO_VM_PAGE(*pde & PG_FRAME);
+                                       mpte->ref_count++;
+                               } else {
+                                       mpte = pmap_allocpte_alloc(pmap,
+                                           ptepindex, NULL, va);
+                                       if (mpte == NULL)
+                                               return (NULL);
+                               }
                        } else {
-                               /*
-                                * Pass NULL instead of the PV list lock
-                                * pointer, because we don't intend to sleep.
-                                */
                                mpte = pmap_allocpte_alloc(pmap, ptepindex,
                                    NULL, va);
                                if (mpte == NULL)
-                                       return (mpte);
+                                       return (NULL);
                        }
                }
                pte = (pt_entry_t *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(mpte));

Reply via email to