summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2002-04-18 03:28:27 +0000
committeralc <alc@FreeBSD.org>2002-04-18 03:28:27 +0000
commit50de41829507706df2569f9a0e93027eeae643ba (patch)
tree57e433fbfb84752f26c5e79b5807c33bcc47be22 /sys
parent431577d47c148bc21bb3bb402bf92354832c65e1 (diff)
downloadFreeBSD-src-50de41829507706df2569f9a0e93027eeae643ba.zip
FreeBSD-src-50de41829507706df2569f9a0e93027eeae643ba.tar.gz
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.)
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/amd64/trap.c19
-rw-r--r--sys/i386/i386/trap.c19
-rw-r--r--sys/vm/vm_fault.c11
3 files changed, 14 insertions, 35 deletions
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index 30af1b6..d72689d 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -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:
diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c
index 30af1b6..d72689d 100644
--- a/sys/i386/i386/trap.c
+++ b/sys/i386/i386/trap.c
@@ -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:
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index 81f89f5..2d46350 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -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;
}
OpenPOWER on IntegriCloud