Hay un fallo de codificaci�n donde un pedazo de c�digo intenta
obtener un spinlock dos veces: �l esperar� siempre, esperando a
que el bloqueo sea liberado (spinlocks, rwlocks y sem�foros no son
recursivos en Linux). Esto es trivial de diagnosticar: no es
un tipo de problema de
estar-cinco-noches-despierto-hablando-con-los-suaves-conejitos-del-c�digo.
Para un caso ligeramente m�s complejo, imag�nate que tienes una
regi�n compartida por un bottom half y un contexto de usuario. Si
usas una llamada spin_lock() para protegerla,
es posible que el contexto de usuario sea interrumpido por el bottom
half mientras mantiene el bloqueo, y el bottom half entonces
esperar� para siempre para obtener el mismo bloqueo.
Ambas son llamadas deadlock (bloqueo muerto), y como se mostr� antes,
puede ocurrir con una CPU simple (aunque no en compilaciones para UP,
ya que los spinlocks se desvanecen en la compilaci�n del n�cleo con
CONFIG_SMP=n. A�n tendr�s corrupci�n de datos en
el segundo ejemplo).
Este bloqueo completo es f�cil de diagnosticar: en equipos SMP el
cron�metro guardi�n o compilado con DEBUG_SPINLOCKS
establecido (include/linux/spinlock.h) nos
mostrar� esto inmediatamente cuando suceda.
Un problema m�s complejo es el tambi�n llamado `abrazo mortal',
involucrando a dos o m�s bloqueos. Digamos que tienes una tabla
hash: cada entrada en la tabla es un spinlock, y una cadena de
objetos ordenados. Dentro de un manejador softirq, algunas veces
quieres alterar un objeto de un lugar de la tabla hash a otro:
coges el spinlock de la vieja cadena hash y el spinlock de la
nueva cadena hash, y borras el objeto de la vieja y lo insertas
en la nueva.
Aqu� hay dos problemas. El primero es que si tu c�digo siempre
intenta mover el objeto a la misma cadena, �l se har� un deadlock
cuando se intente bloquear dos veces. El segundo es que si la
misma softirq u otra CPU est� intentando mover otro objeto en la
direcci�n inversa podr�a pasar lo siguiente:
Tabla 4-1. Consecuencias
CPU 1 | CPU 2 |
---|
Pilla bloqueo A -> OK | Pilla bloqueo B -> OK |
Pilla bloqueo B -> spin | Pilla bloqueo A -> spin |
Las dos CPUs esperar�n para siempre, esperando a que el otro libere
su bloqueo. �l parecer�, oler�, y se sentir� como si cayera el sistema.