Author: kib Date: Sat Jan 24 15:33:42 2015 New Revision: 277646 URL: https://svnweb.freebsd.org/changeset/base/277646
Log: Avoid calling vmspace_free() while owning the process lock. Freeing of an vm space may require obtaining sleepable locks. Hold the process to keep the pointer valid, and change trylock to lock, since there is no longer two process locks owned simultaneously in vm_pageout_oom(). Note that after the process lock is dropped, process might exec, and no longer qualify as the owner of biggest vm space. In collaboration with: rstone Sponsored by: The FreeBSD Foundation MFC after: 1 week Modified: head/sys/vm/vm_pageout.c Modified: head/sys/vm/vm_pageout.c ============================================================================== --- head/sys/vm/vm_pageout.c Sat Jan 24 13:50:13 2015 (r277645) +++ head/sys/vm/vm_pageout.c Sat Jan 24 15:33:42 2015 (r277646) @@ -1516,15 +1516,15 @@ vm_pageout_oom(int shortage) FOREACH_PROC_IN_SYSTEM(p) { int breakout; - if (PROC_TRYLOCK(p) == 0) - continue; + PROC_LOCK(p); + /* * If this is a system, protected or killed process, skip it. */ - if (p->p_state != PRS_NORMAL || - (p->p_flag & (P_INEXEC | P_PROTECTED | P_SYSTEM)) || - (p->p_pid == 1) || P_KILLED(p) || - ((p->p_pid < 48) && (swap_pager_avail != 0))) { + if (p->p_state != PRS_NORMAL || (p->p_flag & (P_INEXEC | + P_PROTECTED | P_SYSTEM | P_WEXIT)) != 0 || + p->p_pid == 1 || P_KILLED(p) || + (p->p_pid < 48 && swap_pager_avail != 0)) { PROC_UNLOCK(p); continue; } @@ -1557,11 +1557,14 @@ vm_pageout_oom(int shortage) PROC_UNLOCK(p); continue; } + _PHOLD(p); if (!vm_map_trylock_read(&vm->vm_map)) { - vmspace_free(vm); + _PRELE(p); PROC_UNLOCK(p); + vmspace_free(vm); continue; } + PROC_UNLOCK(p); size = vmspace_swap_count(vm); vm_map_unlock_read(&vm->vm_map); if (shortage == VM_OOM_MEM) @@ -1573,16 +1576,19 @@ vm_pageout_oom(int shortage) */ if (size > bigsize) { if (bigproc != NULL) - PROC_UNLOCK(bigproc); + PRELE(bigproc); bigproc = p; bigsize = size; - } else - PROC_UNLOCK(p); + } else { + PRELE(p); + } } sx_sunlock(&allproc_lock); if (bigproc != NULL) { + PROC_LOCK(bigproc); killproc(bigproc, "out of swap space"); sched_nice(bigproc, PRIO_MIN); + _PRELE(bigproc); PROC_UNLOCK(bigproc); wakeup(&vm_cnt.v_free_count); } _______________________________________________ svn-src-head@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"