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:
parent
1291e40d3d
commit
6139043b1f
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user