Chapter 2: Process Management and Scheduling
Interactionwithfork
Whenever a new process is created using theforksystem call or one of its variants, the scheduler gets a
chance to hook into the process with thesched_forkfunction. On a single-processor system, the function
performs essentially three actions: Initialize the scheduling-related fields of the new process, set up data
structures (this is rather straightforward), anddetermine the dynamic priority of the process:
kernel/sched.c
/*
* fork()/clone()-time setup:
*/
void sched_fork(struct task_struct *p, int clone_flags)
{
/* Initialize data structures */
...
/*
* Make sure we do not leak PI boosting priority to the child:
*/
p->prio = current->normal_prio;
if (!rt_prio(p->prio))
p->sched_class = &fair_sched_class;
...
}
By using thenormalpriority of the parent process as thedynamicpriority of the child, the kernel ensures
that any temporary boosts of the parent’s priority are not inherited by the child. Recall that the dynamic
priority of a process can be temporarily modified when RT-Mutexes are used. This effect must not be
transferred to the child. If the priority is not in the real-time range, the process will always start out in the
completely fair scheduling class.
When a new task is woken up usingwake_up_new_task, a second opportunity for the scheduler to inter-
act with task creation presents itself: The kernel calls thetask_newfunction of the scheduling class. This
gives an opportunity to enqueue the new process into the run queue of the respective class.
ContextSwitching
Once the kernel has selected a new process, the technical details associated with multitasking must
be dealt with; these details are known collectively ascontext switching. The auxiliary function
context_switchis the dispatcher for the required architecture-specific methods.
kernel/sched.c
static inline void
context_switch(struct rq *rq, struct task_struct *prev,
struct task_struct *next)
{
struct mm_struct *mm, *oldmm;
prepare_task_switch(rq, prev, next);
mm = next->mm;
oldmm = prev->active_mm;
..