summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2012-03-17 22:04:58 +0000
committeralc <alc@FreeBSD.org>2012-03-17 22:04:58 +0000
commiteb494d678de962a38a167f6340ee1f70f7473fa5 (patch)
treeda5389ff077505348dd3b2575f921381bd962ef6
parent26b44e3c9dec81c45a5cd5e5386ca5b6c9a06953 (diff)
downloadFreeBSD-src-eb494d678de962a38a167f6340ee1f70f7473fa5.zip
FreeBSD-src-eb494d678de962a38a167f6340ee1f70f7473fa5.tar.gz
With the changes over the past year to how accesses to the page's dirty
field are synchronized, there is no need for pmap_protect() to acquire the page queues lock unless it is going to access the pv lists. Reviewed by: kib
-rw-r--r--sys/amd64/amd64/pmap.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index 4c7bd2f..1289a38 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -2940,6 +2940,7 @@ pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot)
pd_entry_t ptpaddr, *pde;
pt_entry_t *pte;
int anychanged;
+ boolean_t pv_lists_locked;
if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
pmap_remove(pmap, sva, eva);
@@ -2950,9 +2951,10 @@ pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot)
(VM_PROT_WRITE|VM_PROT_EXECUTE))
return;
+ pv_lists_locked = FALSE;
+resume:
anychanged = 0;
- vm_page_lock_queues();
PMAP_LOCK(pmap);
for (; sva < eva; sva = va_next) {
@@ -3001,9 +3003,25 @@ pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot)
if (pmap_protect_pde(pmap, pde, sva, prot))
anychanged = 1;
continue;
- } else if (!pmap_demote_pde(pmap, pde, sva)) {
- /* The large page mapping was destroyed. */
- continue;
+ } else {
+ if (!pv_lists_locked) {
+ pv_lists_locked = TRUE;
+ if (!mtx_trylock(&vm_page_queue_mtx)) {
+ if (anychanged)
+ pmap_invalidate_all(
+ pmap);
+ PMAP_UNLOCK(pmap);
+ vm_page_lock_queues();
+ goto resume;
+ }
+ }
+ if (!pmap_demote_pde(pmap, pde, sva)) {
+ /*
+ * The large page mapping was
+ * destroyed.
+ */
+ continue;
+ }
}
}
@@ -3043,7 +3061,8 @@ retry:
}
if (anychanged)
pmap_invalidate_all(pmap);
- vm_page_unlock_queues();
+ if (pv_lists_locked)
+ vm_page_unlock_queues();
PMAP_UNLOCK(pmap);
}
OpenPOWER on IntegriCloud