git: 8024a900a4a7 - stable/13 - amd64: Don't repeat unnecessary tests when cmpset fails

Mark Johnston markj at FreeBSD.org
Tue Aug 31 19:09:56 UTC 2021


The branch stable/13 has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=8024a900a4a76f11d972213f108e0cbdeb82564b

commit 8024a900a4a76f11d972213f108e0cbdeb82564b
Author:     Alan Cox <alc at FreeBSD.org>
AuthorDate: 2021-07-24 08:50:27 +0000
Commit:     Mark Johnston <markj at FreeBSD.org>
CommitDate: 2021-08-31 19:09:24 +0000

    amd64: Don't repeat unnecessary tests when cmpset fails
    
    When a cmpset for removing the PG_RW bit in pmap_promote_pde() fails,
    there is no need to repeat the alignment, PG_A, and PG_V tests just to
    reload the PTE's value.  The only bit that we need be concerned with at
    this point is PG_M.  Use fcmpset instead.
    
    (cherry picked from commit 3687797618b6c978ad733bd206a623e5df47dbe3)
---
 sys/amd64/amd64/pmap.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index 705bbe712bff..0ac312a95a8c 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -6511,7 +6511,6 @@ pmap_promote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va,
 	 * within a 2MB page. 
 	 */
 	firstpte = (pt_entry_t *)PHYS_TO_DMAP(*pde & PG_FRAME);
-setpde:
 	newpde = *firstpte;
 	if ((newpde & ((PG_FRAME & PDRMASK) | PG_A | PG_V)) != (PG_A | PG_V) ||
 	    !pmap_allow_2m_x_page(pmap, pmap_pde_ept_executable(pmap,
@@ -6521,12 +6520,13 @@ setpde:
 		    " in pmap %p", va, pmap);
 		return;
 	}
+setpde:
 	if ((newpde & (PG_M | PG_RW)) == PG_RW) {
 		/*
 		 * When PG_M is already clear, PG_RW can be cleared without
 		 * a TLB invalidation.
 		 */
-		if (!atomic_cmpset_long(firstpte, newpde, newpde & ~PG_RW))
+		if (!atomic_fcmpset_long(firstpte, &newpde, newpde & ~PG_RW))
 			goto setpde;
 		newpde &= ~PG_RW;
 	}
@@ -6538,7 +6538,6 @@ setpde:
 	 */
 	pa = (newpde & (PG_PS_FRAME | PG_A | PG_V)) + NBPDR - PAGE_SIZE;
 	for (pte = firstpte + NPTEPG - 1; pte > firstpte; pte--) {
-setpte:
 		oldpte = *pte;
 		if ((oldpte & (PG_FRAME | PG_A | PG_V)) != pa) {
 			atomic_add_long(&pmap_pde_p_failures, 1);
@@ -6546,12 +6545,13 @@ setpte:
 			    " in pmap %p", va, pmap);
 			return;
 		}
+setpte:
 		if ((oldpte & (PG_M | PG_RW)) == PG_RW) {
 			/*
 			 * When PG_M is already clear, PG_RW can be cleared
 			 * without a TLB invalidation.
 			 */
-			if (!atomic_cmpset_long(pte, oldpte, oldpte & ~PG_RW))
+			if (!atomic_fcmpset_long(pte, &oldpte, oldpte & ~PG_RW))
 				goto setpte;
 			oldpte &= ~PG_RW;
 			CTR2(KTR_PMAP, "pmap_promote_pde: protect for va %#lx"


More information about the dev-commits-src-branches mailing list