cfs带宽限制(cfs bandwidth throttle)
只写总结了,哈哈偷懒,代码以前分析的没记录下来:
-
初始化cfs bandwidth相关结构体和定时器
-
在cfs rq入rq(enqueue_entity)时申请slice。特别地,如果时第一次申请slice, 会同事开启period timer监控
-
在每次scheduler_tick时,检查剩余运行时间是否用完。如果已经用完,则尝试再申 请一个slice
-
如果申请不到slice了,那么说明配额已经用完。需要将cfs_rq进行throttle:
-
先设置当前cpu rq重新调度标志
-
在中断返回后,会调用主调度函数__schedule(),检查cfs_rq是否达到throttle;如果达到,就会把cfs_rq中所有se出rq(dequeue_entity),使其停止运行(如下路径都会检查throttle):
- 路径1:enqueue_task_fair
- 路径2:put_prev_task_fair
- 路径3:pick_next_task_fair 三条路径都会通过检查cfs_rq的剩余运行时间来判断是否达到throttle
-
-
在对cfs_rq执行throttle(dequeue_entity)操作,在最后一个se出rq时,会回收所有剩余时间。
-
如果回收的时间累计 >slice,则暂不进行throttle,并开启slack_timer
-
在slack timer的回调函数中,如果距离period timer触发 <2s,则标记cfs_rq为throttle
-
.......,如果距离period timer触发 >2s,则标记cfs_rq为unthrottle,直到再次用完剩余运行时间
-
-
如果回收时间不够(<=slice),则标记cfs_rq为throttle
-
-
当period timer触发(100ms),重新设置定时时间,并根据配额设定,刷新可运行时间和deadline时间
-
如果period中,有出现throttle,则对throttle的cfs_rq进行unthrottle(将task_group中所有未入rq的se,都压入rq),并更新throttle状态。同事,,根据cpu是否idle,来判断是否需要进行唤醒(设置重新调度标志)
-
.......,没有出现throttle,则标记idle。在下一次period timer触发时,仍然没有出现throttle,并且idle标记仍在的话;则说明cpu没有task运行,需要进入idle。那么就会关闭period timer。知道有task入rq(enqueue_entity),清楚idle标记,并重新开启period timer监控(如步骤2)
-