Análisis de mecanismo de implementación de prioridad de kernel de Linux

  
 

Esta serie de publicaciones de blog presenta principalmente varios conceptos y principios técnicos importantes del kernel de Linux, algunos de los cuales provienen de un resumen en línea, y otros provienen de su propio resumen de "diseño e implementación del kernel de Linux" y "comprensión en profundidad del kernel de Linux". El propósito es permitir que algunas personas que son nuevas en el kernel de Linux tengan una comprensión general de algunas técnicas de implementación del kernel de Linux.
1.1 Preferencia de kernel

2.6 El nuevo kernel preventivo se refiere a la preemption de kernel, es decir, cuando el proceso está en el espacio del kernel, cuando ocurre una tarea de mayor prioridad, si el kernel actual permite la preferencia, entonces Puede suspender la tarea actual y ejecutar un proceso de mayor prioridad.

Antes de la versión 2.5.4, el kernel de Linux no era preferible. Los procesos de alta prioridad no podían suspender los procesos de baja prioridad que se ejecutaban en el kernel y se adelantaban a la CPU. Una vez que el proceso se encuentra en un estado central (como un proceso de usuario que ejecuta una llamada al sistema), el proceso continuará ejecutándose hasta que el núcleo se complete o salga, a menos que el proceso renuncie voluntariamente a la CPU. Por el contrario, un kernel de Linux preferible permite que el kernel de Linux se anule como espacio de usuario. Cuando llega un proceso de alta prioridad, independientemente de si el proceso actual está en modo de usuario o estado central, si actualmente se permite la preferencia, Linux que puede adelantarse al kernel programará procesos de alta prioridad para que se ejecuten.
1.2 Preferencia de usuario

Cuando el kernel está a punto de volver al espacio de usuario, si se establece el indicador de necesidad de reprogramación, se llamará a schedule () y se producirá la preferencia de usuario. Cuando el kernel vuelve al espacio de usuario, sabe que está seguro. Por lo tanto, el kernel comprueba el indicador de necesidad de volver a programar si regresa del manejador de interrupciones o después de una llamada al sistema. Si está configurado, entonces el kernel elegirá otro proceso (más apropiado) para ponerlo en funcionamiento.

En resumen, la preferencia de usuario se produce cuando:
l Devuelve el espacio de usuario del sistema.
l Devuelve espacio de usuario desde el controlador de interrupciones.
1.3 Características de los kernels no preferentes

En los kernels que no admiten la preferencia del kernel, el código del kernel puede ejecutarse hasta que se complete. Es decir, el programador no tiene forma de reprogramar &mdash cuando se está ejecutando una tarea de nivel de kernel, las tareas en el kernel son coordinadas y no preventivas. Por supuesto, un proceso que se ejecuta en modo kernel puede renunciar voluntariamente a la CPU. Por ejemplo, en una rutina de servicio de llamadas al sistema, el código del kernel abandona la CPU porque espera recursos. Esta situación se llama cambio de proceso planificado. El código del kernel debe ejecutarse hasta que se complete (regrese al espacio del usuario) o se produzca un bloqueo obvio.

En el caso de una sola CPU, esta configuración simplifica enormemente los mecanismos de sincronización y protección del kernel. Esto se puede analizar en dos pasos:

Primero, independientemente del proceso en el que la CPU renuncia voluntariamente a la CPU (es decir, no se produce un cambio de proceso en el kernel). Una vez que un proceso ingresa al kernel, continuará ejecutándose hasta que complete o salga del kernel. Antes de completar o salir del kernel, ningún otro proceso ingresará al kernel, es decir, la ejecución del proceso en el kernel es en serie. Es imposible tener varios procesos ejecutándose en el kernel al mismo tiempo, por lo que no se considera el diseño del código del kernel. Problemas de concurrencia causados ​​por la ejecución simultánea de múltiples procesos. Los desarrolladores del kernel de Linux no tienen que preocuparse por los procesos complejos que ejecutan simultáneamente el acceso mutuamente exclusivo a los recursos críticos. Cuando un proceso accede y modifica la estructura de datos del kernel, no es necesario bloquearlo para evitar que múltiples procesos ingresen a la sección crítica al mismo tiempo. En este momento, solo debe considerar la situación de interrupción. Si la rutina de procesamiento de interrupciones también es posible acceder a la estructura de datos a la que está accediendo el proceso, el proceso solo necesita cerrar la operación de interrupción antes de ingresar a la sección crítica, y luego abrir la operación de interrupción al salir de la sección crítica. Si

Considere nuevamente el proceso de renunciar voluntariamente a la CPU. Debido a que el abandono de la CPU es voluntario y activo, significa que el proceso de cambio en el kernel se conoce de antemano y no hay cambio en el proceso que se produce sin saberlo. De esta manera, solo necesita considerar los problemas de concurrencia que pueden ocurrir cuando se ejecutan múltiples procesos simultáneamente en el proceso de cambio de proceso, sin tener que considerar la ejecución concurrente del proceso en todo el kernel.
1.4 ¿Por qué necesita la prioridad del kernel?

La implementación de la preferencia del kernel es importante para Linux. Primero, esto es necesario para aplicar Linux a sistemas en tiempo real. El sistema de tiempo real tiene límites estrictos en el tiempo de respuesta. Cuando se interrumpe un proceso en tiempo real por la interrupción de hardware del dispositivo en tiempo real, debe programarse para ejecutarse dentro de un tiempo limitado. Linux no cumple con este requisito porque el kernel de Linux no es preferible y no puede determinar el tiempo de residencia del sistema en el kernel. De hecho, cuando el kernel realiza llamadas largas al sistema, el proceso en tiempo real espera hasta que el proceso que se ejecuta en el kernel salga del kernel para ser programado. El retraso de respuesta resultante es de hasta 100 ms en el hardware actual.

