2014年9月14日 星期日

scheduler_tick()


sourcel:scheduler_tick()



2493 void scheduler_tick(void)
2494 {
2495         int cpu = smp_processor_id();/*目前的CPU ID*/
2496         struct rq *rq = cpu_rq(cpu);/*前CPU的 RunQueue指標*/
2497         struct task_struct *curr = rq->curr;/*目前RunQueue中正在執行的Curr Task指標*/
2499         sched_clock_tick();
/*呼叫 sched_clock_tick(實作在kernel/sched_clock.c中),這函式需在有設定Unstable CPU Clock時才有作用,如果全域變數sched_clock_stable為1,這個函式就會不作用直接返回*/
2501         raw_spin_lock(&rq->lock);/*鎖*/
2502         update_rq_clock(rq);/*處理run queue的更新*/
2503         curr->sched_class->task_tick(rq, curr, 0);
2504         update_cpu_load_active(rq);
2505         raw_spin_unlock(&rq->lock);
2507         perf_event_task_tick();
2509 #ifdef CONFIG_SMP
2510         rq->idle_balance = idle_cpu(cpu);
2511         trigger_load_balance(rq);
2512 #endif
2513         rq_last_tick_reset(rq);
2514 }

整體動作:
以支援CFS的Linux Kernel 來說,每次觸發Scheduling Tick都會執行下述的動作
1、取得目前的CPU ID,與目前CPU的 RunQueue指標,與目前RunQueue中正在執行的Curr Task指標

2、呼叫 sched_clock_tick (實作在kernel/sched_clock.c中),這函式需在有設定Unstable CPU Clock時才有作用,如果全域變數sched_clock_stable為1,這個函式就會不作用直接返回.(ARM環境中,這個變數並無作用.)

3、取得 RunQueue SpinLock

4、呼叫update_rq_clock (實作在kernel/sched.c中), 若runQueue沒有設定skip_clock_update,這函式會更新RunQueue的Clock值.並呼叫函式update_rq_clock_task, 更新RunQueue clock_task值,clock_task會把前後兩次RunQueue Clock的Delta值,減去處理器進行Soft-IRQ與Hardware-IRQ的時間差值後,對clock_task進行累加. 可用以反應出RunQueue中Task實際被處理器執行的時間累加值.

5、呼叫update_cpu_load_active,會透過函式update_cpu_load在每次Tick觸發時,更新RunQueue cpu_load Array,用以反應目前RunQueue所在的處理器負載.

6、執行目前Task 所在Class的Tick函式(ex, curr->sched_class->task_tick),若Current Task是屬於Fair Class,就會呼叫task_tick_fair (實作在kernel/sched_fair.c中). 依序若Current Task為Stop/Real-Time/Idle Scheduling Class就會呼叫函式 task_tick_stop/ task_tick_rt/ task_tick_idle.

7、釋放RunQueue SpinLock

8、呼叫perf_event_task_tick (若編譯時,沒設定CONFIG_PERF_EVENTS,這函式會是inline的空函式),主要用以支援核心處理器效能的監聽動作.

9、在SMP架構下,會呼叫函式idle_cpu,用以更新RunQueue的idle_at_tick值,為1表示目前CPU RunQueue執行的是Idle Task,反之為0,則非Idle Task. 可供判斷目前這RunQueue所在處理器是否處於閒置的狀態.

10、在SMP架構下,會呼叫trigger_load_balance, 若已達到RunQueue設定下一次觸發Load Balance的jiffies時間值(next_balance),就會觸發Scheduling Softare IRQ,並在Software IRQ中透過函式rebalance_domains,執行Scheduling Domain Load Balance動作.若未達RunQueue下一次觸發Load Balance的jiffies時間值,且在編譯核心時有設定CONFIG_NO_HZ (NO HZ可支援處理器執行Idle Task時,停止系統的Scheduling Tick,可在進入pm_idle時,減少Timer中斷觸發(例如HZ=100,每秒就有一百次Tick Timer中斷觸發),減少系統被觸發醒來的機會.),就會呼叫函式nohz_balancer_kick,Kick一個處理器進行No Hz Load Balance.被Kick選擇為進行No Hz Load Balance的處理器所屬RunQueue的nohz_balance_kick值會設定為1.

沒有留言:

張貼留言