o Call vm_map_growstack() from vm_fault() if vm_map_lookup() has failed

due to conditions that suggest the possible need for stack growth.
   This has two beneficial effects: (1) we can
   now remove calls to vm_map_growstack() from the MD trap handlers and (2)
   simple page faults are faster because we no longer unnecessarily perform
   vm_map_growstack() on every page fault.
 o Remove vm_map_growstack() from the i386's trap_pfault().
 o Remove the acquisition and release of Giant from i386's trap_pfault().
   (vm_fault() still acquires it.)
This commit is contained in:
Alan Cox 2002-04-18 03:28:27 +00:00
parent 1291e40d3d
commit 6139043b1f
3 changed files with 14 additions and 35 deletions

View File

@ -703,7 +703,6 @@ trap_pfault(frame, usermode, eva)
else
ftype = VM_PROT_READ;
mtx_lock(&Giant);
if (map != kernel_map) {
/*
* Keep swapout from messing with us during this
@ -713,20 +712,8 @@ trap_pfault(frame, usermode, eva)
++p->p_lock;
PROC_UNLOCK(p);
/*
* Grow the stack if necessary
*/
/* vm_map_growstack fails only if va falls into
* a growable stack region and the stack growth
* fails. It succeeds if va was not within
* a growable stack region, or if the stack
* growth succeeded.
*/
if (vm_map_growstack(p, va) != KERN_SUCCESS)
rv = KERN_FAILURE;
else
/* Fault in the user page: */
rv = vm_fault(map, va, ftype,
/* Fault in the user page: */
rv = vm_fault(map, va, ftype,
(ftype & VM_PROT_WRITE) ? VM_FAULT_DIRTY
: VM_FAULT_NORMAL);
@ -740,8 +727,6 @@ trap_pfault(frame, usermode, eva)
*/
rv = vm_fault(map, va, ftype, VM_FAULT_NORMAL);
}
mtx_unlock(&Giant);
if (rv == KERN_SUCCESS)
return (0);
nogo:

View File

@ -703,7 +703,6 @@ trap_pfault(frame, usermode, eva)
else
ftype = VM_PROT_READ;
mtx_lock(&Giant);
if (map != kernel_map) {
/*
* Keep swapout from messing with us during this
@ -713,20 +712,8 @@ trap_pfault(frame, usermode, eva)
++p->p_lock;
PROC_UNLOCK(p);
/*
* Grow the stack if necessary
*/
/* vm_map_growstack fails only if va falls into
* a growable stack region and the stack growth
* fails. It succeeds if va was not within
* a growable stack region, or if the stack
* growth succeeded.
*/
if (vm_map_growstack(p, va) != KERN_SUCCESS)
rv = KERN_FAILURE;
else
/* Fault in the user page: */
rv = vm_fault(map, va, ftype,
/* Fault in the user page: */
rv = vm_fault(map, va, ftype,
(ftype & VM_PROT_WRITE) ? VM_FAULT_DIRTY
: VM_FAULT_NORMAL);
@ -740,8 +727,6 @@ trap_pfault(frame, usermode, eva)
*/
rv = vm_fault(map, va, ftype, VM_FAULT_NORMAL);
}
mtx_unlock(&Giant);
if (rv == KERN_SUCCESS)
return (0);
nogo:

View File

@ -203,7 +203,7 @@ vm_fault1(vm_map_t map, vm_offset_t vaddr, vm_prot_t fault_type,
{
vm_prot_t prot;
int result;
boolean_t wired;
boolean_t growstack, wired;
int map_generation;
vm_object_t next_object;
vm_page_t marray[VM_FAULT_READ];
@ -215,6 +215,7 @@ vm_fault1(vm_map_t map, vm_offset_t vaddr, vm_prot_t fault_type,
cnt.v_vm_faults++;
hardfault = 0;
growstack = TRUE;
RetryFault:;
@ -228,6 +229,14 @@ RetryFault:;
&fs.first_pindex, &prot, &wired)) != KERN_SUCCESS) {
if ((result != KERN_PROTECTION_FAILURE) ||
((fault_flags & VM_FAULT_WIRE_MASK) != VM_FAULT_USER_WIRE)) {
if (growstack && result == KERN_INVALID_ADDRESS &&
map != kernel_map && curproc != NULL) {
result = vm_map_growstack(curproc, vaddr);
if (result != KERN_SUCCESS)
return (KERN_FAILURE);
growstack = FALSE;
goto RetryFault;
}
return result;
}