From e215ab3b02bae1355e92de58c118eb0032066bf1 Mon Sep 17 00:00:00 2001 From: kib Date: Sun, 19 Apr 2009 20:53:47 +0000 Subject: 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 --- sys/vm/vm_pageout.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) (limited to 'sys') 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); } -- cgit v1.1