I'm newbie on Linux Kernel.
Currently, I looked into idle codes and had a quesition.
When processor doesn't have any taks in their own runqueue then it may
go into idle mode, specific WFI(wating for interrupt).
(All I mentioned is about ARM architecture not X86. So something is wrong for X86.)
After staying in WFI state, maybe other processor(not idle) want to spread
their task to this, idle processor(by load balance). At that time a busy processor
makes task imigrated. In my point of view, when the task is imigrated, the idle processor
should wake up immidiatley to process the task. right? However, I couldn't find
any codes waking up idle processor but only found codes about registering task to idle processor's runqueue.
I'd like to know what mechanism is behind of waking processor up when new task is given.
Or it just move task from one queue to other's than let it be until woken up by
some unpredictable IRQ?
Please show me the truth :)
WFI
is a special co-processor instruction for the ARM. For example,
ENTRY(cpu_arm946_do_idle)
mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
mov pc, lr
It has nothing to do with Linux (directly).
There is a special idle
task that runs the WFI
instruction on the ARM, if there is no work to do. The idle
task is the very lowest priority Linux task, scheduled if there is nothing else. If WFI
is done by idle
, some driver will interrupt (maybe a timer) when there is no work to do. In the SMP case, it will not go to idle
if there are other processes that can be migrated; the scheduler checks this. If a load gets high, then the busy processor needs to wake
the others; In the case of an ARM with an interrupt. Usually this handling is in arch/arch/kernel/process.c. For example the x86 has default_idle()
. I don't know specifics of how the x86 works, but you can look at the source.
For your question How does linux kernel wake idle processor up when new task created?, the answer is it doesn't. Only fork()
(and some similar functions) can create a new task; originally from the init
task and then one of it's children. If you have a cron
job, it will have scheduled a timer before it goes to sleep/idle
. This timer will wake the system, re-schedule cron
and then cron
will call fork()
, to create the new task.
Other related mechanisms are cpufreq
, cpuidle
, kernel/power
etc.
The truth is always objective/subjective and certainly is not global. Show me the metric
for the truth and I can show you the truth.
just set the CPU's flag like below code after create the thread.
= > thread's task_struct->flags |= PF_WAKE_UP_IDLE;
look at select_task_rq_fair(), which is CFS::select_task_rq() method.
This is most representative case where the scheduler wakes up the idle task for re-balancing run-queues.
smp_send_reschedule()
will send IPI_RESCHEDULE
to the processor that is idle. This will wake it up from wfi
. It is called from couple of places, one example being wake_up_process -> try_to_wake_up -> try_to_wake_up -> ttwu_queue -> ttwu_queue_remote
(function names from kernel 3.4).