Clocksources y el problema "Clocksource tsc unstable"
Desde hace tiempo llevo viendo un mensaje de error en mi máquina al arrancar Debian Squeeze: “Clocksouirce tsc unstable (delta = <valor nanosegundos>)”. No le había dado mucha importancia ya que el sistema funciona perfectamente, pero tenía pendiente descubrir de qué se trataba.
Al empezar a buscar por la red, descubrí que mucha gente tiene este mismo problema, pero casi nadie (o nadie) explica qué ocurre exactamente. Este post tiene como intención esclarecer el uso del kernel de linux de los generadores de reloj, la causa de este problema y su solución.
Sistemas operativos y generadores de reloj.
Todos los sistemas operativos necesitan llevar un seguimiento de la hora en la que se encuentra el sistema mientras éste está funcionando. Esto es imprescindible para crear todos los timestamps tan utilizados en los SOs: los relativos a archivos, registro de logs, etc. Para realizar esta tarea, se dispone del IRQ (o interrupción) 0, que indica al núcleo del sistema operativo que debe actualizar la hora vigente. Al arrancar linux, el kernel elige un generador de reloj y mide el tiempo que se tarda en generar un pulso (normalmente se mide en nanosegundos), almacenando este valor. De esta forma, cada vez que se genera una interrupción 0 el núcleo aumenta en uno un contador de ticks de reloj, y al multiplicar por el tiempo de separación entre ticks es capaz de calcular la hora. Si se requiere mayor precisión, el sistema calcula el número de segundos transcurridos desde el último tick.
Por otro lado, los sistemas operativos multiproceso y/o multitarea necesitan controlar el tiempo de ejecución de cada proceso/tarea para repartir los recursos del sistema entre todas las aplicaciones que corren en el sistema. Esto lo hace con el generador de reloj APIC, que viene en el núcleo del procesador.
Evolución de los procesadores y la aparición de problemas en el cálculo del tiempo
Desde la aparición de los procesadores Pentium y algunos equivalente (como AMD) se implantó un sistema de medición de tiempo llamado TSC, cuyo se uso se generalizó rápidamente.
TSC corresponde a la siglas de Time Stamp Counter. Es un registro de 64 bits que se encuentra en el núcleo del procesador y que va almacenando el número de ticks acumulados desde el último inicio/reinicio. Tiene un refresco muy rápido, es preciso y accesible, de ahí que sea el método más utilizado para control de tiempo en la plataforma x86. Sin embargo la evolución que han sufrido los procesadores en los últimos tiempos ha mermado la fiabilidad de este método para controlar tiempo.
Hace algo de tiempo se decidió que los procesadores no deben estar contínuamente al 100% de consumo energético. Desarrollado en principio para mejorar la duración de las baterías de portátiles, se implementó un sistema para hacer variar la frecuencia a la que trabaja el procesador y, consecuentemente, su consumo según las necesidades e indicaciones que tuviese el sistema en cada momento. Al ver lo efectivo que era tanto para ahorro de consumo como para evitar problemas de calentamiento, este sistema se ha portado posteriormente también a los PCs de escritorio. Pero este sistema plantea un problema: el TSC ha dejado de ser fiable. Por cada tick del reloj del procesador se aumenta el tsc, pero dependiendo del estado de velocidad, un tsc puede aumentar, por ejmplo, 800 veces en 1 segundo y 1600 al segundo siguiente. Este problema ocurre sobre todo con los AMDs, que simplemente han reconocido este problema y no parece que intentasen nada para solucionarlo, aunque algunos Intel también lo presentan.
Posteriormente y para rizar el rizo han aparecido los procesadores multinúcleo. Al ser un registro, el TSC está presente en cada uno de los núcleos, y lo peor es que no es posible que todos vayan completamente sincronizados. Intel ha anunciado que está haciendo grandes esfuerzos por que los TSCs de los núcleos de sus micros vayan bien sincronizados, pero de momento no han conseguido terminar de solucionar el problema. Por lo que parece los núcleos del procesador no propagan lo suficiente rápido los valores de sincronización y el kernel de linux se ve afectado.
Así pues si nuestro ordenador no es demasiado antiguo podemos estar afectados por este problema. Lo normal es que el kernel de Linux se percate poco después de arrancar de que el TSC no es una fuente fiable y la cambie por otra distinta. La red está plagada de reportes de usuarios que notifican que su sistema se llega a retrasar 1 minuto al arrancar y recibir este mensaje del núcleo. Esto es un problema, en principio, molesto pero no alarmante. Sin embargo hay reportes de muchos otros usuarios que comentan que la máquina se les cuelga durante 2 minutos o incluso indefinidamente por este problema. Para ser que por un motivo desconocido el kernel detecta el problema pero no cambia la fuente de reloj.
Para detectar si nuestro sistema está afectado podríamos echar mano del dmesg:
nefeli@oscar:~$ dmesg | grep -i clocksource
[ 22.965110] Clocksource tsc unstable (delta = -172516754 ns)
Esta es la prueba indiscutible de que nuestro tsc no es de fiar, pero no hay que alarmarse. Lo más lógico es que el kernel haya cambiado la fuente automáticamente para solucionar el problema. Si queremos comprobarlo podemos acudir al archivo correspondiente en el sistema de ficheros del sistema:
nefeli@oscar:~$ cat /sys/devices/system/clocksource/clocksource0/current_clocksource hpet
Como se puede ver el kernel ha cambiado la fuente de reloj por una fiable para evitar problemas de inestabilidad. El núcleo genera automáticamente una lista de clocksources al arrancar y los ordena de menor a mayor granularidad y fiabilidad. Cuando una fuente falla el sistema debería detectarlo y cambiar a la siguiente de la lista. Esta lista está visible, como siempre, en /sys:
nefeli@oscar:~$ cat /sys/devices/system/clocksource/clocksource0/available_clocksource
hpet acpi_pm jiffies tsc
En mi caso tsc se encuentra en último lugar porque no es una fuente fiable, y hpet ha tomado el puesto.
Posibles alternativas al TSC
Si tenemos el problema del TSC en nuestro sistema deberíamos optar por cambiar el clocksource. Las opciones más factibles son las siguientes:
- HPET: son las siglas de High Precission Event Timer, también conocido como reloj multimedia. Ha sido desarrollado conjuntamente entre Intel y microsoft, aunque en las plataformas AMD también se encuentra. Es un generador de reloj, más rápido el el RTC (Real Time Clock), y se suele utilizar para sincronizaciones. Además puede generar interrupciones periódicas.
- ACPI_PM: En realidad es el PMT (Power Management Timer). Es el generador de reloj destinado a gobernar el sistema ACPI de la máquina. Como consecuencia, todas las máquinas ACPI lo tienen.
Acelerar el proceso de arranque si tenemos el problema
La mayoría de la gente se encuentra con que este problema le causa grandes latencias de arranque. Para evitarlas basta con indicarle al núcleo en el arraque que utilice un clocksource distinto. Para ello editamos el archivo de grub /boot/grub/menu.lst y añadimos a los parámetros de arranque del kernel:
clocksource=<fuente_elegida>
De esta forma el núcleo arrancará utilizando directamente la fuente que le indiquemos evitando esos largos tiempos de espera.

Pingback: [Solucionado]Ubuntu se bloquea por minutos « ZdeS – Zona de Sistemas