2011-01-20 11 views

Respuesta

15

Ejemplo: su controlador se está ejecutando y acaba de sacar un bloqueo que controla el acceso a su dispositivo. Mientras se mantiene el bloqueo, el dispositivo emite una interrupción, lo que hace que se ejecute el manejador de interrupciones. El controlador de interrupciones, antes de acceder al dispositivo, también debe obtener el bloqueo. Sacar un spinlock en un controlador de interrupción es algo legítimo; esa es una de las razones por las que las operaciones de bloqueo de hilado no duermen. Pero, ¿qué sucede si la rutina de interrupción se ejecuta en el mismo procesador que el código que eliminó el bloqueo originalmente? Mientras el controlador de interrupciones está girando, el código no interrumpido no podrá ejecutarse para liberar el bloqueo. Ese procesador girará para siempre.

Fuente: http://www.makelinux.net/ldd3/chp-5-sect-5.shtml

+1

Evidentemente, esta situación se puede evitar desactivando las interrupciones en las secciones críticas que están protegidas mediante spinlocks. Por ejemplo, Oberon toma este enfoque (Pg. 57). http://e-collection.library.ethz.ch/eserv/eth:26082/eth-26082-02.pdf – gjain

2

Otra posible explicación es que, en un contexto pre-spinlock preferente está desactivado.

+0

¿Por qué está deshabilitado? – Bandicoot

2

Aparte de lo que willtate ha mencionado, suponga que un proceso duerme mientras sostiene un spilock. Si el nuevo proceso programado intenta adquirir el mismo spinlock, comienza a girar para que el bloqueo esté disponible. Como el nuevo proceso sigue girando, no es posible programar el primer proceso y, por lo tanto, nunca se libera el bloqueo, lo que hace que el segundo proceso gire para siempre y tenemos un punto muerto.

7

No es que usted no puede dormir mientras sostiene un bloqueo de giro. Es una idea muy muy mala idea de hacer eso. Citando LDD:

Por lo tanto, la regla principal que se aplica a los spinlocks es que cualquier código debe, mientras se mantiene un spinlock, ser atómico. No puede dormir; de hecho, no puede renunciar al procesador por ningún motivo excepto para interrupciones de servicio (y algunas veces ni siquiera entonces).

Cualquier interbloqueo como el mencionado anteriormente puede provocar un estado irrecuperable. Otra cosa que podría suceder es que el spinlock se bloquea en una CPU, y luego, cuando el hilo duerme, se despierta en la otra CPU, lo que provoca un pánico en el kernel.

Respondiendo comentario de Bandicoot, en un contexto de bloqueo de giro, de tanteo se desactiva sólo en el caso de un solo procesador derecho preferente de compra del núcleo debido a la desactivación de tanteo impide eficazmente razas.

Si el kernel se compila sin CONFIG_SMP, pero se configura CONFIG_PREEMPT, a continuación, el spinlocks simplemente desactiva la prioridad, que es suficiente para evitar cualquier carrera. Para la mayoría de los propósitos, podemos pensar en la apropiación como equivalente a SMP, y no preocuparnos por eso por separado.

http://www.kernel.org/pub/linux/kernel/people/rusty/kernel-locking/index.html

3

no estoy de acuerdo con la respuesta de William (su ejemplo). Está mezclando dos conceptos diferentes: preferencia y sincronización.

una interrupción Contexto podría adelantarse un contexto de proceso y por lo tanto si hay un recurso compartido por la tanto, tenemos que utilizar

spin_lock_irqsave() 

a (1) deshabilitar la IRQ (2) adquirir el bloqueo. En el paso 1, podríamos inhabilitar la opción de interrupción.

Creo que this hilo es muy convincente. Sleep() significa que un hilo/proceso cede el control de la CPU y CONTEXT SWITCH a otro, sin soltar el spinlock, es por eso que está mal.

+0

Estoy de acuerdo, si no estoy equivocado, el problema de William se resuelve mediante el uso de la función spin_lock apropiada para deshabilitar la opción de interrupción. El problema del sueño es diferente, solo debes evitar dormir en la sección crítica del bloqueo de giro, de lo contrario obtendrás un mal rendimiento o un punto muerto. –

3

El punto clave es en el kernel de Linux, la adquisición de un bloqueo de giro desactivará la preferencia. Por lo tanto, dormir mientras se mantiene un bloqueo de giro podría provocar un punto muerto.

Por ejemplo, el hilo A adquiere un bloqueo de giro. El subproceso A no se adelantará hasta que libere el bloqueo. Siempre que el subproceso A haga su trabajo rápidamente y libere el bloqueo, no hay problema. Pero si el hilo A duerme mientras sostiene el bloqueo, el hilo B podría programarse para ejecutarse, ya que la función de dormir invocará el programador. Y el hilo B también podría adquirir el mismo candado. El subproceso B también desactiva la preferencia y trata de adquirir el bloqueo. Y se produce un punto muerto. El hilo B nunca obtendrá el bloqueo, ya que el hilo A lo mantiene y el hilo A nunca se ejecutará, ya que el hilo B desactiva la preferencia.

¿Y por qué desactivar la preferencia en primer lugar? Supongo que es porque no queremos que los hilos en otros procesadores esperen demasiado tiempo.

+0

si el derecho preferente está deshabilitado, ¿el subproceso B puede programarse para EJECUTAR mientras que el proceso A actual duerme? –

+0

La acción "dormir" invocará al programador, aunque la preferencia está deshabilitada. –

0

total de acuerdo con Nan Wang. Supongo que el concepto más importante es "prioridad" & "programación" y cómo sucede cuando se adquiere spinlock. cuando se adquiere spinlock, prioridad está deshabilitada (verdadero o no, no sé, pero supongo que es correcto), significa que la interrupción del temporizador no puede anticiparse al titular del spinlock actual, pero el spinlock actual todavía mantiene habilitadas las funciones del kernel para dormir & invoke scheduler & ejecuta "otra tarea". si "otra tarea" pasó a querer adquirir el mismo spinlock que el primer titular del spinlock, aquí viene el problema: dado que la preferencia ya está deshabilitada por el primer titular del spinlock, "otra tarea" invocada activamente por el planificador mediante el primer spinlock titular, no puede ser reemplazado, por lo que su giro siempre toma la CPU, esta es la razón por la cual ocurre un punto muerto.

3

creo que esto tiene una respuesta mail claridad:

Un proceso no pueda ser substituida ni el sueño mientras se mantiene un comportamiento debido spinlocks spinlock. Si un proceso toma un spinlock y se va a dormir antes de soltarlo. Un segundo proceso (o un manejador de interrupciones) que para agarrar el spinlock estará ocupado. En una máquina uniprocesador, el segundo proceso bloqueará la CPU y no permitirá que el primer proceso se active y libere el spinlock para que el segundo proceso pueda continuar, básicamente es un punto muerto.

Cuestiones relacionadas