summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2012-05-24 15:25:35 +0000
committeralc <alc@FreeBSD.org>2012-05-24 15:25:35 +0000
commit20811fd440c15c30bf11425fc57b15309c51a9e7 (patch)
tree91409fbdbcef7d68424468b04d4d7a6d79279ea6
parent96f3e42ce2c9de14b3e9a1de338ed639c1c8b596 (diff)
downloadFreeBSD-src-20811fd440c15c30bf11425fc57b15309c51a9e7.zip
FreeBSD-src-20811fd440c15c30bf11425fc57b15309c51a9e7.tar.gz
MF amd64 r233097, r233122
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 or PMAP1/PADDR1. Style fix to pmap_protect().
-rw-r--r--sys/i386/i386/pmap.c47
1 files changed, 35 insertions, 12 deletions
diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c
index 89e7a2f..e89cf5a 100644
--- a/sys/i386/i386/pmap.c
+++ b/sys/i386/i386/pmap.c
@@ -3050,7 +3050,7 @@ pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot)
vm_offset_t pdnxt;
pd_entry_t ptpaddr;
pt_entry_t *pte;
- int anychanged;
+ boolean_t anychanged, pv_lists_locked;
if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
pmap_remove(pmap, sva, eva);
@@ -3066,10 +3066,16 @@ pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot)
return;
#endif
- anychanged = 0;
+ if (pmap_is_current(pmap))
+ pv_lists_locked = FALSE;
+ else {
+ pv_lists_locked = TRUE;
+resume:
+ vm_page_lock_queues();
+ sched_pin();
+ }
+ anychanged = FALSE;
- vm_page_lock_queues();
- sched_pin();
PMAP_LOCK(pmap);
for (; sva < eva; sva = pdnxt) {
pt_entry_t obits, pbits;
@@ -3104,12 +3110,27 @@ pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot)
*/
if (pmap_protect_pde(pmap,
&pmap->pm_pdir[pdirindex], sva, prot))
- anychanged = 1;
- continue;
- } else if (!pmap_demote_pde(pmap,
- &pmap->pm_pdir[pdirindex], sva)) {
- /* The large page mapping was destroyed. */
+ anychanged = TRUE;
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);
+ goto resume;
+ }
+ }
+ if (!pmap_demote_pde(pmap,
+ &pmap->pm_pdir[pdirindex], sva)) {
+ /*
+ * The large page mapping was
+ * destroyed.
+ */
+ continue;
+ }
}
}
@@ -3155,14 +3176,16 @@ retry:
if (obits & PG_G)
pmap_invalidate_page(pmap, sva);
else
- anychanged = 1;
+ anychanged = TRUE;
}
}
}
- sched_unpin();
if (anychanged)
pmap_invalidate_all(pmap);
- vm_page_unlock_queues();
+ if (pv_lists_locked) {
+ sched_unpin();
+ vm_page_unlock_queues();
+ }
PMAP_UNLOCK(pmap);
}
OpenPOWER on IntegriCloud