The branch main has been updated by alc:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=26a357245f2197eea4dbbae0956d5c71ef8ba4f1

commit 26a357245f2197eea4dbbae0956d5c71ef8ba4f1
Author:     Alan Cox <a...@freebsd.org>
AuthorDate: 2021-06-29 02:57:04 +0000
Commit:     Alan Cox <a...@freebsd.org>
CommitDate: 2021-06-29 03:21:24 +0000

    arm64: a few simplications to pmap_remove_{all,write}
    
    Eliminate some unnecessary unlocking and relocking when we have to retry
    the operation to avoid deadlock.  (All of the other pmap functions that
    iterate over a PV list already implemented retries without these same
    unlocking and relocking operations.)
    
    Avoid a pointer dereference by using an existing local variable that
    already holds the desired value.
    
    Eliminate some unnecessary repetition of code on a failed fcmpset.
    Specifically, there is no point in retesting the DBM bit because it
    cannot change state while the pmap lock is held.
    
    Reviewed by:    kib, markj
    MFC after:      1 week
    Differential Revision:  https://reviews.freebsd.org/D30931
---
 sys/arm64/arm64/pmap.c | 20 +++++++-------------
 1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c
index 76ca8eab70ff..79b9d20231aa 100644
--- a/sys/arm64/arm64/pmap.c
+++ b/sys/arm64/arm64/pmap.c
@@ -3130,8 +3130,8 @@ pmap_remove_all(vm_page_t m)
        SLIST_INIT(&free);
        lock = VM_PAGE_TO_PV_LIST_LOCK(m);
        pvh = (m->flags & PG_FICTITIOUS) != 0 ? &pv_dummy : page_to_pvh(m);
-retry:
        rw_wlock(lock);
+retry:
        while ((pv = TAILQ_FIRST(&pvh->pv_list)) != NULL) {
                pmap = PV_PMAP(pv);
                if (!PMAP_TRYLOCK(pmap)) {
@@ -3140,7 +3140,6 @@ retry:
                        PMAP_LOCK(pmap);
                        rw_wlock(lock);
                        if (pvh_gen != pvh->pv_gen) {
-                               rw_wunlock(lock);
                                PMAP_UNLOCK(pmap);
                                goto retry;
                        }
@@ -3151,7 +3150,6 @@ retry:
                    ("pmap_remove_all: no page table entry found"));
                KASSERT(lvl == 2,
                    ("pmap_remove_all: invalid pte level %d", lvl));
-
                pmap_demote_l2_locked(pmap, pte, va, &lock);
                PMAP_UNLOCK(pmap);
        }
@@ -3165,7 +3163,6 @@ retry:
                        PMAP_LOCK(pmap);
                        rw_wlock(lock);
                        if (pvh_gen != pvh->pv_gen || md_gen != m->md.pv_gen) {
-                               rw_wunlock(lock);
                                PMAP_UNLOCK(pmap);
                                goto retry;
                        }
@@ -5224,8 +5221,8 @@ pmap_remove_write(vm_page_t m)
                return;
        lock = VM_PAGE_TO_PV_LIST_LOCK(m);
        pvh = (m->flags & PG_FICTITIOUS) != 0 ? &pv_dummy : page_to_pvh(m);
-retry_pv_loop:
        rw_wlock(lock);
+retry:
        TAILQ_FOREACH_SAFE(pv, &pvh->pv_list, pv_next, next_pv) {
                pmap = PV_PMAP(pv);
                PMAP_ASSERT_STAGE1(pmap);
@@ -5236,12 +5233,11 @@ retry_pv_loop:
                        rw_wlock(lock);
                        if (pvh_gen != pvh->pv_gen) {
                                PMAP_UNLOCK(pmap);
-                               rw_wunlock(lock);
-                               goto retry_pv_loop;
+                               goto retry;
                        }
                }
                va = pv->pv_va;
-               pte = pmap_pte(pmap, pv->pv_va, &lvl);
+               pte = pmap_pte(pmap, va, &lvl);
                if ((pmap_load(pte) & ATTR_SW_DBM) != 0)
                        (void)pmap_demote_l2_locked(pmap, pte, va, &lock);
                KASSERT(lock == VM_PAGE_TO_PV_LIST_LOCK(m),
@@ -5261,17 +5257,15 @@ retry_pv_loop:
                        if (pvh_gen != pvh->pv_gen ||
                            md_gen != m->md.pv_gen) {
                                PMAP_UNLOCK(pmap);
-                               rw_wunlock(lock);
-                               goto retry_pv_loop;
+                               goto retry;
                        }
                }
                pte = pmap_pte(pmap, pv->pv_va, &lvl);
                oldpte = pmap_load(pte);
-retry:
                if ((oldpte & ATTR_SW_DBM) != 0) {
-                       if (!atomic_fcmpset_long(pte, &oldpte,
+                       while (!atomic_fcmpset_64(pte, &oldpte,
                            (oldpte | ATTR_S1_AP_RW_BIT) & ~ATTR_SW_DBM))
-                               goto retry;
+                               cpu_spinwait();
                        if ((oldpte & ATTR_S1_AP_RW_BIT) ==
                            ATTR_S1_AP(ATTR_S1_AP_RW))
                                vm_page_dirty(m);
_______________________________________________
dev-commits-src-main@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-main
To unsubscribe, send any mail to "dev-commits-src-main-unsubscr...@freebsd.org"

Reply via email to