Chapter 2: Process Management and Scheduling
{
u64 vruntime;
vruntime = cfs_rq->min_vruntime;
if (initial)
vruntime += sched_vslice_add(cfs_rq, se);
if (!initial) {
vruntime -= sysctl_sched_latency;
vruntime = max_vruntime(se->vruntime, vruntime);
}
se->vruntime = vruntime;
}
The function distinguishes between two cases depending on the value ofinitial. This parameter is only
set if a new task is added to the system, but that’s not the case here:initialis zero (I will come back to
the other case when I discusstask_new_fairbelow).
Since the kernel has promised to run all active processes at least once within the current latency
period, themin_vruntimeof the queue is used as the base virtual time, and by subtracting
sysctl_sched_latency, it is ensured that the newly awoken process will only run after the current
latency period has been finished.
However, if the sleeper has accumulated a large unfairness as indicated by a largese_vruntimevalue,
the kernel must honor this. Ifse->vruntimeis larger than the previously computed difference, it is kept
as thevruntimeof the process, which leads to a leftward placement on the red-black tree — recall that
largevruntimevalues are good to schedule early!
Let us go back toenqueue_entity:Afterplace_entityhas determined the proper virtual run time for
the process, it is placed on the red-black tree with__enqueue_entity. I have already noted before that
this is a purely mechanical function that uses standard methods of the kernel to sort the task into the
red-black tree.
2.6.4 Selecting the Next Task
Selecting the next task to run is performed inpick_next_task_fair. The code flow diagram is shown in
Figure 2-21.
If no tasks are currently runnable on the queue as indicated by an emptynr_runningcounter,
there is little to do and the function can return immediately. Otherwise, the work is delegated to
pick_next_entity.
If a leftmost task is available in the tree, it can immediately be determined using thefirst_fairhelper
function, and__pick_next_entityextracts thesched_entityinstance from the red-black tree. This is
done using thecontainer_ofmechanism because the red-black tree manages instances ofrb_nodethat
are embedded insched_entitys.
Now the task has been selected, but some more work is required to mark it as the running task. This is
handled byset_next_entity.