調度子係統3_周期調度器
// 周期調度器 // 調用路徑:update_process_times->scheduler_tick // 函數任務: // 1.更新rq的clock // 2.更新隊列負載 // 3.通知調度器類更新進程運行時間 // 4.更新下一次load balance的時間戳 // 5.觸發load balance 1.1 void scheduler_tick(void) { int cpu = smp_processor_id(); struct rq *rq = cpu_rq(cpu); //當前運行的進程 struct task_struct *curr = rq->curr; raw_spin_lock(&rq->lock); //更新rq的clock update_rq_clock(rq); //更新隊列負載 update_cpu_load_active(rq); //更新進程的運行時間 curr->sched_class->task_tick(rq, curr, 0); raw_spin_unlock(&rq->lock); #ifdef CONFIG_SMP //更新下一次load balance的時間戳 rq->idle_balance = idle_cpu(cpu); //觸發load balance軟中斷 trigger_load_balance(rq, cpu); #endif } // 更新隊列負載(rq->cpu_load[]) // 每scheduler tick(TICK_NSEC)被調用一次 // 函數任務: // 1.更新rq負載 // 1.1 通過CPU_LOAD_IDX_MAX個項記錄rq的曆史負載信息 // 1.2 更新方法 // cpu_load[0] = load.weight // cpu_load[1] = (cpu_load[1] + load.weight)/2 // cpu_load[2] = (cpu_load[2]*3 + load.weight)/4 // cpu_load[3] = (cpu_load[2]*7 + load.weight)/8 // 2.如果當前時間到達計算cpu負載的時間點 // 2.1 更新下一次計算cpu負載的時間點 // 2.2 計算cpu負載 // 調用路徑:scheduler_tick->update_cpu_load 2.1 static void update_cpu_load(struct rq *this_rq) { //rq中所有se負載的總和 unsigned long this_load = this_rq->load.weight; int i, scale; this_rq->nr_load_updates++; //通過CPU_LOAD_IDX_MAX個項記錄rq的曆史負載信息 for (i = 0, scale = 1; i < CPU_LOAD_IDX_MAX; i++, scale += scale) { unsigned long old_load, new_load; old_load = this_rq->cpu_load[i]; //rq中所有se的load.weight之和 new_load = this_load; if (new_load > old_load) new_load += scale-1; //cpu_load[0] = load.weight //cpu_load[1] = (cpu_load[1] + load.weight)/2 //cpu_load[2] = (cpu_load[2]*3 + load.weight)/4 //cpu_load[3] = (cpu_load[2]*7 + load.weight)/8 //.... this_rq->cpu_load[i] = (old_load*(scale-1) + new_load) >> i; } //到達計算cpu負載的時間點 if (time_after_eq(jiffies, this_rq->calc_load_update)) { //更新下一次計算cpu負載的時間點 this_rq->calc_load_update += LOAD_FREQ; //計算係統負載 calc_load_account_active(this_rq); } } // 計算係統負載 // 係統負載考慮就緒狀態進程和不可中斷睡眠的進程(I/O)進程 // 調用路徑:update_cpu_load->calc_load_account_active 2.2 static void calc_load_account_active(struct rq *this_rq) { long nr_active, delta; nr_active = this_rq->nr_running; //就緒狀態的進程 nr_active += (long) this_rq->nr_uninterruptible; //不可中斷睡眠的進程 if (nr_active != this_rq->calc_load_active) { delta = nr_active - this_rq->calc_load_active; this_rq->calc_load_active = nr_active; atomic_long_add(delta, &calc_load_tasks); } }
最後更新:2017-04-03 12:53:45