调度子系统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