Cómo forzar el kernel de Linux a "congelarse" (o casi congelarse) durante unos cientos de milisegundos


17

Estamos ejecutando un proceso en tiempo real en un kernel no en tiempo real (CentOS 6), y esto probablemente no va a cambiar.

Tenemos una aplicación de transmisión de video que requiere aproximadamente 500 MB / s de tráfico PCIe desde un FPGA personalizado de forma continua durante 1,5 horas a la vez. La aplicación funciona bastante bien, la mayoría de las veces. Sin embargo, hemos tenido situaciones en las que parece que el núcleo simplemente deja de responder al servicio de solicitudes PCIe o de memoria de hasta 500 milisegundos a la vez. Esto parece suceder durante el archivo de ráfaga IO desde otro hilo. Me resulta imposible intentar replicar este problema simplemente haciendo un montón de IO de archivos ficticios desde el espacio del usuario mientras se ejecuta la aplicación principal.

¿Hay una manera de forzar (simular) una "congelación" global del núcleo de Linux (en particular, PCIe parar o todos los accesos de memoria DDR3 o algo así) para que podamos reproducir este problema?

Hemos implementado hasta 10 milisegundos de almacenamiento intermedio en la memoria FPGA interna, pero eso no es suficiente. Podemos almacenar en búfer a FPGA DDR3 y luego volcar al host, pero necesitamos un método para probar esta nueva característica bajo coacción.

No queremos que el núcleo se congele o bloquee permanentemente. Nos gustaría poder establecer el intervalo de tiempo.

Estoy buscando algo similar a escribir valores mágicos /proc/sys/vmtemporalmente que haga que el sistema prácticamente se arrastre, y luego retroceder después de unos cientos de milisegundos, pero mirar la cantidad de formas posibles de romperlo no es para un novato como yo ( https://www.kernel.org/doc/Documentation/sysctl/vm.txt ). Tal vez algunos numactlmagia?


Mi impresión es que esto requiere escribir un módulo del núcleo. Tendrá que congelar todos los subprocesos de todas las CPU de alguna manera y hacer arreglos para reiniciar en una interrupción del temporizador.
Gilles 'SO- deja de ser malvado'

No quiero congelar los hilos, ¡quiero congelar el núcleo! Quiero decir, quiero evitar el acceso al hardware (memoria y / o PCIe y / o disco) por un corto tiempo. Si eso no funciona, no me importa hacer las cosas muy poco optimizadas, deshabilitar el caché L1, etc. Simplemente no sé cómo hacer esto.
Mark Lakata

1
Ah, ¿entonces no quieres congelar el kernel, solo quieres congelar la parte del kernel que responde a algún hardware? Eso también requeriría sumergirse bastante en el núcleo.
Gilles 'SO- deja de ser malvado'

No me importa congelar el núcleo por completo, siempre que el hardware esté congelado como parte de él.
Marcos Lakata

1
Resulta que el problema está relacionado con la transferencia TLB, ya que la CPU host descarga algunas memorias intermedias de E / S (estamos usando HDF5 para escribir archivos), y esta transferencia TLB está causando que el coprocesador también falle, ya que es un sistema NUMA. Supongo que todo lo que necesitamos ahora es una forma confiable de causar una paliza TLB programáticamente durante un período de tiempo controlado.
Marcos Lakata

Respuestas:


9

Una opción para hacer una prueba rápida podría ser usar un kernel habilitado para KGDB y detener el kernel manualmente y probar, vea este enlace .

Por otro lado, las cosas que recuerdo que podrían causar que sus pausas:

  • cpufreq, cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_transition_latencyel valor está en ns (4000 en mi procesador AMD FX (tm) -8120 de ocho núcleos) no debería ser un problema, pero verifique
  • Regulación térmica, ya sea la propia CPU o el módulo regulador de voltaje.
  • o el tráfico y NAPI / red pesada
  • PCIe ASPM ( cat /sys/module/pcie_aspm/parameters/policy)
  • Contención en las memorias intermedias de su dispositivo de destino (disco duro, nic ...)
  • Error en el firmware de algunos dispositivos en el bus PCIe (incluso si no lo está usando), puede intentar apagarlos con /sys/bus/pci/devices/$DEVICE/power/control

¿Podría usar en kdblugar de kgdbhacer lo mismo? Nunca he usado tampoco. ¿Es esto como la secuencia de comando "Stop-A" en estaciones de trabajo Sun de antaño? Si acabo de hacer una rápida Pet Sis-g, a continuación, escriba "go", voy a tener una alta probabilidad de no romper el sistema? (ref: kernel.org/pub/linux/kernel/people/jwessel/kdb/… )
Mark Lakata

1
Probablemente podrás usar kdb. Tenga en cuenta que se debe trabajar con los teclados USB conectado, pero trata de tener un PS / 2 uno a mano por si acaso. Y este es un depurador de muy bajo nivel (kernel land), así que, como siempre, guarde copias de seguridad y, si se rompe, puede conservar ambas piezas :).
Jorge Nerín

