2012-06-28 15 views
6

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.

risposta

6

Non sono a conoscenza di alcun hardware x86 che supporti il ​​tipo di memoria WriteBack (WB) per gli indirizzi MMIO e quasi sicuramente si vede un risultato di tale incompatibilità. Ho inviato una discussione su questo argomento sul mio blog all'indirizzo http://blogs.utexas.edu/jdm4372/2013/05/29/ e http://blogs.utexas.edu/jdm4372/2013/05/30/

In questi messaggi, discuto un metodo che funziona su alcuni processori - mappare la gamma MMIO due volte - una volta per memorizzare le operazioni dal processore per l'FPGA usando il tipo di memoria Write-Combining (WC) e una volta per le letture dal processore all'FPGA usando i tipi Write Protect (WP) o Write Through (WT). Sarà necessario mantenere la coerenza manualmente utilizzando CLFLUSH sulle linee della cache nella regione "sola lettura" quando si scrive sull'alias di quella linea nella regione "solo scrittura". Sarà inoltre necessario mantenere la coerenza manualmente rispetto alle modifiche dei valori nella memoria FPGA, poiché i dispositivi IO non possono generare transazioni di invalidamento della cache per gli indirizzi MMIO.

La mia squadra ha fatto questo alcuni anni fa quando ero a AMD, e sto cercando ora di capire come farlo con i nuovi kernel di Linux e con i processori Intel. Linux non supporta direttamente i tipi di memoria WP o WT con le sue funzioni di mappatura predefinite, quindi è richiesto un po 'di hacking ....È abbastanza semplice sovrascrivere l'MTRR per una regione, ma sto riscontrando più problemi nel trovare il posto giusto nei discendenti della funzione remap_pfn_range() che devo modificare per ottenere l'attributo WP o WT impostato in le voci PAT per l'intervallo.

Questo metodo è probabilmente più adatto per FPGA rispetto ad altri tipi (predefiniti) di IO Device, poiché la programmabilità dell'FPGA consente la flessibilità di definire le BAR PCI per operare in questa modalità a doppio mappaggio e di cooperare con il driver lato processore nel mantenimento della coerenza della cache.

Problemi correlati