During the code to pick a process to kill when memory is exhausted, keep

the process in question locked as soon as we find it and determine it to
be eligible until we actually kill it.  To avoid deadlock, we don't block
on the process lock but skip any process that is already locked during our
search.
This commit is contained in:
John Baldwin 2001-05-17 22:49:03 +00:00
parent 1ad5401134
commit 1c58e4e550

View File

@ -1121,23 +1121,33 @@ vm_pageout_scan(int pass)
/*
* make sure that we have swap space -- if we are low on memory and
* swap -- then kill the biggest process.
*
* We keep the process bigproc locked once we find it to keep anyone
* from messing with it; however, there is a possibility of
* deadlock if process B is bigproc and one of it's child processes
* attempts to propagate a signal to B while we are waiting for A's
* lock while walking this list. To avoid this, we don't block on
* the process lock but just skip a process if it is already locked.
*/
if ((vm_swap_size < 64 || swap_pager_full) && vm_page_count_min()) {
bigproc = NULL;
bigsize = 0;
sx_slock(&allproc_lock);
LIST_FOREACH(p, &allproc, p_list) {
/*
* If this process is already locked, skip it.
*/
if (PROC_TRYLOCK(p) == 0)
continue;
/*
* if this is a system process, skip it
*/
PROC_LOCK(p);
if ((p->p_flag & P_SYSTEM) || (p->p_lock > 0) ||
(p->p_pid == 1) ||
((p->p_pid < 48) && (vm_swap_size != 0))) {
PROC_UNLOCK(p);
continue;
}
PROC_UNLOCK(p);
/*
* if the process is in a non-running type state,
* don't touch it.
@ -1145,6 +1155,7 @@ vm_pageout_scan(int pass)
mtx_lock_spin(&sched_lock);
if (p->p_stat != SRUN && p->p_stat != SSLEEP) {
mtx_unlock_spin(&sched_lock);
PROC_UNLOCK(p);
continue;
}
mtx_unlock_spin(&sched_lock);
@ -1157,9 +1168,12 @@ vm_pageout_scan(int pass)
* remember it.
*/
if (size > bigsize) {
if (bigproc != NULL)
PROC_UNLOCK(bigproc);
bigproc = p;
bigsize = size;
}
} else
PROC_UNLOCK(p);
}
sx_sunlock(&allproc_lock);
if (bigproc != NULL) {
@ -1169,6 +1183,7 @@ vm_pageout_scan(int pass)
bigproc->p_nice = PRIO_MIN;
resetpriority(bigproc);
mtx_unlock_spin(&sched_lock);
PROC_UNLOCK(bigproc);
wakeup(&cnt.v_free_count);
}
}