Antes de recurrir a ajustes con el kernel que empezarían por tratar de descargar los módulos del kernel no utilizados para los dispositivos PCIe que podrían estar utilizando el bus (controladores de gráficos más notablemente), ya sea física y la eliminación de los dispositivos del sistema o encendido apagado. PCIe 1.0 x1 tiene un ancho de banda de 250 MB / sy PCIe 2.0 x1 sube a 500 MB / s, son tanto el origen como dispositivo de destino libre de aceptar dicha tasa sostenida y sin interrupciones o tienen más carriles para permitir más espacio para la cabeza?
Jorge Nerín

Otra posible fuente del retraso podría ser algún manejador de administración de energía ACPI de algún dispositivo o incluso algún manejador de CPU SMM que espera un evento externo.
Franki

2

¿Podemos tener más detalles sobre cómo se comunica su aplicación con la FPGA? ¿Es la aplicación que lee el búfer del FPGA, o el FPGA que envía la interrupción al núcleo (como las tarjetas de red)?

Espero que abra un bloque / char in / dev y luego se comunique con él. Esto significa que utiliza un controlador para hacer la comunicación entre la aplicación y el archivo / dev / XXX.

Me gustaría tener la salida de cat /proc/interrupts:; lsmod;ls -al /dev/yourmod

Aquí están las ideas:

  • Si se activa por interrupción, puede configurar el PIC de la CPU para deshabilitar la IRQ correspondiente y luego volver a habilitarla. Esto hará que se ignore cada solicitud de la tarjeta (sin que la tarjeta se dé cuenta).
  • Si es como una lectura de búfer, puede:
    • Ponga su aplicación en estado de suspensión, para que los datos del FPGA no se lean y su búfer se llene, luego active su aplicación y continúe la lectura.
    • Use "crash" o "kgdb" para cambiar el valor de "lectura" a "noop" durante unos segundos, luego vuelva a configurarlo en la función predeterminada.

Proporcione toda la información que pueda serle útil.


FPGA escribe DMA en la memoria del host, y durante estos períodos de interrupción, el FPGA no puede escribir en la memoria del host, por lo que su respaldo interno FIFO. Hay una interfaz basada en mensajes para el proceso del host (sucede a través de PCIe), pero estoy seguro de que esto no está involucrado. Para fines de validación, básicamente necesito una forma de prohibir que el hardware FPGA escriba en la memoria del host durante unos cientos de milisegundos. No quiero resolver el problema de memoria, pero quiero asegurarme de que nuestra implementación en el FPGA sea capaz de lidiar con una interrupción de la memoria (hasta 1000 ms).
Mark Lakata

Ok, si es el uso de DMA, puede echar un vistazo en: kernel.org/doc/Documentation/DMA-ISA-LPC.txt particularmente en el claim_dma_lock () y dma_disable (). Sin embargo, necesitará saber las direcciones utilizadas por su FPGA.
Adrien M.

1

No estoy seguro si ayuda. Pero si puede escribir un módulo de kernel que llame a la suspendfunción del módulo de kernel de otro dispositivo, eso podría funcionar.

Cada dispositivo PCI se puede suspender de acuerdo con el archivo de encabezado http://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/include/linux/pci.h#L479

Por ejemplo, de aquí Intel E1000 de NIC función suspenden http://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/drivers/net/e1000e/netdev.c#L4643

Por lo que puedo recordar, esta función se usó principalmente cuando el sistema entra en hibernación, el controlador del dispositivo debe guardar el estado de ejecución actual y apagarse.


Gracias, pero no creo que el trabajo voluntad. Realmente no quiero suspender un dispositivo, que es el núcleo que le dice al dispositivo que se prepare para la hibernación; Quiero que el kernel ignore el dispositivo específico (en este caso, la placa secundaria FPGA) sin que lo sepa (aparte de largas latencias o tiempos de espera), o quiero detener todas las transferencias de memoria SDRAM.
Marcos Lakata

0

Creo que usted está pensando a lo largo de las líneas equivocadas. Su objetivo es claro.

El camino no es detener el resto de los procesos, sino darle a sus procesos principales una prioridad de planificación en tiempo real. Utilice agradable para sus importantes del espacio de usuario-procesos para eso.

El problema más difícil es el PCIe manejo de interrupciones, que reside en espacio de núcleo.

Dado que el hardware está implicado, debe empezar a tomar un vistazo más de cerca el carril PCIe involucrados en la placa base y la forma en que está posiblemente conectada a una toma específica de la CPU.

Irqbalance normalmente hace un buen trabajo aquí, pero puede configurar su comportamiento para satisfacer sus necesidades.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.