aboutsummaryrefslogtreecommitdiff
path: root/sys/vm/vm_fault.c
diff options
context:
space:
mode:
authorAlan Cox <alc@FreeBSD.org>2004-12-24 19:31:54 +0000
committerAlan Cox <alc@FreeBSD.org>2004-12-24 19:31:54 +0000
commita51b084059e93d45eb9e9e0393367bb8b600c6b3 (patch)
treec107db5fbf1579df9e9a27b8a3bc54bbd4a0e77c /sys/vm/vm_fault.c
parentc628825b30012c832d1b9b859bb4aea69a49810a (diff)
downloadsrc-a51b084059e93d45eb9e9e0393367bb8b600c6b3.tar.gz
src-a51b084059e93d45eb9e9e0393367bb8b600c6b3.zip
Continue the transition from synchronizing access to the page's PG_BUSY
flag and busy field with the global page queues lock to synchronizing their access with the containing object's lock. Specifically, acquire the containing object's lock before reading the page's PG_BUSY flag and busy field in vm_fault(). Reviewed by: tegge@
Notes
Notes: svn path=/head/; revision=139265
Diffstat (limited to 'sys/vm/vm_fault.c')
-rw-r--r--sys/vm/vm_fault.c40
1 files changed, 29 insertions, 11 deletions
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index 4f6d1e957abb..69efea80060c 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -148,7 +148,7 @@ unlock_map(struct faultstate *fs)
}
static void
-_unlock_things(struct faultstate *fs, int dealloc)
+unlock_and_deallocate(struct faultstate *fs)
{
vm_object_pip_wakeup(fs->object);
@@ -162,9 +162,7 @@ _unlock_things(struct faultstate *fs, int dealloc)
VM_OBJECT_UNLOCK(fs->first_object);
fs->first_m = NULL;
}
- if (dealloc) {
- vm_object_deallocate(fs->first_object);
- }
+ vm_object_deallocate(fs->first_object);
unlock_map(fs);
if (fs->vp != NULL) {
mtx_lock(&Giant);
@@ -172,13 +170,10 @@ _unlock_things(struct faultstate *fs, int dealloc)
mtx_unlock(&Giant);
fs->vp = NULL;
}
- if (dealloc && !fs->map->system_map)
+ if (!fs->map->system_map)
VM_UNLOCK_GIANT();
}
-#define unlock_things(fs) _unlock_things(fs, 0)
-#define unlock_and_deallocate(fs) _unlock_things(fs, 1)
-
/*
* TRYPAGER - used by vm_fault to calculate whether the pager for the
* current object *might* contain the page.
@@ -367,10 +362,33 @@ RetryFault:;
*/
if ((fs.m->flags & PG_BUSY) || fs.m->busy) {
vm_page_unlock_queues();
- unlock_things(&fs);
- vm_page_lock_queues();
- if (!vm_page_sleep_if_busy(fs.m, TRUE, "vmpfw"))
+ VM_OBJECT_UNLOCK(fs.object);
+ if (fs.object != fs.first_object) {
+ VM_OBJECT_LOCK(fs.first_object);
+ vm_page_lock_queues();
+ vm_page_free(fs.first_m);
vm_page_unlock_queues();
+ vm_object_pip_wakeup(fs.first_object);
+ VM_OBJECT_UNLOCK(fs.first_object);
+ fs.first_m = NULL;
+ }
+ unlock_map(&fs);
+ if (fs.vp != NULL) {
+ mtx_lock(&Giant);
+ vput(fs.vp);
+ mtx_unlock(&Giant);
+ fs.vp = NULL;
+ }
+ VM_OBJECT_LOCK(fs.object);
+ if (fs.m == vm_page_lookup(fs.object,
+ fs.pindex)) {
+ vm_page_lock_queues();
+ if (!vm_page_sleep_if_busy(fs.m, TRUE,
+ "vmpfw"))
+ vm_page_unlock_queues();
+ }
+ vm_object_pip_wakeup(fs.object);
+ VM_OBJECT_UNLOCK(fs.object);
atomic_add_int(&cnt.v_intrans, 1);
if (!fs.map->system_map)
VM_UNLOCK_GIANT();