NAPI vs Adaptive Interrupts


12

Könnte jemand erklären, wie zwei der folgenden Technologien verwendet werden, um den Interrupt-Overhead bei hoher Netzwerklast zu verringern?

  1. Adaptive-rx / Adaptive-tx und
  2. NAPI;

Ich würde eine Antwort begrüßen, die den Unterschied näher an der Linux-Kernel-Quellenebene erklärt. Ich würde auch gerne hören, wie man die Netzwerkkarte dazu zwingt, den Koaleszenzmodus bei einer Last von ~ 400 Mbit / s abzufragen / zu unterbrechen.

Mehr Hintergrund:

Das Problem scheint zu sein, dass bnx2- und e1000-Treiber den Befehl "ethtool -C adaptive-rx on" ignorieren. Dies liegt wahrscheinlich daran, dass diese Treiber keine adaptiven Interrupts unterstützen. Das Referenzhandbuch des Broadcom-Programmierers besagt jedoch, dass diese Funktion von der BCM5709-NIC-Hardware unterstützt werden sollte.

Daher habe ich mich entschlossen, NAPI zu testen und das Gewicht im Funktionsaufruf netif_napi_add () von 64 auf 16 zu reduzieren, um die Netzwerkkarte im Abrufmodus unter einer viel geringeren Last zu zwingen, aber das hat leider nicht funktioniert. Ich vermute, dass NAPI keine spezielle Hardwareunterstützung in der Netzwerkkarte benötigt. Ist das richtig?

Die Hardware, die ich benutze, ist BCM5709 NIC (es benutzt bnx2 Treiber). Und das Betriebssystem ist Ubuntu 10.04. Die CPU ist XEON 5620.

Antworten:


18

Das Hauptprinzip der Interrupt-Moderation besteht darin, weniger als einen Interrupt pro empfangenem Frame (oder einen Interrupt pro abgeschlossenem Sende-Frame) zu generieren, um den bei der Interrupt-Wartung auftretenden Overhead des Betriebssystems zu verringern. Der BCM5709-Controller unterstützt eine Reihe von Hardwaremethoden zum Zusammenführen von Interrupts, darunter:

  • Erzeugen eines Interrupts nach Empfang von X Frames (RX-Frames in Ethtool)
  • Generiere einen Interrupt, wenn nach X usecs keine Frames mehr empfangen werden (rx-usecs in ethtool)

Das Problem bei der Verwendung dieser Hardwaremethoden besteht darin, dass Sie sie auswählen müssen, um den Durchsatz oder die Latenz zu optimieren. Beides ist nicht möglich. Das Erzeugen eines Interrupts für jeden empfangenen Frame (RX-Frames = 1) minimiert die Latenz, jedoch mit einem hohen Aufwand an Interrupt-Service-Overhead. Wenn Sie einen größeren Wert festlegen (z. B. rx-frames = 10), wird die Anzahl der CPU-Zyklen reduziert, indem nur ein Interrupt für jeweils zehn empfangene Frames generiert wird. Bei den ersten Frames in dieser Zehnergruppe tritt jedoch eine höhere Latenz auf.

Die NAPI-Implementierung versucht, die Tatsache zu nutzen, dass der Datenverkehr in Bündeln eingeht, sodass Sie beim ersten empfangenen Frame sofort einen Interrupt generieren und dann sofort in den Abfragemodus wechseln (dh Interrupts deaktivieren), da mehr Datenverkehr in der Nähe ist. Nachdem Sie eine bestimmte Anzahl von Frames (16 oder 64 in Ihrer Frage) oder ein bestimmtes Zeitintervall abgefragt haben, aktiviert der Treiber die Interrupts erneut und startet erneut.

Wenn Sie eine vorhersehbare Arbeitsauslastung haben, können feste Werte für eine der oben genannten Optionen (NAPI, RX-Frames, RX-Usecs) ausgewählt werden, die Ihnen den richtigen Kompromiss bieten. Hier kommt adaptive-rx / adaptive-tx ins Spiel. Die Idee dabei ist, dass der Treiber die Arbeitslast (empfangene Frames pro Sekunde, Framegröße usw.) ständig überwacht und das Hardware-Interrupt-Koaleszenzschema optimiert, um die Latenz in Situationen mit geringem Verkehr oder den Durchsatz in Situationen mit hohem Verkehr zu optimieren. Es ist eine coole Theorie, aber möglicherweise schwierig in die Praxis umzusetzen. Nur wenige Treiber implementieren es (siehe http://fxr.watson.org/fxr/search?v=linux-2.6&string=use_adaptive_rx_coalesce ) und die bnx2 / e1000-Treiber sind nicht in dieser Liste enthalten.

In den Definitionen für die ethtool_coalesce-Struktur finden Sie eine gute Beschreibung der Funktionsweise der einzelnen ethtool-Koaleszenzfelder unter der folgenden Adresse:

http://fxr.watson.org/fxr/source/include/linux/ethtool.h?v=linux-2.6#L111

Für Ihre spezielle Situation (~ 400Mb / s Durchsatz) würde ich vorschlagen, die RX-Frames und die RX-Usecs-Werte für die besten Einstellungen für Ihre Workload zu optimieren. Betrachten Sie sowohl den Overhead des ISR als auch die Empfindlichkeit Ihrer Anwendung (httpd? Usw.) gegenüber Latenz.

Dave


1
Sie sagten: "Die NAPI-Implementierung versucht, die Tatsache zu nutzen, dass der Datenverkehr in Bündeln eingeht , sodass Sie beim ersten empfangenen Frame sofort einen Interrupt generieren und dann sofort in den Abfragemodus wechseln. " Aber in dem Wiki gesagt , dass NAPI nicht Hardware - Interrupts nicht verwendet, nie, aber Umfragen jeder bestimmten Zeitraum : en.wikipedia.org/wiki/New_API Genaue Zitat: „Der Kernel kann in regelmäßigen Abständen überprüfen für die Ankunft des eingehenden Netzwerkpakete ohne unterbrochen werden , wodurch der Overhead der Interrupt-Verarbeitung entfällt. " Wo ist die wahrheit
Alex

1
@Alex Hardware-Interrupts müssen verwendet werden, um den Kernel über den zu empfangenden Datenverkehr zu informieren. Ein Interrupt-Handler "alten Stils" plant den Paketempfang und gibt dann die Interrupts wieder frei. Ein NAPI-Interrupt-Handler deaktiviert Interrupts, plant einen Poller und aktiviert Interrupts erneut. Der Poller führt den Paketempfang für eine bestimmte Anzahl von Paketen aus. Solange noch Datenverkehr für den Dienst vorhanden ist, wird der Poller weiter ausgeführt. Ziel ist es, harte Interrupts zu verhindern, indem der Datenverkehr immer von der Netzwerkkarte abgerufen wird. Wenn der Verkehr nachlässt, wird der Poller beendet und das System wartet wieder auf eine Unterbrechung.
Suprjami
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.