当系统软件调用schedule放弃cpu的时候会发生进程切换,如果某一cpu消耗性进程长时间不调用schedule,我们如何推进调度器的运行来保障系统性能呢?这就是本文要分析的cfs对linux周期性调度的支持。
CFS调度器并不会显示地为进程分配对应的时间片,相应地CFS用周期性调度实现进程的及时切换:在SysTick的中断函数中通过一层层函数调用最终到scheduler_tick函数,周期性地检查当前进程是否耗尽了自己应该分得的一个调度周期里面对应的时间片,并以此为依据决策是否要设置抢占标志,同时设计rq->hrtick_timer配合SysTick提升系统的实时性。
1. SysTick中断调度
1.1 定时器中断scheduler_tick
当系统调度不够频繁的时候,System Tick中断可以继续推进调度器的及时运转,我们首先来看定时器中断入口Timer.c (kernel\time):
在定时器中断中我们会调用update_process_times来更新进程的时间统计信息。内部会调用scheduler_tick执行具体的处理,该函数的执行频率是HZ:
(1)调用调度类实现的task_tick方法,针对CFS调度类该函数是task_tick_fair。
(2)触发负载均衡,暂时忽略。
1.2 CFS的周期性调度处理task_tick_fair
for_each_sched_entity是对当前进程的group层级进行处理,对每一个层级的sched_entity调用entity_tick传入queued=0进行处理:
(1)调用update_curr()更新当前运行的调度实体的虚拟时间等信息
(2)除了System Tick定时器,per-cpu rq还有一个hrtimer在推进调度器的调度工作,如果hrtimer的callback正在执行,那么这个时候