Index: sys/vm/vm_glue.c =================================================================== --- sys/vm/vm_glue.c +++ sys/vm/vm_glue.c @@ -863,22 +863,32 @@ struct vmspace *vm; int minslptime = 100000; int slptime; - + + PROC_LOCK(p); /* * Watch out for a process in * creation. It may have no * address space or lock yet. */ - if (p->p_state == PRS_NEW) + if (p->p_state == PRS_NEW) { + PROC_UNLOCK(p); continue; + } /* * An aio daemon switches its * address space while running. * Perform a quick check whether * a process has P_SYSTEM. + * Filter out exiting processes. */ - if ((p->p_flag & P_SYSTEM) != 0) + if ((p->p_flag & (P_SYSTEM | P_WEXIT)) != 0) { + PROC_UNLOCK(p); continue; + } + p->p_lock++; + PROC_UNLOCK(p); + sx_sunlock(&allproc_lock); + /* * Do not swapout a process that * is waiting for VM data @@ -893,16 +903,15 @@ */ vm = vmspace_acquire_ref(p); if (vm == NULL) - continue; + goto nextproc2; if (!vm_map_trylock(&vm->vm_map)) goto nextproc1; PROC_LOCK(p); - if (p->p_lock != 0 || - (p->p_flag & (P_STOPPED_SINGLE|P_TRACED|P_SYSTEM|P_WEXIT) - ) != 0) { + if (p->p_lock != 1 || (p->p_flag & (P_STOPPED_SINGLE | + P_TRACED | P_SYSTEM)) != 0) goto nextproc; - } + /* * only aiod changes vmspace, however it will be * skipped because of the if statement above checking @@ -977,12 +986,12 @@ if ((action & VM_SWAP_NORMAL) || ((action & VM_SWAP_IDLE) && (minslptime > swap_idle_threshold2))) { + _PRELE(p); if (swapout(p) == 0) didswap++; PROC_UNLOCK(p); vm_map_unlock(&vm->vm_map); vmspace_free(vm); - sx_sunlock(&allproc_lock); goto retry; } } @@ -991,7 +1000,9 @@ vm_map_unlock(&vm->vm_map); nextproc1: vmspace_free(vm); - continue; +nextproc2: + sx_slock(&allproc_lock); + PRELE(p); } sx_sunlock(&allproc_lock); /* Index: sys/vm/vm_meter.c =================================================================== --- sys/vm/vm_meter.c +++ sys/vm/vm_meter.c @@ -159,6 +159,11 @@ thread_unlock(td); } } + if ((p->p_flag & P_WEXIT) != 0) { + PROC_UNLOCK(p); + continue; + } + p->p_lock++; /* avoid _PHOLD, no need for faultin() */ PROC_UNLOCK(p); } sx_sunlock(&allproc_lock); Index: sys/vm/vm_pageout.c =================================================================== --- sys/vm/vm_pageout.c +++ sys/vm/vm_pageout.c @@ -1485,19 +1485,21 @@ PROC_UNLOCK(p); continue; } - _PHOLD(p); + p->p_lock++; + PROC_UNLOCK(p); + sx_sunlock(&allproc_lock); if (!vm_map_trylock_read(&vm->vm_map)) { - _PRELE(p); - PROC_UNLOCK(p); vmspace_free(vm); + sx_slock(&allproc_lock); + PRELE(p); continue; } - PROC_UNLOCK(p); size = vmspace_swap_count(vm); if (shortage == VM_OOM_MEM) size += vm_pageout_oom_pagecount(vm); vm_map_unlock_read(&vm->vm_map); vmspace_free(vm); + sx_slock(&allproc_lock); /* * If this process is bigger than the biggest one, @@ -1812,9 +1814,13 @@ if ((p->p_flag & P_INMEM) == 0) limit = 0; /* XXX */ vm = vmspace_acquire_ref(p); + p->p_lock++; PROC_UNLOCK(p); - if (vm == NULL) + if (vm == NULL) { + PRELE(p); continue; + } + sx_sunlock(&allproc_lock); size = vmspace_resident_count(vm); if (size >= limit) { @@ -1859,6 +1865,8 @@ } #endif vmspace_free(vm); + sx_slock(&allproc_lock); + PRELE(p); } sx_sunlock(&allproc_lock); if (tryagain != 0 && attempts <= 10)