Ich habe ein PCIe-Gerät mit einem Userspace-Treiber. Ich schreibe Befehle über eine BAR an das Gerät, die Befehle sind latenzempfindlich und die Datenmenge ist klein (~ 64 Bytes), daher möchte ich DMA nicht verwenden.Aktivieren Schreib-Kombinieren IO-Zugriff in Benutzerbereich
Wenn ich die physikalische Adresse des BAR im Kernel unter Verwendung ioremap_wc
und dann schreibe 64-Bytes an die BAR innerhalb des Kernels neu zuordnen, kann ich sehen, daß das 64-Bytes als eine einzige TLP über PCIe geschrieben werden. Wenn ich mein Userspace-Programm auf mmap
die Region mit dem MAP_SHARED
-Flag und dann 64-Byte schreibe, sehe ich mehrere TPLs auf dem PCIe-Bus statt einer einzelnen Transaktion.
Nach dem Kernel PAT documentation Ich sollte Zuschreibung kombinierenden Seiten bis hin zu User-Space exportieren können: einige Seiten wollen
Treiber exportieren, um den Userspace tun durch mmap -Schnittstelle und eine Kombination aus
1)
pgprot_noncached()
2)
io_remap_pfn_range()
oderremap_pfn_range()
odervm_insert_pfn()
Mit PAT-Unterstützung wird eine neue API
pgprot_writecombine
hinzugefügt. So können Treiber weiterhin die obige Sequenz verwenden, mit beidenpgprot_noncached()
oderpgprot_writecombine()
in Schritt 1, gefolgt von Schritt 2.
Auf der Grundlage dieser Dokumentation, die entsprechenden Kernel-Code von meinem mmap-Handler wie folgt aussieht :
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);
Mein PCIe-Gerät zeigt in lspci up mit den Stäben als prefetchable wie erwartet markiert:
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]
Als ich mmap
von Anwenderseite aufrufen sehe ich eine Log-Meldung (debugpat Kernel-Boot-Parameter eingestellt haben):
reserve_memtype hat [mem 0xd4000000-0xd7ffffff], Track Write-Combining, erf Write-Combining aD write-combining
ich auch in /sys/kernel/debug/x86/pat_memtype_list
, dass ein PAT Eintrag korrekt aussieht und es gibt keine überlappenden Bereiche sehen:
write-combining @ 0xd4000000-0xd8000000
uncached-minus @ 0xd8000000-0xda000000
Ich habe auch überprüft, dass es keine MTRR-Einträge gibt, die mit der PAT-Konfiguration in Konflikt kämen. Soweit ich sehen kann, ist alles korrekt eingerichtet, damit das Write-Combining im Userspace abläuft. Unter Verwendung eines PCIe-Analyzers zur Beobachtung der Transaktionen auf dem PCIe-Bus unterscheidet sich das Userspace-Zugriffsmuster jedoch vollständig vom gleichen vom Kernel ausgeführten Schreiben nach einem ioremap_wc
Anruf.
Warum funktioniert Write-Combining nicht wie erwartet vom Benutzerbereich?
Was kann ich tun, um weiter zu debuggen?
Ich bin derzeit auf einem einzigen Sockel 6-Core i7-3930K läuft.
Was die User-Space für den Bereich sichtbaren Adresse ist? Vielleicht ist es nicht richtig ausgerichtet? – wallyk
@wallyk Guter Vorschlag, aber die sichtbare Adresse des Userspace sieht aus, als wäre sie ausgerichtet. – Chiggs