summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_pageout.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2009-04-19 20:53:47 +0000
committerkib <kib@FreeBSD.org>2009-04-19 20:53:47 +0000
commite215ab3b02bae1355e92de58c118eb0032066bf1 (patch)
tree49d8843d5ddc2a8d945252f807b8b25e30b906fd /sys/vm/vm_pageout.c
parent8df790f38fc6501dadb8302ef4a236525bb7d2c4 (diff)
downloadFreeBSD-src-e215ab3b02bae1355e92de58c118eb0032066bf1.zip
FreeBSD-src-e215ab3b02bae1355e92de58c118eb0032066bf1.tar.gz
In both pageout oom handler and vm_daemon, acquire the reference to
the vmspace of the examined process instead of directly accessing its vmspace, that may change. Also, as an optimization, check for P_INEXEC flag before examining the process. Reported and tested by: pho (previous version) Reviewed by: alc MFC after: 3 week
Diffstat (limited to 'sys/vm/vm_pageout.c')
-rw-r--r--sys/vm/vm_pageout.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c
index 2baa0f1..bfc343b 100644
--- a/sys/vm/vm_pageout.c
+++ b/sys/vm/vm_pageout.c
@@ -1183,6 +1183,7 @@ vm_pageout_oom(int shortage)
struct proc *p, *bigproc;
vm_offset_t size, bigsize;
struct thread *td;
+ struct vmspace *vm;
/*
* We keep the process bigproc locked once we find it to keep anyone
@@ -1203,8 +1204,8 @@ vm_pageout_oom(int shortage)
/*
* If this is a system or protected process, skip it.
*/
- if ((p->p_flag & P_SYSTEM) || (p->p_pid == 1) ||
- (p->p_flag & P_PROTECTED) ||
+ if ((p->p_flag & (P_INEXEC | P_PROTECTED | P_SYSTEM)) ||
+ (p->p_pid == 1) ||
((p->p_pid < 48) && (swap_pager_avail != 0))) {
PROC_UNLOCK(p);
continue;
@@ -1232,14 +1233,21 @@ vm_pageout_oom(int shortage)
/*
* get the process size
*/
- if (!vm_map_trylock_read(&p->p_vmspace->vm_map)) {
+ vm = vmspace_acquire_ref(p);
+ if (vm == NULL) {
+ PROC_UNLOCK(p);
+ continue;
+ }
+ if (!vm_map_trylock_read(&vm->vm_map)) {
+ vmspace_free(vm);
PROC_UNLOCK(p);
continue;
}
size = vmspace_swap_count(p->p_vmspace);
- vm_map_unlock_read(&p->p_vmspace->vm_map);
+ vm_map_unlock_read(&vm->vm_map);
if (shortage == VM_OOM_MEM)
- size += vmspace_resident_count(p->p_vmspace);
+ size += vmspace_resident_count(vm);
+ vmspace_free(vm);
/*
* if the this process is bigger than the biggest one
* remember it.
@@ -1532,6 +1540,7 @@ vm_daemon()
struct rlimit rsslim;
struct proc *p;
struct thread *td;
+ struct vmspace *vm;
int breakout, swapout_flags;
while (TRUE) {
@@ -1556,7 +1565,7 @@ vm_daemon()
* looked at this process, skip it.
*/
PROC_LOCK(p);
- if (p->p_flag & (P_SYSTEM | P_WEXIT)) {
+ if (p->p_flag & (P_INEXEC | P_SYSTEM | P_WEXIT)) {
PROC_UNLOCK(p);
continue;
}
@@ -1594,13 +1603,17 @@ vm_daemon()
*/
if ((p->p_flag & P_INMEM) == 0)
limit = 0; /* XXX */
+ vm = vmspace_acquire_ref(p);
PROC_UNLOCK(p);
+ if (vm == NULL)
+ continue;
- size = vmspace_resident_count(p->p_vmspace);
+ size = vmspace_resident_count(vm);
if (limit >= 0 && size >= limit) {
vm_pageout_map_deactivate_pages(
- &p->p_vmspace->vm_map, limit);
+ &vm->vm_map, limit);
}
+ vmspace_free(vm);
}
sx_sunlock(&allproc_lock);
}
OpenPOWER on IntegriCloud