diff options
author | alc <alc@FreeBSD.org> | 2002-04-18 03:28:27 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2002-04-18 03:28:27 +0000 |
commit | 50de41829507706df2569f9a0e93027eeae643ba (patch) | |
tree | 57e433fbfb84752f26c5e79b5807c33bcc47be22 /sys | |
parent | 431577d47c148bc21bb3bb402bf92354832c65e1 (diff) | |
download | FreeBSD-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.c | 19 | ||||
-rw-r--r-- | sys/i386/i386/trap.c | 19 | ||||
-rw-r--r-- | sys/vm/vm_fault.c | 11 |
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; } |