Date: Sun, 19 Apr 2009 20:53:47 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r191277 - head/sys/vm Message-ID: <200904192053.n3JKrl4T019903@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Sun Apr 19 20:53:47 2009 New Revision: 191277 URL: http://svn.freebsd.org/changeset/base/191277 Log: 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 Modified: head/sys/vm/vm_pageout.c Modified: head/sys/vm/vm_pageout.c ============================================================================== --- head/sys/vm/vm_pageout.c Sun Apr 19 20:19:13 2009 (r191276) +++ head/sys/vm/vm_pageout.c Sun Apr 19 20:53:47 2009 (r191277) @@ -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); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200904192053.n3JKrl4T019903>