Date: Tue, 29 Jun 2021 03:23:11 GMT From: Alan Cox <alc@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 26a357245f21 - main - arm64: a few simplications to pmap_remove_{all, write} Message-ID: <202106290323.15T3NBK8048216@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by alc: URL: https://cgit.FreeBSD.org/src/commit/?id=26a357245f2197eea4dbbae0956d5c71ef8ba4f1 commit 26a357245f2197eea4dbbae0956d5c71ef8ba4f1 Author: Alan Cox <alc@FreeBSD.org> AuthorDate: 2021-06-29 02:57:04 +0000 Commit: Alan Cox <alc@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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202106290323.15T3NBK8048216>