summaryrefslogtreecommitdiffstats
path: root/sys/vm
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2015-01-31 11:02:20 +0000
committerkib <kib@FreeBSD.org>2015-01-31 11:02:20 +0000
commit8cc5d657dc11a2cf776cd3d403699c2e89344b5d (patch)
tree41e1d64f3a589df4f930181cc5f2678965e45604 /sys/vm
parent11512d9430ef0d6ffd4996c18aa37368253f4934 (diff)
downloadFreeBSD-src-8cc5d657dc11a2cf776cd3d403699c2e89344b5d.zip
FreeBSD-src-8cc5d657dc11a2cf776cd3d403699c2e89344b5d.tar.gz
MFC r277646:
Avoid calling vmspace_free() while owning the process lock.
Diffstat (limited to 'sys/vm')
-rw-r--r--sys/vm/vm_pageout.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c
index 3154ce3..3cd1e54 100644
--- a/sys/vm/vm_pageout.c
+++ b/sys/vm/vm_pageout.c
@@ -1526,15 +1526,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;
}
@@ -1567,11 +1567,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)
@@ -1583,16 +1586,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(&cnt.v_free_count);
}
OpenPOWER on IntegriCloud