2.6.2.2 调度逻辑 - vruntime
/* file: kernel/sched/fair.c */
/* 参数delta代表墙上时间 */
static inline u64 calc_delta_fair(u64 delta, struct sched_entity *se) {
/* 如果se的权重不等于NICE_0_LOAD,则需要根据其权重计算出vruntime */
if (unlikely(se->load.weight != NICE_0_LOAD))
delta = __calc_delta(delta, NICE_0_LOAD, &se->load);
/* 如果se的权重等于NICE_0_LOAD, 则该se的vruntime就是墙上时间,即返回delta即可
*/
return delta;
}/* file: kernel/sched/fair.c */
static void place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se,
int initial) {
/* 以队列的min_vruntime为基础进行调整 */
u64 vruntime = cfs_rq->min_vruntime;
/* 对新创建的进程(initial=1)适当的惩罚,为其加上一定的 vruntime,
* 函数sched_vslice将任务在一个调度周期内应当分配到的墙上时间换算成虚拟时间,调度周期会在下一节介绍
*/
if (initial && sched_feat(START_DEBIT))
vruntime += sched_vslice(cfs_rq, se);
if (!initial) {
/* 如果进程睡眠了很久,那么其 vruntime 可能远远小于队列中其他任务的vruntime,
* 我们也需要对其vruntime
* 进行惩罚,但进程被唤醒(initial=0)说明它所等待的事件已经得到了满足,需要马上干活,所以这里减去一定的vruntime作为补偿。*/
unsigned long thresh = sysctl_sched_latency;
if (sched_feat(GENTLE_FAIR_SLEEPERS))
thresh >>= 1;
vruntime -= thresh;
}
/* 确保不要因为 vruntime -=thresh 导致 se.vruntime 的值越来越小了 */
se->vruntime = max_vruntime(se->vruntime, vruntime);
}Last updated