linux kernel - ¿Cómo funciona el cronograma SMP en kernel de Linux?(Arquitectura ARM)
linux-kernel scheduler (1)
En Linux, el programador se activará cuando haya transcurrido un tiempo específico. Según entendí, el temporizador dispara una interrupción que a su vez activa una llamada para schedule
.
En un sistema SMP, leí en el libro "Understanding the Linux Kernel" que "cada procesador ejecuta la función del scheduler () por su cuenta". ¿Significa esto que cada interrupción del temporizador activa cada CPU para hacer un reprogramación al mismo tiempo?
Los sistemas ARM SMP admiten dos tipos de interrupciones. SPI (interrupción periférica compartida) y PPI (interrupciones privadas periféricas). El PPI es una fuente de interrupción por CPU . Un caso especial para SMP del PPI es un SGI (interrupción generada por software); esta es una interrupción de CPU a CPU que se usa para enviar señales de una CPU a otra en el mundo de SMP (llamado IPI ). Nota 1
Se puede usar un temporizador PPI para permitir que cada CPU use ''programación sin marca''; es decir, las interrupciones del temporizador se programan a través del conocimiento de eventos de tiempo futuros (rueda de distribución de google, consulte la documentación de NO_HZ
, etc.). El kernel de Linux actual no usa este temporizador PPI específico para la programación. Solo se usa como fuente de tiempo de bucle de retardo. En cambio, se utiliza el temporizador PPI global . Este temporizador puede interrumpir cada CPU de forma selectiva, pero el conjunto de registros es global para todas las CPU. Una CPU particular puede programar una interrupción por sí misma; con la base de tiempo siendo global.
La complicación es que las tareas deben migrarse de una CPU a otra para equilibrar el trabajo entre las CPU. Además, el código / planificador central del kernel de Linux está escrito para múltiples CPU (o arquitecturas) y es posible que no tengan estas fuentes de interrupción por CPU . Una respuesta definitiva puede depender de la versión de su kernel y del planificador utilizado (o, más en general, de la configuración del kernel). En general, una CPU ocupada hará la migración , otras CPU se pueden activar con un temporizador solo para ver si una tarea en su conjunto debe ejecutarse (tal vez un proceso migrado). Si NO_HZ
está en efecto, algunas CPU pueden no despertar en absoluto; obtendrán un IPI en el caso de la migración.
En cualquier caso, no hay nada que sea específico de ARM en la programación de CPU además de la fuente de reloj. Es posible que un sistema ARM SMP no tenga un temporizador PPI global . En este caso, cada CPU puede despertarse para dar servicio a una interrupción, pero la mayoría puede dormir inmediatamente. Esto podría suceder en cualquier sistema debido a un mal diseño del temporizador / controlador de interrupción o una mala configuración del sistema. Sin embargo, incluso en estos casos, el código no llamaría al planificador, excepto cuando sea necesario.
Ver: Programador de Linux en SMP (que puede ser un duplicado aunque la respuesta no es muy buena), el artículo del planificador completamente justo de IBM y el capítulo del programador O''Reillys Linux Kernel .
Nota 1: Esta es realmente la terminología GIC (o controlador de interrupción genérico ). Sin embargo, la mayoría de los sistemas ARM SMP usan este controlador de interrupción. Se incluye con CPU Cortex-A y viene como un componente externo para algunos sistemas ARMv6. Es posible que un sistema ARM SMP use otro controlador, pero es probable que sea extremadamente raro o inexistente.
Editar: hay dos temporizadores ARM en el chip; estos son útiles ya que cada Cortex-A los compara con los temporizadores de vendedor de SOC. Uno de ellos se usa en lugar de un "ciclo de conteo" para un retraso. Esto funciona mejor en el caso de interrupciones. No creo que sea crítico comprender la programación de SMP, puede ignorar ese comentario y saber que ese archivo fuente no se usa para la programación. Fue el primero que miré. Si realmente lo distrae, eliminaré esa información.
Vea este documento sobre las ruedas dentadas ; se trata de ''IP'' / redes, pero el concepto de NO_HZ
es similar. Es decir. No interrumpa cada 10mS, solo para incrementar los tics. En el caso de NO_HZ
, cada CPU puede establecer un tiempo de NO_HZ
futuro basado en qué tipo de solicitudes han proporcionado los controladores y subsistemas. Es decir, schedule_work()
necesita ejecutarse en 175 ms, luego el temporizador se establece en ese valor para la CPU y no nos despertamos 17 veces (si el tic del sistema es 10 mS), sino que simplemente incrementamos ticks en 17. Algunos Las CPU pueden necesitar un tiempo de espera para desalojar el proceso actual y ejecutar otro para tareas múltiples, así el planificador mismo puede configurar un temporizador.