Esto es inaceptable para los sistemas que requieren una alta respuesta en tiempo real. El kernel preferente no solo es crítico para las aplicaciones de Linux en tiempo real, sino que también resuelve los inconvenientes de la compatibilidad de Linux con baja latencia para aplicaciones multimedia (video, audio).

Debido a la importancia de preemplazar el kernel, cuando se lanza la versión Linux 2.5.4, se puede anular en el kernel, y como una configuración opcional estándar del kernel como SMP.
1.5 ¿Qué es lo que no permite que el kernel se anule?
Hay varios casos en los que el kernel de Linux no se debe anular, excepto que el kernel de Linux se puede anular en cualquier momento. Estos casos son:

(1) El kernel está realizando un procesamiento de interrupción. En el kernel de Linux, los procesos no pueden adelantarse a las interrupciones (las interrupciones solo pueden abortarse, anticiparse a otras interrupciones, los procesos no pueden abortarse, las interrupciones anticipadas) y la programación de procesos no está permitida en las rutinas de interrupción. La función de programación de procesos programada () juzgará esto. Si se llama en una interrupción, se imprimirá un mensaje de error.

(2) El kernel está procesando la mitad inferior (mitad inferior de la interrupción) del contexto de interrupción. Se ejecuta una interrupción suave antes de que la interrupción de hardware regrese y aún se encuentra en el contexto de interrupción.

(3) El segmento de código del kernel contiene bloqueos como el bloqueo de giro de bloqueo de giro, bloqueo de lectura /escritura de bloqueo de lectura /bloqueo de bloqueo de lectura, etc., en el estado de protección de estos bloqueos. Estos bloqueos en el kernel están diseñados para garantizar la ejecución correcta de la ejecución concurrente de procesos que se ejecutan en diferentes CPU en poco tiempo en un sistema SMP. Cuando se mantienen estos bloqueos, el kernel no se debe anular, de lo contrario, la CPU hará que otros CPU pierdan los bloqueos durante mucho tiempo y mueran.

(4) El kernel está ejecutando el programador Scheduler. El motivo de la preferencia es hacer un nuevo horario, no hay razón para anticiparse al programador y ejecutar el programador.

(5) El kernel está trabajando en las operaciones de estructura de datos "privadas" de cada CPU (estructuras de fecha por CPU). En SMP, la estructura de datos por CPU no está protegida con spinlocks, ya que estas estructuras de datos están protegidas implícitamente (diferentes CPU tienen diferentes datos por CPU, los procesos que se ejecutan en otras CPU no utilizan otra CPU por datos de la CPU). Sin embargo, si se permite la preferencia, pero un proceso se vuelve a programar después de ser reemplazado, es posible programarlo para otras CPUs. En este momento, la variable definida por CPU tendrá un problema y se debe prohibir la preferencia.

Para asegurarse de que el kernel de Linux no se anulará en las condiciones anteriores, el kernel preventivo utiliza una variable preempt_ count, llamada el bloqueo de preferencia del kernel. Esta variable se establece en la estructura de PCB del proceso task_struct. Cada vez que el kernel quiere ingresar a los estados anteriores, la variable preempt_count se incrementa en 1, lo que indica que el kernel no permite la preferencia. Cada vez que el kernel sale de los estados anteriores, la variable preempt_count se reduce en uno, y el juicio y la programación previsibles se realizan al mismo tiempo.

Al devolver el espacio del kernel desde una interrupción, el kernel verifica los valores de need_resched y preempt_count. Si se establece need_resched y el recuento de preferencia es 0, esto significa que puede haber una tarea más importante que debe ejecutarse y que se puede anticipar de manera segura, en qué punto se llamará al programador. Si el conteo anticipado no es 0, el kernel ahora se encuentra en un estado no anticipable y no se puede reprogramar. En este punto, el proceso de ejecución actual se devuelve directamente de la interrupción como de costumbre. Si se liberan todos los bloqueos retenidos por el proceso actual, el conteo preempt_ se restablecerá a cero. En este punto, el código que libera las comprobaciones de bloqueo para ver si está establecido need_resched. Si es así, se llama al programador.
1.6 Oportunidad de Prevención de Kernel

En el kernel 2.6, el kernel introduce la capacidad de preferencia, ahora, mientras la reprogramación sea segura, el kernel puede aprovechar la tarea que se está ejecutando en cualquier momento.

Entonces, ¿cuándo es seguro reprogramar? Siempre que la cuenta de prempt sea 0, el kernel puede adelantarse. Por lo general, los bloqueos e interrupciones son signos de áreas no preferidas. Dado que el kernel es compatible con SMP, si el bloqueo no se mantiene, el código que se está ejecutando se puede redirigir, es decir, se puede anular.

Si el proceso en el kernel está bloqueado, o si llama explícitamente a schedule (), la preferencia del kernel también ocurrirá explícitamente. Esta forma de preferencia de kernel siempre ha sido admitida (en realidad, renunciando activamente a la CPU) porque no hay necesidad de lógica adicional para garantizar que el kernel pueda ser reemplazado de forma segura. Si el código llama explícitamente a schedule (), debe quedar claro que se puede anticipar de forma segura.

La preferencia de núcleo puede ocurrir:
l Antes de que el controlador de interrupciones se ejecute y regrese al espacio del kernel.
l Cuando el código del kernel es una vez más preventivo, como desbloquear y habilitar interrupciones por software (local_bh_enable).
l Si la tarea en el kernel llama explícitamente a schedule ()
l si la tarea en el kernel está bloqueada (esto también hará que se llame a schedule ()

Copyright © Conocimiento de Windows All Rights Reserved