在sheduler_tick->task_tick_fair->entity_tick->check_preempt_tick 这个函数中会检查当前进程是否要
被调度出去,从这个函数中我们可以知道在cfg调度中一个进程最小运行时间是0.75ms
源码分析如下:
static void
check_preempt_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr)
{
unsigned long ideal_runtime, delta_exec;
struct sched_entity *se;
s64 delta;
#当前进程理论运行时间
ideal_runtime = sched_slice(cfs_rq, curr);
#当前进程实际运行时间
delta_exec = curr->sum_exec_runtime - curr->prev_sum_exec_runtime;
#如果实际运行时间已经大于理论运行时间,则调用resched_curr 来设置TIF_NEED_RESCHED 标志位,表示
#当前进程需要被调度出去
if (delta_exec > ideal_runtime) {
resched_curr(rq_of(cfs_rq));
/*
* The current task ran long enough, ensure it doesn't get
* re-elected due to buddy favours.
*/
clear_buddies(cfs_rq, curr);
return;
}
/*
* Ensure that a task that missed wakeup preemption by a
* narrow margin doesn't have to wait for a full slice.
* This also mitigates buddy induced latencies under load.
*/
#从这里知道每个进程最小运行时间是sysctl_sched_min_granularity,这个值是0.75ms,如果进程运行时间小于
#这个值则不能调度
if (delta_exec < sysctl_sched_min_granularity)
return;
#获得调度实体
se = __pick_first_entity(cfs_rq);
#获得调度实体的实际运行时间
delta = curr->vruntime - se->vruntime;
#如果时间小于零,则不用调度
if (delta < 0)
return;
#如果这个调度实体实际运行时间超过理论运行时间,则调用resched_curr 来设置TIF_NEED_RESCHED 标志位开始调度
if (delta > ideal_runtime)
resched_curr(rq_of(cfs_rq));
}
unsigned int sysctl_sched_min_granularity = 750000ULL;
进程最小运行时间默认是0.75ms,可以通过sysctl来改变
cfs调度中进程最小运行时间是0.75ms
最新推荐文章于 2023-10-09 16:09:30 发布