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
|
else
|
||||||
ftype = VM_PROT_READ;
|
ftype = VM_PROT_READ;
|
||||||
|
|
||||||
mtx_lock(&Giant);
|
|
||||||
if (map != kernel_map) {
|
if (map != kernel_map) {
|
||||||
/*
|
/*
|
||||||
* Keep swapout from messing with us during this
|
* Keep swapout from messing with us during this
|
||||||
@ -713,20 +712,8 @@ trap_pfault(frame, usermode, eva)
|
|||||||
++p->p_lock;
|
++p->p_lock;
|
||||||
PROC_UNLOCK(p);
|
PROC_UNLOCK(p);
|
||||||
|
|
||||||
/*
|
/* Fault in the user page: */
|
||||||
* Grow the stack if necessary
|
rv = vm_fault(map, va, ftype,
|
||||||
*/
|
|
||||||
/* 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,
|
|
||||||
(ftype & VM_PROT_WRITE) ? VM_FAULT_DIRTY
|
(ftype & VM_PROT_WRITE) ? VM_FAULT_DIRTY
|
||||||
: VM_FAULT_NORMAL);
|
: VM_FAULT_NORMAL);
|
||||||
|
|
||||||
@ -740,8 +727,6 @@ trap_pfault(frame, usermode, eva)
|
|||||||
*/
|
*/
|
||||||
rv = vm_fault(map, va, ftype, VM_FAULT_NORMAL);
|
rv = vm_fault(map, va, ftype, VM_FAULT_NORMAL);
|
||||||
}
|
}
|
||||||
mtx_unlock(&Giant);
|
|
||||||
|
|
||||||
if (rv == KERN_SUCCESS)
|
if (rv == KERN_SUCCESS)
|
||||||
return (0);
|
return (0);
|
||||||
nogo:
|
nogo:
|
||||||
|
@ -703,7 +703,6 @@ trap_pfault(frame, usermode, eva)
|
|||||||
else
|
else
|
||||||
ftype = VM_PROT_READ;
|
ftype = VM_PROT_READ;
|
||||||
|
|
||||||
mtx_lock(&Giant);
|
|
||||||
if (map != kernel_map) {
|
if (map != kernel_map) {
|
||||||
/*
|
/*
|
||||||
* Keep swapout from messing with us during this
|
* Keep swapout from messing with us during this
|
||||||
@ -713,20 +712,8 @@ trap_pfault(frame, usermode, eva)
|
|||||||
++p->p_lock;
|
++p->p_lock;
|
||||||
PROC_UNLOCK(p);
|
PROC_UNLOCK(p);
|
||||||
|
|
||||||
/*
|
/* Fault in the user page: */
|
||||||
* Grow the stack if necessary
|
rv = vm_fault(map, va, ftype,
|
||||||
*/
|
|
||||||
/* 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,
|
|
||||||
(ftype & VM_PROT_WRITE) ? VM_FAULT_DIRTY
|
(ftype & VM_PROT_WRITE) ? VM_FAULT_DIRTY
|
||||||
: VM_FAULT_NORMAL);
|
: VM_FAULT_NORMAL);
|
||||||
|
|
||||||
@ -740,8 +727,6 @@ trap_pfault(frame, usermode, eva)
|
|||||||
*/
|
*/
|
||||||
rv = vm_fault(map, va, ftype, VM_FAULT_NORMAL);
|
rv = vm_fault(map, va, ftype, VM_FAULT_NORMAL);
|
||||||
}
|
}
|
||||||
mtx_unlock(&Giant);
|
|
||||||
|
|
||||||
if (rv == KERN_SUCCESS)
|
if (rv == KERN_SUCCESS)
|
||||||
return (0);
|
return (0);
|
||||||
nogo:
|
nogo:
|
||||||
|
@ -203,7 +203,7 @@ vm_fault1(vm_map_t map, vm_offset_t vaddr, vm_prot_t fault_type,
|
|||||||
{
|
{
|
||||||
vm_prot_t prot;
|
vm_prot_t prot;
|
||||||
int result;
|
int result;
|
||||||
boolean_t wired;
|
boolean_t growstack, wired;
|
||||||
int map_generation;
|
int map_generation;
|
||||||
vm_object_t next_object;
|
vm_object_t next_object;
|
||||||
vm_page_t marray[VM_FAULT_READ];
|
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++;
|
cnt.v_vm_faults++;
|
||||||
hardfault = 0;
|
hardfault = 0;
|
||||||
|
growstack = TRUE;
|
||||||
|
|
||||||
RetryFault:;
|
RetryFault:;
|
||||||
|
|
||||||
@ -228,6 +229,14 @@ RetryFault:;
|
|||||||
&fs.first_pindex, &prot, &wired)) != KERN_SUCCESS) {
|
&fs.first_pindex, &prot, &wired)) != KERN_SUCCESS) {
|
||||||
if ((result != KERN_PROTECTION_FAILURE) ||
|
if ((result != KERN_PROTECTION_FAILURE) ||
|
||||||
((fault_flags & VM_FAULT_WIRE_MASK) != VM_FAULT_USER_WIRE)) {
|
((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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user