Estoy intentando escribir un controlador con la función personalizada mmap()
para la barra PCIe, con el objetivo de hacer que esta BAR sea almacenable en el caché del procesador. Soy consciente de que esta no es la mejor manera de lograr el mayor ancho de banda y que el orden de las escrituras es impredecible (como tampoco lo son los problemas en este caso).cómo hacer mmap para almacenar en caché la barra PCIe
Esto es similar a lo que se describe en How would one prevent MMAP from caching values?
El procesador es de arena i7 Puente, dispositivo PCIe es Altera Stratix IV dev. tablero.
Primero, traté de hacerlo en CentOS 5 (2.6.18). Cambié las configuraciones de MTRR para asegurarme de que la BAR no esté dentro de un MTRR que no se puede descartar y que usó io_remap_pfn_range()
con _PAGE_PCD
y _PAGE_PWT
bits borrados. Read trabajó como se esperaba: lee los valores correctos devueltos y la segunda lectura para la misma dirección no necesariamente hace que la lectura vaya a PCIe (el contador de lectura se activó en FPGA). Sin embargo, las escrituras causaron que el sistema se congele y luego se reinicie sin ningún mensaje en los registros o en la pantalla.
En segundo lugar, traté de hacerlo en CentOS 6 (2.6.32), que tiene compatibilidad con PAT. El resultado es el mismo: las lecturas funcionan correctamente, las escrituras causan la congelación del sistema y se reinician. Curiosamente, las escrituras en línea de caché completa (AVX/SSE) no temporales/que combinan escritura funcionan como se esperaba, es decir, siempre van a FPGA y FPGA observa las escrituras completas de la línea de caché, lee los valores de retorno correctos después. Sin embargo, las escrituras simples de 64 bits todavía causan el congelamiento/reinicio del sistema.
También intenté ioremap_cache()
y luego iowrite32()
dentro del código del controlador. El resultado es el mismo.
Creo que es un problema de hardware pero agradecería que alguien pueda compartir cualquier idea sobre lo que está pasando.
EDITAR: Pude capturar el mensaje MCE en CentOS 6: Excepción de comprobación de la máquina: 5 Banco 5: be2000000003110a.
También probé el mismo código en Sandy Bridge de 2 sockets (Romley): las lecturas y el comportamiento de escritura no temporal son las mismas, las escrituras simples no causan MCE/crash pero no tienen efecto en el estado del sistema, es decir, la memoria no cambia
Además, probé el mismo código en el antiguo sistema Nehalem de 2 sockets: las escrituras simples también causan MCE, aunque los códigos son diferentes.