Hi, Currently trap_pfault for each of the three DragonFly platforms attempts to grow the stack region (via growstack()) before attempting vm_fault. For any faults not in stack growth regions, this will result in lots of work (3 crit_enter/crit_exit pairs, a number of zone allocations). Would it be worth moving the stack growth call into vm_fault, after the vm_map_lookup call?
Here is a patch that does this: (to sys/platform/<T>/<A>/trap.c): --- trap.c.orig 2010-02-26 06:17:34 -0800 +++ trap.c 2010-02-26 06:17:54 -0800 @@ -989,21 +989,6 @@ PHOLD(lp->lwp_proc); - /* - * Grow the stack if necessary - */ - /* grow_stack returns false only if va falls into - * a growable stack region and the stack growth - * fails. It returns true if va was not within - * a growable stack region, or if the stack - * growth succeeded. - */ - if (!grow_stack(lp->lwp_proc, va)) { - rv = KERN_FAILURE; - PRELE(lp->lwp_proc); - goto nogo; - } - /* * Issue fault */ fault_flags = 0; To vm/vm_fault.c: diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index 0fae064..7fd0998 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -223,12 +223,14 @@ vm_fault(vm_map_t map, vm_offset_t vaddr, vm_prot_t fault_type, int fault_flags) int result; vm_pindex_t first_pindex; struct faultstate fs; + int growstack; mycpu->gd_cnt.v_vm_faults++; fs.didlimit = 0; fs.hardfault = 0; fs.fault_flags = fault_flags; + growstack = 1; RetryFault: /* @@ -256,10 +258,21 @@ RetryFault: * to do a user wiring we have more work to do. */ if (result != KERN_SUCCESS) { - if (result != KERN_PROTECTION_FAILURE) - return result; - if ((fs.fault_flags & VM_FAULT_WIRE_MASK) != VM_FAULT_USER_WIRE) - return result; + if (result != KERN_PROTECTION_FAILURE || + (fs.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 = 0; + goto RetryFault; + } + return (result); + } /* * If we are user-wiring a r/w segment, and it is COW, then I'm not currently setup to measure the speed differences or the distribution of faults, to know whether this is a good idea... does this seem reasonable? Thanks, -- vs