Aprovechando las bondades del Kernel Real TIme


¡Esto es realmente tiempo real! el kernel compilado con el parche rt nos habilita muchas posibilidades pero no las activa, recién después de aplicar esta configuración no vamos a tener nunca pérdida de audio (xruns) y vamos a poder usar latencias muy bajas.

El paso final es establecer unas cuantas prioridades de tareas. El parche para tiempo real debería haber creado varias tareas IRQ, así como una tarea hrtimer. Pueden visualizarse con el comando:

# ps -e

nos muestra lo siguiente (solo copio las tareas que nos pueden llegar a interesar para audio ya que son muchas, para ahorrar espacio):

PID TTY TIME CMD
1 ? 00:00:01 init
2 ? 00:00:00 kthreadd
3 ? 00:00:00 migration/0
4 ? 00:00:00 posixcputmr/0
6 ? 00:01:11 sirq-timer/0
12 ? 00:00:00 sirq-hrtimer/0
53 ? 00:00:00 IRQ-9
295 ? 00:00:25 IRQ-12
296 ? 00:00:00 IRQ-1
303 ? 00:00:00 IRQ-8
616 ? 00:00:00 IRQ-16
628 ? 00:00:00 IRQ-19
645 ? 00:00:00 IRQ-18
665 ? 00:00:00 IRQ-23
692 ? 00:00:00 IRQ-6
752 ? 00:00:02 IRQ-14
753 ? 00:00:05 IRQ-15
1435 ? 00:00:00 IRQ-7
1493 ? 00:01:14 IRQ-17
1872 ? 00:00:08 IRQ-20
2480 ? 00:00:00 IRQ-4
2483 ? 00:00:00 IRQ-3

Nos interesan las tareas: sirq-timer/0, sirq-hrtimer/0 y la IRQ de nuestra placa de sonido que tenemos que ubicar cual es (ya voy a explicar como ubicarla). En un sistema core dual debe haber dos de cada tarea, una por cada CPU. Yo no pude comprobarlo porque no tengo core dual.

Vamos a tomar nota del PID de cada una: 6 (sirq-timer) y 12 (sirq-hrtimer).

Luego vamos a buscar el pid de la tarea IRQ en la que reside la tarjeta de sonido.

Vemos la salida de:

# cat /proc/interrupts

debería revelar esto:

CPU0
0: 200 IO-APIC-edge timer
1: 14890 IO-APIC-edge i8042
3: 2 IO-APIC-edge
4: 1 IO-APIC-edge
6: 7 IO-APIC-edge floppy
7: 0 IO-APIC-edge parport0
8: 2 IO-APIC-edge rtc0
9: 0 IO-APIC-fasteoi acpi
12: 529675 IO-APIC-edge i8042
14: 88412 IO-APIC-edge ide0

15:

587044

IO-APIC-edge

ide1

16:

0

IO-APIC-fasteoi

uhci_hcd:usb1

17:

1685387

IO-APIC-fasteoi

ICE1712

18:

0

IO-APIC-fasteoi

uhci_hcd:usb3

19:

0

IO-APIC-fasteoi

uhci_hcd:usb2

20:

19611

IO-APIC-fasteoi

eth0

23:

229710

IO-APIC-fasteoi

ehci_hcd:usb4

NMI:

0

Non-maskable interrupts

LOC:

7295599

Local timer interrupts

RES:

0

Rescheduling interrupts

CAL:

0

function call interrupts

TLB:

0

TLB shootdowns

TRM:

0

Thermal event interrupts

SPU:

0

Spurious interrupts

ERR:

0

MIS:

0

Entonces según esta información:

17: 1660453 IO-APIC-fasteoi ICE1712

el IRQ-17 es donde está mi placa de sonido (en mi caso me doy cuenta porque ICE1712 es el chipset de las m-audio, que es mi placa)

Para obtener el PID, uso de nuevo el comando:

# ps -e

