idle(): recheck runq just before cpu status check
There is a problem which causes wait4(2) hang when wait4(2) called by a process races with its child process termination. This is a quick fix for this problem. See idle(). refs #271
This commit is contained in:
@@ -1789,6 +1789,38 @@ static void idle(void)
|
|||||||
while (1) {
|
while (1) {
|
||||||
schedule();
|
schedule();
|
||||||
cpu_disable_interrupt();
|
cpu_disable_interrupt();
|
||||||
|
/*
|
||||||
|
* XXX: KLUDGE: It is desirable to be resolved in schedule().
|
||||||
|
*
|
||||||
|
* There is a problem which causes wait4(2) hang when
|
||||||
|
* wait4(2) called by a process races with its child process
|
||||||
|
* termination. This is a quick fix for this problem.
|
||||||
|
*
|
||||||
|
* The problem occurrd in the following sequence.
|
||||||
|
* 1) The parent process called schedule() from sys_wait4() to
|
||||||
|
* wait for an event generated by the child process.
|
||||||
|
* 2) schedule() resumed the idle process because there was no
|
||||||
|
* runnable process in run queue.
|
||||||
|
* 3) At the moment, the child process began to end. It set
|
||||||
|
* the parent process runnable, and sent an interrupt to
|
||||||
|
* the parent process's cpu. But this interrupt had no
|
||||||
|
* effect because the parent process's cpu had not halted.
|
||||||
|
* 4) The idle process was resumed, and halted for waiting for
|
||||||
|
* the interrupt that had already been handled.
|
||||||
|
*/
|
||||||
|
if (v->status == CPU_STATUS_IDLE) {
|
||||||
|
long s;
|
||||||
|
struct process *p;
|
||||||
|
|
||||||
|
s = ihk_mc_spinlock_lock(&v->runq_lock);
|
||||||
|
list_for_each_entry(p, &v->runq, sched_list) {
|
||||||
|
if (p->status == PS_RUNNING) {
|
||||||
|
v->status = CPU_STATUS_RUNNING;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ihk_mc_spinlock_unlock(&v->runq_lock, s);
|
||||||
|
}
|
||||||
if (v->status == CPU_STATUS_IDLE) {
|
if (v->status == CPU_STATUS_IDLE) {
|
||||||
cpu_safe_halt();
|
cpu_safe_halt();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user