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"

Reply via email to