Große PCIe DMA Linux x86-64

8

Ich arbeite mit einer seriellen Hochgeschwindigkeits-Karte für Datentransfer von einer externen Quelle zu einer Linux-Box mit einer PCIe-Karte. Die PCIe-Karte kam mit einigen Treibern von Drittanbietern, die dma_alloc_coherent verwenden, um die dma-Puffer zuzuweisen, um die Daten zu empfangen. Aufgrund von Linux-Beschränkungen begrenzt dieser Ansatz die Datenübertragung auf 4 MB. Ich habe mehrere Methoden zum Zuweisen eines großen DMA-Puffers gelesen und ausprobiert und war nicht in der Lage, einen zu verwenden.

Dieses System hat 32 GB Arbeitsspeicher und läuft mit Red Hat mit einer Kernel-Version von 3.10, und ich möchte 4 GB davon für eine zusammenhängende DMA verfügbar machen. Ich weiß, dass die bevorzugte Methode Scatter / Gather ist, aber das ist in meiner Situation nicht möglich, da es einen Hardwarechip gibt, der das serielle Protokoll in ein DMA außerhalb meiner Kontrolle übersetzt, wo das einzige, was ich kontrollieren kann, ein Offset zu dem ist eingehende Adressen (dh die Adresse 0, wie sie vom externen System aus gesehen wird, kann auf die Adresse 0x700000000 auf dem lokalen Bus abgebildet werden).

Da es sich um eine einmalige Labormaschine handelt, wäre der schnellste / einfachste Ansatz die Verwendung des Konfigurationsparameters mem = 28GB. Ich habe das funktioniert gut, aber der nächste Schritt zum Zugriff auf diesen Speicher aus dem virtuellen Raum ist, wo ich Probleme habe. Hier ist mein Code zu den relevanten Komponenten zusammengefasst:

Im Kernel-Modul:

%Vor%

In der Anwendung:

%Vor%

Eine weitere interessante Sache ist, dass bevor Sie all dies tun, die physikalische Adresse, die von dma_alloc_coherent zurückgegeben wird, größer ist als die Menge an RAM auf dem System (0x83d000000). Ich dachte, dass in x86 der RAM immer die niedrigsten Adressen wäre und daher würde ich eine Adresse von weniger als 32GB erwarten.

Jede Hilfe wäre willkommen.

    
LINEMAN78 20.11.2015, 01:28
quelle

1 Antwort

0

Anstatt die Menge des Systemspeichers über mem zu begrenzen, versuchen Sie es mit CMA: Ссылка

Mit dem CMA-Kernel-Befehlszeilenargument können Sie eine bestimmte Speichermenge für DMA-Operationen reservieren, die garantiert zusammenhängend ist. Der Kernel erlaubt Nicht-DMA-Prozessen den Zugriff auf diesen Speicher, aber sobald eine DMA-Operation diesen Speicher benötigt, werden Nicht-DMA-Prozesse entfernt. Daher würde ich empfehlen, den Parameter mem nicht zu ändern, sondern cma=4G zu Ihrer cmdline hinzuzufügen. dma_alloc_coherent sollte automatisch von diesem reservierten Bereich abziehen, aber Sie können das CMA-Debugging in Ihrer Kernel-Konfiguration aktivieren, um sicherzugehen.

    
John Moon 16.11.2017 17:24
quelle

Tags und Links