2493 void scheduler_tick(void)
2494 {
2495 int cpu = smp_processor_id();
2496 struct rq *rq = cpu_rq(cpu);
2497 struct task_struct *curr = rq->curr;
2499 sched_clock_tick();
2501 raw_spin_lock(&rq->lock);
2502 update_rq_clock(rq);
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.
沒有留言:
張貼留言