xref: /linux/Documentation/translations/sp_SP/scheduler/sched-design-CFS.rst (revision c532de5a67a70f8533d495f8f2aaa9a0491c3ad0)
1.. include:: ../disclaimer-sp.rst
2
3:Original: :ref:`Documentation/scheduler/sched-design-CFS.rst <sched_design_CFS>`
4:Translator: Sergio González Collado <sergio.collado@gmail.com>
5
6.. _sp_sched_desing_CFS:
7
8====================
9Gestor de tareas CFS
10====================
11
121.  VISIÓN GENERAL
13==================
14
15CFS viene de las siglas en inglés de "Gestor de tareas totalmente justo"
16("Completely Fair Scheduler"), y es el nuevo gestor de tareas de escritorio
17implementado por Ingo Molnar e integrado en Linux 2.6.23. Es el sustituto
18del previo gestor de tareas SCHED_OTHER. Hoy en día se está abriendo camino
19para el gestor de tareas EEVDF, cuya documentación se puede ver en
20Documentation/scheduler/sched-eevdf.rst
21
22El 80% del diseño de CFS puede ser resumido en una única frase: CFS
23básicamente modela una "CPU ideal, precisa y multi-tarea" sobre hardware
24real.
25
26"una CPU multitarea ideal" es una CPU (inexistente :-)) que tiene un 100%
27de potencia y que puede ejecutar cualquier tarea exactamente a la misma
28velocidad, en paralelo, y cada una a 1/n velocidad. Por ejemplo, si hay dos
29tareas ejecutándose, entonces cada una usa un 50% de la potencia --- es decir,
30como si se ejecutaran en paralelo.
31
32En hardware real, se puede ejecutar una única tarea a la vez, así que
33se ha usado el concepto de "tiempo de ejecución virtual". El tiempo
34de ejecución virtual de una tarea específica cuando la siguiente porción
35de ejecución podría empezar en la CPU ideal multi-tarea descrita anteriormente.
36En la práctica, el tiempo de ejecución virtual de una tarea es el
37tiempo de ejecución real normalizado con respecto al número total de
38tareas ejecutándose.
39
40
412.  UNOS CUANTOS DETALLES DE IMPLEMENTACIÓN
42===========================================
43
44En CFS, el tiempo de ejecución virtual se expresa y se monitoriza por
45cada tarea, en su valor de p->se.vruntime (en unidades de nanosegundos).
46De este modo, es posible temporizar con precisión y medir el "tiempo
47de CPU esperado" que una tarea debería tener.
48
49Un pequeño detalle: en hardware "ideal", en cualquier momento todas las
50tareas pueden tener el mismo valor de p->se.vruntime --- i.e., tareas
51se podrían ejecutar simultáneamente y ninguna tarea podría escaparse del
52"balance" de la partición "ideal" del tiempo compartido de la CPU.
53
54La lógica de elección del tareas de CFS se basa en el valor de p->se.vruntime
55y por tanto es muy sencilla: siempre intenta ejecutar la tarea con el valor
56p->se.vruntime más pequeño (i.e., la tarea que se ha ejecutado menos hasta el
57momento). CFS siempre intenta dividir el espacio de tiempo entre tareas
58en ejecución tan próximo a la "ejecución multitarea ideal del hardware" como
59sea posible.
60
61El resto del diseño de CFS simplemente se escapa de este simple concepto,
62con unos cuantos añadidos como los niveles "nice" ("nice" significa "amable"
63en inglés), multi-tarea y varias variantes del algoritmo para identificar
64tareas "durmiendo".
65
66
673.  EL ÁRBOL ROJO-NEGRO
68=======================
69
70El diseño de CFS es bastante radical: no utiliza las antiguas estructuras
71de datos para las colas de ejecución (en inglés "runqueues"), pero usa una
72estructura de árbol rojo-negro (en inglés "red-black tree") ordenado cronológicamente
73para construir un línea de ejecución en el futuro, y por eso no tiene ningún
74artificio de "cambio de tareas" (algo que previamente era usado por el gestor
75anterior y RSDL/SD).
76
77CFS también mantiene el valor de rq->cfs.min_vruntime, el cual crece
78monotónicamente siguiendo el valor más pequeño de vruntime de entre todas
79las tareas en la cola de ejecución. La cantidad total de trabajo realizado
80por el sistema es monitorizado usado min_vruntime; este valor es usado
81para situar las nuevas tareas en la parte izquierda del árbol tanto
82como sea posible.
83
84El valor total de tareas ejecutándose en la cola de ejecución es
85contabilizado mediante el valor rq->cfs.load, el cual es la suma de los
86de esas tareas que están en la cola de ejecución.
87
88CFS mantiene un árbol rojo-negro cronológicamente ordenado, donde todas las
89tareas que pueden ser ejecutadas están ordenadas por su valor de
90p->se.vruntime. CFS selecciona la tarea más hacia la izquierda de este
91árbol y la mantiene. Según el sistema continúa, las tareas ejecutadas
92se ponen en este árbol más y más hacia la derecha --- lentamente pero
93de forma continuada dando una oportunidad a cada tarea de ser la que
94está "la más hacia la izquierda" y por tanto obtener la CPU una cantidad
95determinista de tiempo.
96
97Resumiendo, CFS funciona así: ejecuta una tarea un tiempo, y cuando la
98tarea se gestiona (o sucede un tic del gestor de tareas) se considera
99que el tiempo de uso de la CPU se ha completado, y se añade a
100p->se.vruntime. Una vez p->se.vruntime ha aumentado lo suficiente como
101para que otra tarea sea "la tarea más hacia la izquierda" del árbol
102rojo-negro ordenado cronológicamente esta mantienen (más una cierta pequeña
103cantidad de distancia relativa a la tarea más hacia la izquierda para
104que no se sobre-reserven tareas y perjudique a la cache), entonces la
105nueva tarea "que está a la izquierda del todo", es la que se elige
106para que se ejecute, y la tarea en ejecución es interrumpida.
107
1084.  ALGUNAS CARACTERÍSTICAS DE CFS
109==================================
110
111CFS usa una granularidad de nanosegundos y no depende de ningún
112jiffy o detalles como HZ. De este modo, el gestor de tareas CFS no tiene
113noción de "ventanas de tiempo" de la forma en que tenía el gestor de
114tareas previo, y tampoco tiene heurísticos. Únicamente hay un parámetro
115central ajustable (se ha de cambiar en CONFIG_SCHED_DEBUG):
116
117   /sys/kernel/debug/sched/base_slice_ns
118
119El cual puede ser usado para afinar desde el gestor de tareas del "escritorio"
120(i.e., bajas latencias) hacia cargas de "servidor" (i.e., bueno con
121procesamientos). Su valor por defecto es adecuado para tareas de escritorio.
122SCHED_BATCH también es gestionado por el gestor de tareas CFS.
123
124Debido a su diseño, el gestor de tareas CFS no es proclive a ninguno de los
125ataques que existen a día de hoy contra los heurísticos del gestor de tareas:
126fiftyp.c, thud.c, chew.c, ring-test.c, massive_intr.c todos trabajan
127correctamente y no tienen impacto en la interacción y se comportan de la forma
128esperada.
129
130El gestor de tareas CFS tiene una gestión mucho más firme de los niveles
131"nice" y SCHED_BATCH que los previos gestores de tareas: ambos tipos de
132tareas están aisladas de forma más eficiente.
133
134El balanceo de tareas SMP ha sido rehecho/mejorado: el avance por las
135colas de ejecución de tareas ha desaparecido del código de balanceo de
136carga, y ahora se usan iteradores en la gestión de módulos. El balanceo
137del código ha sido simplificado como resultado esto.
138
1395.  Políticas de gestión de tareas
140==================================
141
142CFS implementa tres políticas de gestión de tareas:
143
144  - SCHED_NORMAL (tradicionalmente llamada SCHED_OTHER): Gestión de
145    tareas que se usan para tareas normales.
146
147  - SCHED_BATCH: No interrumpe tareas tan a menudo como las tareas
148    normales harían, por eso permite a las tareas ejecutarse durante
149    ventanas de tiempo mayores y hace un uso más efectivo de las
150    caches pero al coste de la interactividad. Esto es adecuado
151    para trabajos de procesado de datos.
152
153  - SCHED_IDLE: Esta política es más débil incluso que nice 19, pero
154    no es un gestor "idle" para evitar caer en el problema de la
155    inversión de prioridades que causaría un bloqueo de la máquina
156    (deadlock).
157
158SCHED_FIFO/_RR se implementan en sched/rt.c y son específicos de
159POSIX.
160
161El comando chrt de util-linux-ng 2.13.1.1. puede asignar cualquiera de
162estas políticas excepto SCHED_IDLE.
163
164
1656.  CLASES DE GESTIÓN
166=====================
167
168El nuevo gestor de tareas CFS ha sido diseñado de tal modo para incluir
169"clases de gestión", una jerarquía ampliable de módulos que pueden tener
170distintas políticas de gestión de tareas. Estos módulos encapsulan los
171detalles de las politicas de gestión y son manejadas por el núcleo del
172gestor de tareas sin que este tenga que presuponer mucho sobre estas clases.
173
174sched/fair.c implementa el gestor de tareas CFS descrito antes.
175
176sched/rt.c implementa la semántica de SCHED_FIFO y SCHED_RR, de una forma
177más sencilla que el gestor de tareas anterior. Usa 100 colas de ejecución
178(por todos los 100 niveles de prioridad RT, en vez de las 140 que necesitaba
179el gestor de tareas anterior) y no necesita las listas de expiración.
180
181Las clases de gestión de tareas son implementadas por medio de la estructura
182sched_class, la cual tiene llamadas a las funciones que deben de llamarse
183cuando quiera que ocurra un evento interesante.
184
185Esta es la lista parcial de llamadas:
186
187 - enqueue_task(...)
188
189   Llamada cuando una tarea entra en el estado de lista para ejecución.
190   Pone la entidad a ser gestionada (la tarea) en el árbol rojo-negro
191   e incrementa la variable nr_running.
192
193 - dequeue_task(...)
194
195   Cuando una tarea deja de ser ejecutable, esta función se llama para
196   mantener a la entidad gestionada fuera del árbol rojo-negor. Esto
197   decrementa la variable nr_running.
198
199 - yield_task(...)
200
201   Esta función es básicamente desencolar, seguido por encolar, a menos que
202   sysctl compat_yield esté activado; en ese caso, sitúa la entidad a gestionar
203   en la parte más hacia la derecha del árbol rojo-negro.
204
205 - check_preempt_curr(...)
206
207   Esta función comprueba si una tarea que ha entrado en el estado de
208   poder ser ejecutada, podría reemplazar a la tarea que actualmente
209   se esté ejecutando.
210
211 - pick_next_task(...)
212
213   Esta función elige la tarea más apropiada para ser ejecutada a continuación.
214
215 - set_curr_task(...)
216
217   Esta función se llama cuando una tarea cambia su clase de gestión o
218   cambia su grupo de tareas.
219
220 - task_tick(...)
221
222   Esta función es llamada la mayoría de las veces desde la función de tiempo
223   tick; esto puede llevar a un cambio de procesos. Esto dirige el reemplazo
224   de las tareas.
225
226
2277.  EXTENSIONES DE GRUPOS PARA CFS
228==================================
229
230Normalmente, el gestor de tareas gestiona tareas individuales e intenta
231proporcionar una cantidad justa de CPU a cada tarea. Algunas veces, puede
232ser deseable agrupar las tareas y proporcionarles una cantidad justa
233de tiempo de CPU a cada una de las tareas de ese grupo. Por ejemplo,
234podría ser deseable que primero se proporcione una cantidad justa de
235tiempo de CPU a cada usuario del sistema y después a cada tarea
236que pertenezca a un usuario.
237
238CONFIG_CGROUP_SCHED destaca en conseguir exactamente eso. Permite a las
239tareas ser agrupadas y divide el tiempo de CPU de forma just entre esos
240grupos.
241
242CONFIG_RT_GROUP_SCHED permite agrupar tareas de tiempo real (i.e.,
243SCHED_FIFO y SCHED_RR).
244
245CONFIG_FAIR_GROUP_SCHED permite agrupar tareas de CFS (i.e., SCHED_NORMAL y
246SCHED_BATCH).
247
248Estas opciones necesitan CONFIG_CGROUPS para ser definidas, y permitir
249al administrador crear grupos arbitrarios de tareas, usando el pseudo
250sistema de archivos "cgroup". Vease la documentación para más información
251sobre este sistema de archivos: Documentation/admin-guide/cgroup-v1/cgroups.rst
252
253Cuando CONFIG_FAIR_GROUP_SCHED es definido, un archivo
254"cpu.shares" es creado por cada grupo creado usado en el pseudo
255sistema de archivos. Véanse por ejemplo los pasos a continuación
256para crear grupos de tareas y modificar cuanto comparten de la CPU
257usando el pseudo sistema de archivos "cgroup" ::
258
259	# mount -t tmpfs cgroup_root /sys/fs/cgroup
260	# mkdir /sys/fs/cgroup/cpu
261	# mount -t cgroup -ocpu none /sys/fs/cgroup/cpu
262	# cd /sys/fs/cgroup/cpu
263
264	# mkdir multimedia	# crear un grupo de tareas "multimedia"
265	# mkdir browser 	# crear un grupo de tareas "browser"
266
267	# #Configurar el grupo multimedia para tener el doble de tiempo de CPU
268	# #que el grupo browser
269
270	# echo 2048 > multimedia/cpu.shares
271	# echo 1024 > browser/cpu.shares
272
273	# firefox &	# Lanzar firefox y moverlo al grupo "browser"
274	# echo <firefox_pid> > browser/tasks
275
276	# #Lanzar gmplayer (o su programa favorito de reproducción de películas)
277	# echo <movie_player_pid> > multimedia/tasks
278