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.
Wenn ich die physikalische Adresse des BAR im Kernel mit ioremap_wc
neu ordne und dann 64 Bytes in den BAR innerhalb des Kernels schreibe , kann ich sehen, dass die 64 Bytes als geschrieben werden ein einzelnes TLP über PCIe. Wenn ich meinem Userspace-Programm mmap
die Region mit dem MAP_SHARED
-Flag gebe und dann 64-Bytes schreibe, sehe ich mehrere TPLs auf dem PCIe-Bus statt einer einzelnen Transaktion.
Laut Kernel PAT-Dokumentation sollte ich Schreib-kombinierte Seiten durch exportieren können zu Benutzerbereich:
Treiber, die einige Seiten in den Benutzerbereich exportieren möchten, tun dies mit mmap Schnittstelle und eine Kombination von
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. Damit, Treiber können weiterhin die obige Sequenz verwendenpgprot_noncached()
oderpgprot_writecombine()
in Schritt 1, gefolgt von Schritt 2.
Basierend auf dieser Dokumentation sieht der relevante Kernel-Code aus meinem mmap-Handler wie folgt aus:
%Vor%Mein PCIe-Gerät wird in lspci angezeigt, wobei die BARs wie erwartet vorausberechnet sind:
%Vor%
Wenn ich mmap
vom Benutzerbereich aus anrufe, sehe ich eine Protokollnachricht (mit gesetztem debugpat kernel boot-Parameter):
reserve_memptype hinzugefügt [mem 0xd4000000-0xd7ffffff], track schreiben-kombinieren, req schreiben-kombinieren, ret schreiben-kombinieren
Ich kann auch in /sys/kernel/debug/x86/pat_memtype_list
sehen, dass ein PAT-Eintrag korrekt aussieht und keine überlappenden Bereiche vorhanden sind:
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
Aufruf.
Warum funktioniert Write-Combining nicht wie erwartet vom Benutzerbereich?
Was kann ich tun, um weiter zu debuggen?
Ich laufe derzeit auf einem einzelnen Sockel 6-Core i7-3930K.
Ich weiß nicht, ob das helfen wird, aber so habe ich Schreibkombinations-Arbeiten an PCIe bekommen. Zugegeben, es war im Kernel-Bereich, aber das entspricht der Intel-Dokumentation. Es ist einen Versuch wert, wenn Sie stecken bleiben.
Global definiert:
%Vor%In Ihrer Funktion:
%Vor%Tags und Links c linux linux-device-driver linux-kernel pci-e