2011-06-29 8 views
5

Hola chicos, Mientras se hace portar SMP de algunos de nuestros conductores (en objetivo PowerPC) se observó un comportamiento en el que te necesito chicos a arrojar algo de luz:disable_local_irq y los cronómetros del núcleo

  1. En haciendo un local_irq_disable() en un sistema UP los jiffies tienden a congelar, es decir, el conteo deja de incrementarse. Es esto esperado? Pensé que la interrupción del decrementador es 'interna' y no debería ser afectada por el tipo de llamada local_irq_disable ya que esperaba deshabilitar el procesamiento de interrupción IRQ local (interrupción externa). El sistema por supuesto también se congela al hacer un local_irq_enable() el cuenta de jiffies salta y parece estar compensando el 'lapso de tiempo ' entre la llamada local_irq_disable() y enable().

  2. Haciendo lo mismo en un sistema SMP (P2020 con 2 núcleos e500) los resultados son sorprendentes. En primer lugar, el módulo que se está insertando en hace esta prueba siempre se ejecuta en el núcleo 1. Además, a veces lo hace no ver una congelación del contador 'jiffies' y, a veces vemos que de hecho se congela. De nuevo, en caso de congelación de conteo, tiende a saltar después de hacer un local_irq_enable(). No tengo idea de por qué esto puede estar ocurriendo . ¿Sabemos que en el caso de un SMP ambos núcleos ejecutan un temporizador de programación, por lo que que en algunos casos no vemos un congelamiento de conteos de jiffie o es solo en el núcleo 0?

Asimismo, puesto que los temporizadores del núcleo se basan en unidades de tiempo '' - esto significaría que ninguno de nuestros contadores de tiempo del kernel se disparará si local_irq_disable() ha sido hecho? ¿Cuál sería el caso de que esto se haga en uno de los núcleos en un sistema SMP ?

Hay muchas otras preguntas, pero supongo que éstos serán suficientes para comenzar una discusión general sobre el mismo :)

TIA

NS

Algunos más comentarios de la experimentación realizada .

Mi comprensión en este momento es que dado que los temporizadores kernel dependen de 'jiffies' para disparar, en realidad no dispararán en un sistema UP cuando emita un local_irq_save(). De hecho, parte de nuestro código se basa en la suposición de que cuando expido un local_irq_save() garantiza la protección contra interrupciones en el procesador local y en los temporizadores del núcleo también.

Sin embargo, al llevar a cabo el mismo experimento en un sistema SMP, incluso con ambos núcleos ejecutando un local_irq_save(), los jiffies NO dejan de incrementarse y el sistema no se congela. Cómo es esto posible ? ¿LINUX utiliza algún otro mecanismo para activar interrupciones de temporizador en el sistema SMP o posiblemente usar IPI? Esto también rompe nuestra suposición de que local_irq_disable protegerá el sistema contra los temporizadores kernel que se ejecutan en el mismo núcleo por lo menos.

¿Cómo hacemos para escribir un código que sea seguro contra eventos asíncronos, es decir, interrupciones y temporizadores de núcleo, y es válido tanto para UP como para SMP?

Respuesta

4

local_irq_disable solo deshabilita las interrupciones en el núcleo actual, por lo tanto, cuando tiene núcleo único, todo está deshabilitado (incluidas las interrupciones del temporizador) y es por eso que los jiffies no se actualizan. Cuando se ejecuta en SMP, algunas veces desactivas las interrupciones en el núcleo que está actualizando los jiffies, a veces no. Esto normalmente no es un problema, ya que se supone que las interrupciones se deben desactivar solo por períodos muy cortos, y todos los temporizadores programados se activarán después de que las interrupciones se vuelvan a habilitar.

¿Cómo sabe que su módulo siempre se ejecuta en el núcleo 1? En las versiones actuales del kernel, incluso puede estar ejecutándose en más de un núcleo al mismo tiempo (es decir, si no lo forzó a hacerlo).

+0

Como estaba haciendo todo esto en module_init, también estaba imprimiendo la CPU que estaba en mi memoria (get_cpu()). Ahora la parte triste es que en los casos en los que estaba viendo 'jiffies' atascados, estaba en el núcleo 1 y en los casos en los que 'jiffies' no estaban bloqueados, ¡todavía estaba en el núcleo 1! –

+0

También, curiosamente, cuando uso local_irq_save()/restore() en lugar de local_irq_enable()/disable(), el problema de que los bloqueos se bloqueen nunca ocurre independientemente del núcleo en el que estoy. Completamente confundido !! :( –

+0

Victor, ¿qué quiere decir con ejecutar en más de un núcleo al mismo tiempo? ¿Es eso una realidad? ¿Puede indicarme algo de literatura al respecto? –

4

Hay varias facetas de este problema. Les permite tomar 1 por 1.

1.

a)

local_irq_save() simplemente borra la bandera de IF de la eflags registro. Los manejadores de IRQ pueden funcionar concurentemente en los otros núcleos.

global_irq_save() no está disponible porque eso requeriría la comunicación del interprocesador para implementarlo y en realidad no es realmente necesario ya que la inhabilitación de irq local solo está prevista para un período de tiempo muy corto.

b)

moderno APIC permite IRQ distribución dinámica entre los presentes núcleos y además raras excepciones, el núcleo esencialmente los programas de los registros necesarios para obtener una distribución round-robin de las IRQ.

La consecuencia de esto es que si los irqs están deshabilitados el tiempo suficiente localmente, cuando el APIC entrega una IRQ al núcleo que los tiene deshabilitados, el resultado final será que el sistema dejará de recibir este IRQ en particular hasta el punto donde los irqs se vuelven a habilitar localmente en el núcleo que recibió la última IRQ de ese tipo.

2.

En cuanto a los diferentes resultados en cuanto a actualizaciones jiffies y desactivación de IRQ, que depende de la clocksource seleccionado.

Usted puede averiguar cuál es elegido por la consultoría:

$ cat/sys/devices/system/clocksource/clocksource0/current_clocksource

si tiene TSC como clocksource entonces todos los núcleos tienen forma local. Sin embargo, si su fuente de reloj es otra cosa, es decir: HPET un dispositivo externo, los jiffies se congelarán por los motivos descritos en el punto 1.

Cuestiones relacionadas