Sto cercando di scrivere un driver con la funzione personalizzata mmap()
per PCIe BAR, con l'obiettivo di rendere questa BAR memorizzabile nella cache del processore. Sono consapevole che questo non è il modo migliore per ottenere la massima larghezza di banda e che l'ordine delle scritture è imprevedibile (né i problemi sono in questo caso).come eseguire mmap per la cache PCIe memorizzabile nella cache
Questo è simile a quanto descritto in How would one prevent MMAP from caching values?
Il processore è Sandy Bridge i7, dispositivo PCIe è Altera Stratix IV dev. tavola.
In primo luogo, ho provato a farlo su CentOS 5 (2.6.18). Ho modificato le impostazioni MTRR per accertarmi che la BAR non sia all'interno di MTRR non memorizzabili e che utilizzasse io_remap_pfn_range()
con _PAGE_PCD
e _PAGE_PWT
bit cancellati. Le letture hanno funzionato come previsto: la lettura dei valori corretti restituiti e la seconda lettura sullo stesso indirizzo non obbligano necessariamente la lettura a passare a PCIe (il contatore di lettura è stato controllato in FPGA). Tuttavia, le scritture hanno causato il blocco del sistema e il riavvio senza messaggi nei registri o sullo schermo.
In secondo luogo, ho provato a farlo su CentOS 6 (2.6.32), che ha il supporto PAT. Il risultato è lo stesso: legge il lavoro correttamente, scrive causa il blocco del sistema e il riavvio. È interessante notare che le scritture di riga cache complete (non-temporali/in scrittura) (AVX/SSE) funzionano come previsto, vale a dire che vanno sempre in FPGA e FPGA osserva le scritture di riga cache complete, legge valori di ritorno corretti in seguito. Tuttavia, le semplici scritture a 64 bit causano ancora il blocco/riavvio del sistema.
Ho anche provato a ioremap_cache()
e quindi iowrite32()
all'interno del codice del driver. Il risultato è lo stesso.
Penso che sia un problema hardware, ma sarei grato se qualcuno possa condividere idee su cosa sta succedendo.
MODIFICA: Sono riuscito a catturare il messaggio MCE su CentOS 6: Eccezione controllo macchina: 5 Banco 5: be2000000003110a.
Ho anche provato lo stesso codice su Sandy Bridge a 2 socket (Romley): le letture e il comportamento di scrittura non temporaneo sono gli stessi, le scritture semplici non causano MCE/crash ma non hanno alcun effetto sullo stato del sistema, cioè valore in la memoria non cambia.
Inoltre, ho provato lo stesso codice sul sistema Nehalem a 2 socket più vecchio: anche le scritture semplici causano MCE, anche se i codici sono diversi.