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 de 18el previo gestor de tareas SCHED_OTHER. 19 20Nota: El planificador EEVDF fue incorporado más recientemente al kernel. 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 112jiffie 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