wake_up vs. wake_up_sync
Quoted 6 lines
I'm having trouble understanding the difference between these. Synchronous apparently causes
try_to_wake_up()to NOT callreschedule_idle()but I'm uncertain whatreschedule_idle()is doing. I assume it just looks for an idle CPU and makes that CPU reschedule.What is the purpose of
wake_up_sync?
Avoid the reschedule_idle() call - it's quite costly, and it could cause processes jumping from one cpu to another.
Quoted 3 lines
Why would you want to prevent
reschedule_idle()?
If one process runs, wakes up another process and _knows_ that it's going to sleep immediately after the wake_up it doesn't need thereschedule_idle: the current cpu will be idle soon, the scheduler doesn't need to find another cpu for the woken up thread.
I think the pipe code is the only user of _sync right now - pipes cause an incredible amount of task switches.
--
Manfred
Quoted 7 lines · Manfred Spraul
Quoted 3 lines
Why would you want to prevent
reschedule_idle()?If one process runs, wakes up another process and _knows_ that it's going to sleep immediately after the
wake_upit doesn't need thereschedule_idle: the current cpu will be idle soon, the scheduler doesn't need to find another cpu for the woken up thread.
I'm curious. How does the caller of wake_up_sync know that the current cpu will soon be idle. Does it assume that there are no other tasks on the runqueue waiting for a CPU? If there are other tasks on the runqueue, isn't it possible that another task has a higher goodness value than the task being awakened. In such a case, isn't is possible that the awakened task could sit on the runqueue (waiting for a CPU) while tasks with a lower goodness value are allowed to run?
Signature · 2 lines
Mike Kravetz [email protected] IBM Linux Technology Center
Does reschedule_idle() ever cause the current CPU to get scheduled? That is, if someone calls wake_up() and wakes up a higher-priority process could reschedule_idle() potentially immediately switch the current CPU to that higher-priority process?
Because this is NOT what I want to happen (it would produce a deadlock in this particular situation). Having other CPUs get scheduled is ok, but having the process that called wake_up() get kicked out would be very bad. In that case I suppose I will have to use wake_up_sync().
Would the following be an appropriate solution?
{
wake_up_sync(&wq->q);
/* Potential deadlock situation */
user_unlock(&wq->lock);
/* Potential for deadlock has passed */
reschedule_idle();
}Thanks,
Scott
Quoted 24 lines · Manfred Spraul
Quoted 7 lines
I'm having trouble understanding the difference between these. Synchronous apparently causes
try_to_wake_up()to NOT callreschedule_idle()but I'm uncertain whatreschedule_idle()is doing. I assume it just looks for an idle CPU and makes that CPU reschedule.What is the purpose of
wake_up_sync?Avoid the
reschedule_idle()call - it's quite costly, and it could cause processes jumping from one cpu to another.Quoted 3 lines
Why would you want to prevent
reschedule_idle()?If one process runs, wakes up another process and _knows_ that it's going to sleep immediately after the
wake_upit doesn't need thereschedule_idle: the current cpu will be idle soon, the scheduler doesn't need to find another cpu for the woken up thread.I think the pipe code is the only user of
_syncright now - pipes cause an incredible amount of task switches.--
Manfred
Quoted 4 lines · Scott Long
Does
reschedule_idle()ever cause the current CPU to get scheduled? That is, if someone callswake_up()and wakes up a higher-priority process couldreschedule_idle()potentially immediately switch the current CPU to that higher-priority process?
No. reschedule_idle() never directly performs a 'task to task' context switch itself. Instead, it simply marks a currently running task to indicate that a reschedule is needed on that task's CPU. No task context switch will occur until schedule() is run on that CPU.
Signature · 2 lines
Mike Kravetz [email protected] IBM Linux Technology Center
Quoted 10 lines · Mike Kravetz
Quoted 7 lines · Manfred Spraul
Quoted 3 lines
Why would you want to prevent
reschedule_idle()?If one process runs, wakes up another process and _knows_ that it's going to sleep immediately after the
wake_upit doesn't need thereschedule_idle: the current cpu will be idle soon, the scheduler doesn't need to find another cpu for the woken up thread.
Quoted 9 lines
I'm curious. How does the caller of
wake_up_syncknow that the current cpu will soon be idle. Does it assume that there are no other tasks on the runqueue waiting for a CPU? If there are other tasks on the runqueue, isn't it possible that another task has a higher goodness value than the task being awakened. In such a case, isn't is possible that the awakened task could sit on the runqueue (waiting for a CPU) while tasks with a lower goodness value are allowed to run?
I found one combination where that could happen:
process.thread
A.1: highest priority, runs on cpu0
B.1: lowest priority, runs on cpu1
A.2: another thread of process A, priority PROC_CHANGE_PENALTY+PRIORITY(B.1)+1, sleeping. B.2: same priority as A.2, sleeping, same process as B.1
A.1:
{
wake_up("A.2");
/* nothing happens: preemption_goodness is 0 since B.1 has both
PROC_CHANGE_PENALTY and the += 1 from 'same mm'
*/
wake_up_sync("B.2");
schedule();
/* schedule selects A.2 instead of B.2 due to the += 1 from 'same mm'.
BUG: B.2 should replace B.1 on cpu1. The preemption_goodness is 1.*/
IMHO obscure and very rare.
But I just found a bigger problem:
If wake_up_sync wakes up more than 1 process then cpus could remain in cpu_idle() although processes are on the runqueue without cpus.
--
Manfred