si se fijan al principio del documento (cuando mostre el resultado de #ps -e) era el PID 1493

Ahora vamos a utilizar el comando chrt para establecer prioridades real time. En Debian, este comando forma parte del paquete schedutils. No importa el orden en el que se establecen las prioridades.

Establecemos nuevas prioridades para cada tarea:

En mi caso: # chrt -f -p 99 6

# chrt -f -p 99 12

# chrt -f -p 99 1493

Esto debe establecer una prioridad de tiempo real a las tareas identificadas como 6, 12 y 1493. Una prioridad tan alta como 99 podría no ser en realidad necesaria e incluso un tanto insegura (para mi si es necesaria).

Hay que probar con valores (por lo menos de 50 a 99) hasta encontrar los adecuados.

Luego y usamos el comando:

# top

para ver si cambiaron las prioridades (antes ejecuté jackd para poner en uso la placa de sonido para que aparezca IRQ-17 entre los procesos) me devuelve:

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2747 gabriel 20 0 22588 2052 1716 S 11.6 0.1 0:02.91 jackd
2718 gabriel 20 0 37700 13m 9.9m S 11.3 0.9 0:09.77 gnome-terminal
2741 gabriel 20 0 44080 11m 9.8m S 10.0 0.8 0:02.98 qjackctl
2577 root 20 0 97.8m 11m 4788 S 6.6 0.8 0:07.85 Xorg
1493 root RT -5 0 0 0 S 3.3 0.0 0:01.19 IRQ-17
2713 gabriel 20 0 30472 11m 7524 S 1.7 0.7 0:01.77 pcmanfm
295 root -51 -5 0 0 0 S 0.7 0.0 0:00.70 IRQ-12
2711 gabriel 20 0 20560 10m 7168 S 0.7 0.7 0:04.87 lxpanel
2739 gabriel 20 0 2428 1136 900 R 0.3 0.1 0:00.41 top
1 root 20 0 2132 748 652 S 0.0 0.0 0:01.38 init
2 root 15 -5 0 0 0 S 0.0 0.0 0:00.00 kthreadd
3 root RT -5 0 0 0 S 0.0 0.0 0:00.00 migration/0
4 root RT -5 0 0 0 S 0.0 0.0 0:00.00 posixcputmr/0
5 root -51 -5 0 0 0 S 0.0 0.0 0:00.00 sirq-high/0
6 root RT -5 0 0 0 S 0.0 0.0 0:00.33 sirq-timer/0
7 root -51 -5 0 0 0 S 0.0 0.0 0:00.00 sirq-net-tx/0
8 root -51 -5 0 0 0 S 0.0 0.0 0:00.00 sirq-net-rx/0

en este caso no aparece la línea:

12 root RT -5 0 0 0 S 0.0 0.0 0:00.01 sirq-hrtimer/0

pero se debe a que top esta en movimiento todo el tiempo (pero les aseguro que está).

Como pueden ver en la sección PR se puede ver la prioridad RT a la que están corriendo las tareas sirq-timer/0, sirq-hrtimer/0 y IRQ-17.

En realidad todo lo que hicimos hasta ahora sirve para probar el funcionamiento de las prioridades. Estas prioridades serán restablecidas después de cada reinicio, así que deberá crearse un script de inicio sencillo, para recuperarlas.

Dado que los pids de sirq-timer/0 y sirq-hrtimer/0 no van a cambiar, pero el pid de la placa de sonido sí, vamos a usar “pgrep” para que busque la tarea IRQ-17, a continuación describo como tiene que ser el contenido del script y donde debemos copiarlo, (yo voy a usar el editor de textos nano pero ustedes pueden usar el que quieran) :

# nano realtime.sh

copiamos lo que sigue a continuación adentro:

#!/bin/bash

#el 99 es la prioridad y el 6 el pid del sirq-timer

chrt -f -p 99 6

#el 12 es el pid de sirq-hrtimer

chrt -f -p 99 12

#IRQ-17 es el IRQ de la placa de sonido

chrt -f -p 99 `pgrep IRQ-17`

presionamos ctrl-o para salvar y luego <enter>

Luego le damos permisos de ejecución con:

# chmod +x realtime.sh

Y lo copiamos a /etc/init.d :

# cp realtime.sh /etc/init.d/

Y creamos un enlace simbólico que copiamos a /etc/rc5.d ; /etc/rc4.d ; /etc/rc3.d y a /etc/rc2.d

# ln -s /etc/init.d/realtime.sh /etc/rc5.d/S99realtime

# cp /etc/rc5.d/S99realtime /etc/rc4.d/

# cp /etc/rc5.d/S99realtime /etc/rc3.d/

# cp /etc/rc5.d/S99realtime /etc/rc2.d/

Para comprobar que todo funciona una vez reiniciado el sistema usar el comando top de nuevo.

Nota sobre APIC: En placas bases con APIC y kernels donde APIC está habilitado, pueden tenerse dificultades al establecer prioridades en las IRQ. Simplemente iníciese la máquina con la opción noapic en grub para el kernel utilizado, y compruébese si desaparecen los problemas.

He realizado este artículo basándome en el de Florian Paul Schmidt (muy completo el que quiera lo puede buscar en la web) pero agregando todo lo que yo pude experimentar.

Espero que sirva.

, , , ,

  1. No hay Comentarios
(No será publicado)