summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2003-12-26 23:33:37 +0000
committeralc <alc@FreeBSD.org>2003-12-26 23:33:37 +0000
commit5eb32a5d39d8852686eb0b1a26d1ec151eae5b64 (patch)
tree2baaf0dd37619831f610f06cd9b78bafdc94369a
parent2ce64279e54710912cdac619afa147ca8937c3ac (diff)
downloadFreeBSD-src-5eb32a5d39d8852686eb0b1a26d1ec151eae5b64.zip
FreeBSD-src-5eb32a5d39d8852686eb0b1a26d1ec151eae5b64.tar.gz
- Reduce Giant's scope in vm_fault().
- Use vm_object_reference_locked() instead of vm_object_reference() in vm_fault().
-rw-r--r--sys/vm/vm_fault.c24
1 files changed, 10 insertions, 14 deletions
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index f1e06d7..567926e 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -170,6 +170,8 @@ _unlock_things(struct faultstate *fs, int dealloc)
vput(fs->vp);
fs->vp = NULL;
}
+ if (dealloc)
+ mtx_unlock(&Giant);
}
#define unlock_things(fs) _unlock_things(fs, 0)
@@ -220,7 +222,6 @@ vm_fault(vm_map_t map, vm_offset_t vaddr, vm_prot_t fault_type,
growstack = TRUE;
atomic_add_int(&cnt.v_vm_faults, 1);
- mtx_lock(&Giant);
RetryFault:;
/*
@@ -235,15 +236,14 @@ RetryFault:;
(fault_flags & VM_FAULT_WIRE_MASK) != VM_FAULT_USER_WIRE) {
if (growstack && result == KERN_INVALID_ADDRESS &&
map != kernel_map && curproc != NULL) {
+ mtx_lock(&Giant);
result = vm_map_growstack(curproc, vaddr);
- if (result != KERN_SUCCESS) {
- mtx_unlock(&Giant);
+ mtx_unlock(&Giant);
+ if (result != KERN_SUCCESS)
return (KERN_FAILURE);
- }
growstack = FALSE;
goto RetryFault;
}
- mtx_unlock(&Giant);
return (result);
}
@@ -257,10 +257,8 @@ RetryFault:;
result = vm_map_lookup(&fs.map, vaddr,
VM_PROT_READ|VM_PROT_WRITE|VM_PROT_OVERRIDE_WRITE,
&fs.entry, &fs.first_object, &fs.first_pindex, &prot, &wired);
- if (result != KERN_SUCCESS) {
- mtx_unlock(&Giant);
+ if (result != KERN_SUCCESS)
return (result);
- }
/*
* If we don't COW now, on a user wire, the user will never
@@ -293,8 +291,9 @@ RetryFault:;
*
* XXX vnode_pager_lock() can block without releasing the map lock.
*/
- vm_object_reference(fs.first_object);
+ mtx_lock(&Giant);
VM_OBJECT_LOCK(fs.first_object);
+ vm_object_reference_locked(fs.first_object);
fs.vp = vnode_pager_lock(fs.first_object);
vm_object_pip_add(fs.first_object, 1);
@@ -316,7 +315,6 @@ RetryFault:;
*/
if (fs.object->flags & OBJ_DEAD) {
unlock_and_deallocate(&fs);
- mtx_unlock(&Giant);
return (KERN_PROTECTION_FAILURE);
}
@@ -371,6 +369,7 @@ RetryFault:;
if (!vm_page_sleep_if_busy(fs.m, TRUE, "vmpfw"))
vm_page_unlock_queues();
cnt.v_intrans++;
+ mtx_unlock(&Giant);
vm_object_deallocate(fs.first_object);
goto RetryFault;
}
@@ -411,7 +410,6 @@ RetryFault:;
if (TRYPAGER || fs.object == fs.first_object) {
if (fs.pindex >= fs.object->size) {
unlock_and_deallocate(&fs);
- mtx_unlock(&Giant);
return (KERN_PROTECTION_FAILURE);
}
@@ -598,7 +596,6 @@ readrest:
vm_page_unlock_queues();
fs.m = NULL;
unlock_and_deallocate(&fs);
- mtx_unlock(&Giant);
return ((rv == VM_PAGER_ERROR) ? KERN_FAILURE : KERN_PROTECTION_FAILURE);
}
if (fs.object != fs.first_object) {
@@ -820,7 +817,6 @@ readrest:
if (result != KERN_SUCCESS) {
release_page(&fs);
unlock_and_deallocate(&fs);
- mtx_unlock(&Giant);
return (result);
}
fs.lookup_still_valid = TRUE;
@@ -904,6 +900,7 @@ readrest:
if (((fault_flags & VM_FAULT_WIRE_MASK) == 0) && (wired == 0)) {
vm_fault_prefault(fs.map->pmap, vaddr, fs.entry);
}
+ mtx_unlock(&Giant);
vm_page_lock_queues();
vm_page_flag_clear(fs.m, PG_ZERO);
vm_page_flag_set(fs.m, PG_REFERENCED);
@@ -937,7 +934,6 @@ readrest:
* Unlock everything, and return
*/
vm_object_deallocate(fs.first_object);
- mtx_unlock(&Giant);
return (KERN_SUCCESS);
}
OpenPOWER on IntegriCloud