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 ==================== 9 Gestor de tareas CFS 10 ==================== 11 12 1. VISIÓN GENERAL 13 ================== 14 15 CFS 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 17 implementado por Ingo Molnar e integrado en Linux 2.6.23. Es el sustituto 18 del previo gestor de tareas SCHED_OTHER. Hoy en día se está abriendo camino 19 para el gestor de tareas EEVDF, cuya documentación se puede ver en 20 Documentation/scheduler/sched-eevdf.rst 21 22 El 80% del diseño de CFS puede ser resumido en una única frase: CFS 23 básicamente modela una "CPU ideal, precisa y multi-tarea" sobre hardware 24 real. 25 26 "una CPU multitarea ideal" es una CPU (inexistente :-)) que tiene un 100% 27 de potencia y que puede ejecutar cualquier tarea exactamente a la misma 28 velocidad, en paralelo, y cada una a 1/n velocidad. Por ejemplo, si hay dos 29 tareas ejecutándose, entonces cada una usa un 50% de la potencia --- es decir, 30 como si se ejecutaran en paralelo. 31 32 En hardware real, se puede ejecutar una única tarea a la vez, así que 33 se ha usado el concepto de "tiempo de ejecución virtual". El tiempo 34 de ejecución virtual de una tarea específica cuando la siguiente porción 35 de ejecución podría empezar en la CPU ideal multi-tarea descrita anteriormente. 36 En la práctica, el tiempo de ejecución virtual de una tarea es el 37 tiempo de ejecución real normalizado con respecto al número total de 38 tareas ejecutándose. 39 40 41 2. UNOS CUANTOS DETALLES DE IMPLEMENTACIÓN 42 =========================================== 43 44 En CFS, el tiempo de ejecución virtual se expresa y se monitoriza por 45 cada tarea, en su valor de p->se.vruntime (en unidades de nanosegundos). 46 De este modo, es posible temporizar con precisión y medir el "tiempo 47 de CPU esperado" que una tarea debería tener. 48 49 Un pequeño detalle: en hardware "ideal", en cualquier momento todas las 50 tareas pueden tener el mismo valor de p->se.vruntime --- i.e., tareas 51 se 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 54 La lógica de elección del tareas de CFS se basa en el valor de p->se.vruntime 55 y por tanto es muy sencilla: siempre intenta ejecutar la tarea con el valor 56 p->se.vruntime más pequeño (i.e., la tarea que se ha ejecutado menos hasta el 57 momento). CFS siempre intenta dividir el espacio de tiempo entre tareas 58 en ejecución tan próximo a la "ejecución multitarea ideal del hardware" como 59 sea posible. 60 61 El resto del diseño de CFS simplemente se escapa de este simple concepto, 62 con unos cuantos añadidos como los niveles "nice" ("nice" significa "amable" 63 en inglés), multi-tarea y varias variantes del algoritmo para identificar 64 tareas "durmiendo". 65 66 67 3. EL ÁRBOL ROJO-NEGRO 68 ======================= 69 70 El diseño de CFS es bastante radical: no utiliza las antiguas estructuras 71 de datos para las colas de ejecución (en inglés "runqueues"), pero usa una 72 estructura de árbol rojo-negro (en inglés "red-black tree") ordenado cronológicamente 73 para construir un línea de ejecución en el futuro, y por eso no tiene ningún 74 artificio de "cambio de tareas" (algo que previamente era usado por el gestor 75 anterior y RSDL/SD). 76 77 CFS también mantiene el valor de rq->cfs.min_vruntime, el cual crece 78 monotónicamente siguiendo el valor más pequeño de vruntime de entre todas 79 las tareas en la cola de ejecución. La cantidad total de trabajo realizado 80 por el sistema es monitorizado usado min_vruntime; este valor es usado 81 para situar las nuevas tareas en la parte izquierda del árbol tanto 82 como sea posible. 83 84 El valor total de tareas ejecutándose en la cola de ejecución es 85 contabilizado mediante el valor rq->cfs.load, el cual es la suma de los 86 de esas tareas que están en la cola de ejecución. 87 88 CFS mantiene un árbol rojo-negro cronológicamente ordenado, donde todas las 89 tareas que pueden ser ejecutadas están ordenadas por su valor de 90 p->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 92 se ponen en este árbol más y más hacia la derecha --- lentamente pero 93 de forma continuada dando una oportunidad a cada tarea de ser la que 94 está "la más hacia la izquierda" y por tanto obtener la CPU una cantidad 95 determinista de tiempo. 96 97 Resumiendo, CFS funciona así: ejecuta una tarea un tiempo, y cuando la 98 tarea se gestiona (o sucede un tic del gestor de tareas) se considera 99 que el tiempo de uso de la CPU se ha completado, y se añade a 100 p->se.vruntime. Una vez p->se.vruntime ha aumentado lo suficiente como 101 para que otra tarea sea "la tarea más hacia la izquierda" del árbol 102 rojo-negro ordenado cronológicamente esta mantienen (más una cierta pequeña 103 cantidad de distancia relativa a la tarea más hacia la izquierda para 104 que no se sobre-reserven tareas y perjudique a la cache), entonces la 105 nueva tarea "que está a la izquierda del todo", es la que se elige 106 para que se ejecute, y la tarea en ejecución es interrumpida. 107 108 4. ALGUNAS CARACTERÍSTICAS DE CFS 109 ================================== 110 111 CFS usa una granularidad de nanosegundos y no depende de ningún 112 jiffy o detalles como HZ. De este modo, el gestor de tareas CFS no tiene 113 noción de "ventanas de tiempo" de la forma en que tenía el gestor de 114 tareas previo, y tampoco tiene heurísticos. Únicamente hay un parámetro 115 central ajustable (se ha de cambiar en CONFIG_SCHED_DEBUG): 116 117 /sys/kernel/debug/sched/base_slice_ns 118 119 El 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 121 procesamientos). Su valor por defecto es adecuado para tareas de escritorio. 122 SCHED_BATCH también es gestionado por el gestor de tareas CFS. 123 124 Debido a su diseño, el gestor de tareas CFS no es proclive a ninguno de los 125 ataques que existen a día de hoy contra los heurísticos del gestor de tareas: 126 fiftyp.c, thud.c, chew.c, ring-test.c, massive_intr.c todos trabajan 127 correctamente y no tienen impacto en la interacción y se comportan de la forma 128 esperada. 129 130 El 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 132 tareas están aisladas de forma más eficiente. 133 134 El balanceo de tareas SMP ha sido rehecho/mejorado: el avance por las 135 colas de ejecución de tareas ha desaparecido del código de balanceo de 136 carga, y ahora se usan iteradores en la gestión de módulos. El balanceo 137 del código ha sido simplificado como resultado esto. 138 139 5. Políticas de gestión de tareas 140 ================================== 141 142 CFS 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 158 SCHED_FIFO/_RR se implementan en sched/rt.c y son específicos de 159 POSIX. 160 161 El comando chrt de util-linux-ng 2.13.1.1. puede asignar cualquiera de 162 estas políticas excepto SCHED_IDLE. 163 164 165 6. CLASES DE GESTIÓN 166 ===================== 167 168 El 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 170 distintas políticas de gestión de tareas. Estos módulos encapsulan los 171 detalles de las politicas de gestión y son manejadas por el núcleo del 172 gestor de tareas sin que este tenga que presuponer mucho sobre estas clases. 173 174 sched/fair.c implementa el gestor de tareas CFS descrito antes. 175 176 sched/rt.c implementa la semántica de SCHED_FIFO y SCHED_RR, de una forma 177 má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 179 el gestor de tareas anterior) y no necesita las listas de expiración. 180 181 Las clases de gestión de tareas son implementadas por medio de la estructura 182 sched_class, la cual tiene llamadas a las funciones que deben de llamarse 183 cuando quiera que ocurra un evento interesante. 184 185 Esta 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 227 7. EXTENSIONES DE GRUPOS PARA CFS 228 ================================== 229 230 Normalmente, el gestor de tareas gestiona tareas individuales e intenta 231 proporcionar una cantidad justa de CPU a cada tarea. Algunas veces, puede 232 ser deseable agrupar las tareas y proporcionarles una cantidad justa 233 de tiempo de CPU a cada una de las tareas de ese grupo. Por ejemplo, 234 podría ser deseable que primero se proporcione una cantidad justa de 235 tiempo de CPU a cada usuario del sistema y después a cada tarea 236 que pertenezca a un usuario. 237 238 CONFIG_CGROUP_SCHED destaca en conseguir exactamente eso. Permite a las 239 tareas ser agrupadas y divide el tiempo de CPU de forma just entre esos 240 grupos. 241 242 CONFIG_RT_GROUP_SCHED permite agrupar tareas de tiempo real (i.e., 243 SCHED_FIFO y SCHED_RR). 244 245 CONFIG_FAIR_GROUP_SCHED permite agrupar tareas de CFS (i.e., SCHED_NORMAL y 246 SCHED_BATCH). 247 248 Estas opciones necesitan CONFIG_CGROUPS para ser definidas, y permitir 249 al administrador crear grupos arbitrarios de tareas, usando el pseudo 250 sistema de archivos "cgroup". Vease la documentación para más información 251 sobre este sistema de archivos: Documentation/admin-guide/cgroup-v1/cgroups.rst 252 253 Cuando CONFIG_FAIR_GROUP_SCHED es definido, un archivo 254 "cpu.shares" es creado por cada grupo creado usado en el pseudo 255 sistema de archivos. Véanse por ejemplo los pasos a continuación 256 para crear grupos de tareas y modificar cuanto comparten de la CPU 257 usando 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
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.