Elements in the Task Structure

There are several scheduling-relevant elements in the task structure of each process. <sched.h>

struct task_struct {

int prio, static_prio, normal_prio; unsigned int rt_priority;

struct list_head run_list;

const struct sched_class *sched_class;

struct sched_entity se;

unsigned int policy; cpumask_t cpus_allowed; unsigned int time_slice;

□ Not all processes on a system are equally important: Less urgent tasks should receive less attention, while important work should be done as quickly as possible. To determine the importance of a particular task, it is equipped with a relative priority.

However, the task structure employs three elements to denote the priority of a process: prio and normal_prio indicate the dynamic priorities, static_prio the static priority of a process. The static priority is the priority assigned to the process when it was started. It can be modified with the nice and sched_setscheduler system calls, but remains otherwise constant during the process' run time.

normal_priority denotes a priority that is computed based on the static priority and the scheduling policy of the process. Identical static priorities will therefore result in different normal priorities depending on whether a process is a regular or a real-time process. When a process forks, the child process will inherit the normal priority.

However, the priority considered by the scheduler is kept in prio. A third element is required because situations can arise in which the kernel needs to temporarily boost the priority of a process. Since these changes are not permanent, the static and normal priorities are unaffected by this. How the three priorities depend on each other is slightly subtle, and I discuss this in detail below.

□ rt_priority denotes the priority of a real-time process. Note that this does not replace the previously discussed values! The lowest real-time priority has value 0, whereas the highest priority is 99. Higher values correspond to higher priorities. The convention used here is different from the convention used for nice values.

□ sched_class denotes the scheduler class the process is in.

□ The scheduler is not limited to schedule processes, but can also work with larger entities. This allows for implementing group scheduling: This way, the available CPU time can first be distributed between general process groups (e.g., all processes can be grouped according to their owner), and the assigned time is then again distributed within the group.

This generality requires that the scheduler does not directly operate on processes but works with schedulable entities. An entity is represented by an instance of sched_entity.

In the simplest case, scheduling is performed on a per-process level, and this is the case we concentrate on initially. Since the scheduler is designed to work on schedulable entities, each process must look to it like such an entity. se therefore embeds an instance of sched_entity on which the scheduler operates in each task struct (notice that se is not a pointer because the entity is embedded in the task!).

□ policy holds the scheduling policy applied to the process. Linux supports five possible values:

□ sched_normal is used for normal processes on which our description focuses. They are handled by the completely fair scheduler. sched_batch and sched_idle are also handled by the completely fair scheduler but can be used for less important tasks. sched_batch is for CPU-intensive batch processes that are not interactive. Tasks of this type are disfavored in scheduling decisions: They will never preempt another process handled by the CF scheduler and will therefore not disturb interactive tasks. The class is well suited for situations in which the static priority of a task is not desired to be decreased with nice, but when the task should nevertheless not influence the interactivity of a system.

sched_idle tasks will also be of low importance in the scheduling decisions, but this time because their relative weight is always minimal (this will become clear when I discuss how the kernel computes task weights that reflect their priority).

Note that sched_idle is, despite its name, not responsible to schedule the idle task. The kernel provides a separate mechanism for this purpose.

□ sched_rr and sched_fifo are used to implement soft real-time processes. sched_rr implements a round robin method, while sched_fifo uses a first in, first out mechanism. These are not handled by the completely fair scheduler class, but by the real-time scheduler class, which is discussed in Section 2.7 in greater length.

The auxiliary function rt_policy is used to decide if a given scheduling policy belongs to the real-time class (sched_rr and sched_fifo) or not. task_has_rt_policy determines this property for a given task.

+1 0

Post a comment