Ho un dispositivo PCIe con un driver dello spazio utente. Sto scrivendo comandi al dispositivo tramite una BAR, i comandi sono sensibili alla latenza e la quantità di dati è piccola (~ 64-byte), quindi non voglio usare DMA.Abilitazione dell'accesso IO combina scrittura nello spazio utente
Se rimappare l'indirizzo fisico della BAR nel kernel utilizzando ioremap_wc
e poi scrivere 64-byte al bar all'interno del kernel, posso vedere che i 64-byte vengono scritti come un unico TLP su PCIe. Se permetto al mio programma userspace di mmap
l'area con il flag MAP_SHARED
e poi scrivo 64-byte, vedo più TPL sul bus PCIe, piuttosto che una singola transazione.
Secondo il kernel PAT documentation dovrei essere in grado di esportare le pagine di scrittura-unito fino alla userspace:
driver che vogliono esportare alcune pagine allo userspace farlo utilizzando l'interfaccia mmap e una combinazione di
1)
pgprot_noncached()
2)
io_remap_pfn_range()
oremap_pfn_range()
ovm_insert_pfn()
Con il supporto PAT, è stata aggiunta una nuova API
pgprot_writecombine
. Così, piloti possono continuare a utilizzare la sequenza di cui sopra, sia conpgprot_noncached()
opgprot_writecombine()
al punto 1, seguito da passo 2.
Sulla base di questa documentazione, il codice del kernel rilevanti dal mio gestore mmap assomiglia a questo :
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
return io_remap_pfn_range(vma,
vma->vm_start,
info->mem[vma->vm_pgoff].addr >> PAGE_SHIFT,
vma->vm_end - vma->vm_start,
vma->vm_page_prot);
il dispositivo PCIe presenta in lspci con le barre contrassegnati come prefetchable come previsto:
Latency: 0, Cache Line Size: 64 bytes Interrupt: pin A routed to IRQ 11 Region 0: Memory at d8000000 (64-bit, prefetchable) [size=32M] Region 2: Memory at d4000000 (64-bit, prefetchable) [size=64M]
Quando chiamo mmap
da userspace vedo un messaggio di log (dopo aver impostato debugpat parametro di avvio del kernel):
reserve_memtype aggiunto [mem 0xd4000000-0xd7ffffff], pista write-combining, req write-combining , ret scrittura che unisce
posso anche vedere in /sys/kernel/debug/x86/pat_memtype_list
che una voce di PAT è corretto e non ci sono regioni che si sovrappongono:
write-combining @ 0xd4000000-0xd8000000
uncached-minus @ 0xd8000000-0xda000000
Ho anche verificato che non ci siano voci MTRR in conflitto con la configurazione PAT. Per quanto posso vedere, tutto è impostato correttamente affinché la combinazione di scrittura avvenga nello userspace, tuttavia utilizzando un analizzatore PCIe per osservare le transazioni sul bus PCIe, lo schema di accesso allo spazio utente è completamente diverso dalla stessa scrittura eseguita dal kernel dopo una chiamata ioremap_wc
.
Perché la combinazione di scrittura non funziona come previsto dallo spazio utente?
Cosa posso fare per eseguire il debug ulteriormente?
Attualmente sono in esecuzione su un singolo socket 6-core i7-3930K.
Qual è l'indirizzo visibile userspace per la gamma? Forse non è allineato correttamente? – wallyk
@wallyk Buon suggerimento ma l'indirizzo visibile dello spazio utente sembra allineato. – Chiggs