git: 26a357245f21 - main - arm64: a few simplications to pmap_remove_{all, write}
Alan Cox
alc at FreeBSD.org
Tue Jun 29 03:23:11 UTC 2021
The branch main has been updated by alc:
URL: https://cgit.FreeBSD.org/src/commit/?id=26a357245f2197eea4dbbae0956d5c71ef8ba4f1
commit 26a357245f2197eea4dbbae0956d5c71ef8ba4f1
Author: Alan Cox <alc at FreeBSD.org>
AuthorDate: 2021-06-29 02:57:04 +0000
Commit: Alan Cox <alc at 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);
More information about the dev-commits-src-main
mailing list