diff options
author | kib <kib@FreeBSD.org> | 2009-04-19 20:53:47 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2009-04-19 20:53:47 +0000 |
commit | e215ab3b02bae1355e92de58c118eb0032066bf1 (patch) | |
tree | 49d8843d5ddc2a8d945252f807b8b25e30b906fd /sys/vm | |
parent | 8df790f38fc6501dadb8302ef4a236525bb7d2c4 (diff) | |
download | FreeBSD-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')
-rw-r--r-- | sys/vm/vm_pageout.c | 29 |
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); } |