2012-03-27 6 views
10

Ho scritto un driver linux che ioremaps esporta PCI BAR0 per un particolare dispositivo in un attributo binario sysfs permettendo allo userspace di controllarlo direttamente.Come impedire a MMAP di memorizzare i valori nella cache?

Il problema si verifica quando provo a MMAP sopra l'attributo per accedere direttamente a quel bit di memoria (da un programma userland). Le letture hanno esito positivo e restituiscono i valori previsti, anche se quando scrivo in quella memoria sembra essere memorizzato nella cache da qualche parte tra il kernel e la memoria e non viene consegnato al complesso root GMCH (e quindi al dispositivo). Quello che mi piacerebbe fare è avere una barriera implicita della memoria di scrittura dopo ogni accesso.

  • C'è un modo per evitare che il kernel da caching scrive per un po 'mmap-ed di memoria?

follow up:

  • chiama msync() dopo ogni accesso al "accettato" modo di fare questo?
+1

Per rispondere al follow-up ... non è necessario 'msync() 'qui perché non c'è alcun file che supporta il mmap. Ciò di cui potresti aver bisogno sono alcune istruzioni specifiche per l'architettura per varie cose ... per esempio per garantire l'ordine corretto degli accessi hardware su powerpc potresti aver bisogno di [eieio] (https://www-01.ibm.com/support/knowledgecenter /ssw_aix_61/com.ibm.aix.alangref/idalangref_eieio_instrs.htm) istruzione (qualcuno ha il senso dell'umorismo :-) ... stesso commento fatto [qui] (https://unix.stackexchange.com/questions/237783/ Accedendo-memory-mappato-io-è-lenta). –

risposta

19

Andando avanti, rispondo a questo con la mia soluzione.

Nel driver Kernel della mia funzione sysfs mmap, c'è una macro in /include/asm/pgtable.h che imposta i flag appropriati per una rimappatura pfn di nocache'd. Ecco come si presenta:

vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 
if (io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, 
       vma->vm_end - vma->vm_start, 
       vma->vm_page_prot)) 
    return -EAGAIN; 

Inoltre, nel mmap userland, ho usato la bandiera MAP_SHARED nell'argomento bandiere mmap.

La combinazione dei due ha fatto il trucco.

+0

Grazie mille! Ho avuto esattamente lo stesso problema di te e non ho trovato una soluzione ... – Julien

+1

+1 Ho lavorato anche per me. Grazie per aver dedicato del tempo per pubblicare la soluzione qui una volta che l'hai trovata. :-) – TheCodeArtist

+0

grazie fratello, questo era esattamente quello che stavo cercando! – Luca

0

Possibile aiuto ioremap_nocache()?

+0

Sto usando io_remap_pfn_range per rimappare e tradurre le pagine del kernel negli indirizzi dello spazio utente. Ho cercato (e sto usando) ioremap_nocache() altrove e questo imposta manualmente l'attributo KERNEL_NOCACHE su ogni pagina manualmente. Non riesco a trovare alcuna menzione di ciò che sta accadendo (o un flag da impostare) usando io_remap_pfn_range. –

+1

Additional: ioremap_nocache() è usato praticamente solo per mappare la memoria IO nello spazio del kernel e non giù nello userspace - ecco perché io_remap_pfn_range è a portata di mano. –