svn commit: r277646 - head/sys/vm
Konstantin Belousov
kib at FreeBSD.org
Sat Jan 24 15:33:43 UTC 2015
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);
}
More information about the svn-src-all
mailing list