Neuverhandlung der PCIe-Geschwindigkeit unter Linux erzwingen

Neuverhandlung der PCIe-Geschwindigkeit unter Linux erzwingen

Ich arbeite mit PCIe Gen 3-Karten und von Zeit zu Zeit scheinen sie auf PCIe 1- oder 2-Geschwindigkeiten zurückzufallen (laut lspci und auch am Durchsatz beobachtet).

Beim Neustart/Aus- und Wiedereinschalten des Computers wird die Geschwindigkeit in den meisten Fällen auf die volle PCIe Gen 3-Geschwindigkeit zurückgesetzt.

Gibt es eine weniger aufdringliche Möglichkeit, eine Neuverhandlung der PCI-Verbindungsgeschwindigkeit zu erzwingen (um sie wieder auf PCI Gen 3 zu bringen), beispielsweise bei RHEL6?

Antwort1

Sie können Ihre PCIe-Energierichtlinie in dieser Datei überprüfen:

# cat /sys/module/pcie_aspm/parameters/policy

Da Gen3 bei der Energieverwaltung über ASPM (Active-State Power Management) ziemlich unkompliziert ist, könnte dies die Hauptursache für das Problem auf Ihrem Bus sein: Der Durchsatz ist niedrig, sodass die Module die Geschwindigkeit reduzieren, aber vergessen, sie bei Bedarf wieder zu erhöhen (falls nötig). Sie könnten Grub dazu zwingen, die Verwendung der Richtlinie „Powersave“ oder „Default“ zu vermeiden, indem Sie ASPM mit dem folgenden Parameter deaktivieren:

pcie_aspm=off

Testen Sie dies auf nur einem Kernel, indem Sie diese Option an /boot/grub/grub.confdie Zeile „Kernel“ Ihres Standard-Boot-Linux anhängen. Beispiel einer Grub-Konfiguration aus den Red Hat-Dokumenten:

default=0 
timeout=10 
splashimage=(hd0,0)/grub/splash.xpm.gz 
hiddenmenu 
title Red Hat Enterprise Linux Server (2.6.18-2.el5PAE)         
root (hd0,0)         
kernel /boot/vmlinuz-2.6.18-2.el5PAE ro root=LABEL=/1 rhgb quiet pcie_aspm=off      
initrd /boot/initrd-2.6.18-2.el5PAE.img

Antwort2

PCIe-Geschwindigkeit festlegenhat ein pcie_set_speed.shSkript, mit dem die Zielverbindungsgeschwindigkeit eines Geräts geändert werden kann. Habe dieses Skript erfolgreich unter Alma 8.9 (also RHEL-basiert) mit einem 4.18.0-513.18.1.el8_9.x86_64Kernel verwendet.

Haben Sie ein Xilinx Kintex-7 FPGA in einer PCIe-Karte:

  1. Das FPGA PCIe IP wurde auf einen Betrieb mit PCIe 2-Geschwindigkeit mit 4 Lanes eingestellt.
  2. Die PCIe-Karte befindet sich in einem 16-Lane-Steckplatz mit einer Intel i5-2310-CPU, die PCIe 2-Geschwindigkeit unterstützt.

Es wurde festgestellt, dass die PCIe-Schnittstelle mit PCIe-1-Geschwindigkeit (2,5 GT/s) ausgehandelt wurde:

$ dump_info/dump_info_libpciaccess 
domain=0000 bus=01 dev=00 func=00
  vendor_id=10ee (Xilinx Corporation) device_id=7024 ((null)) subvendor_id=0002 subdevice_id=0009
  control: I/O- Mem+ BusMaster- ParErr- SERR- DisINTx-
  status: INTx- <ParErr- >TAbort- <TAbort- <MAbort- >SERR- DetParErr-
  bar[0] base_addr=f0110000 size=4000 is_IO=0 is_prefetchable=1 is_64=1
  bar[2] base_addr=f0100000 size=10000 is_IO=0 is_prefetchable=1 is_64=1
  Capabilities: [40] Power Management
  Capabilities: [48] Message Signaled Interrupts
  Capabilities: [60] PCI Express v2 Express Endpoint, MSI 0
    Link capabilities: Max speed 5.0 GT/s Max width x4
    Negotiated link status: Current speed 2.5 GT/s Width x4
    Link capabilities2: Not implemented
    DevCtl: CorrErr- NonFatalErr- FatalErr- UnsupReq-
            RlxdOrd- ExtTag+ PhantFunc- AuxPwr- NoSnoop+
    DevSta: CorrErr- NonFatalErr- FatalErr- UnsupReq- AuxPwr- TransPend-
  domain=0000 bus=00 dev=01 func=00
    vendor_id=8086 (Intel Corporation) device_id=0101 (Xeon E3-1200/2nd Generation Core Processor Family PCI Express Root Port) subvendor_id=8086 subdevice_id=2002
    control: I/O+ Mem+ BusMaster+ ParErr- SERR- DisINTx+
    status: INTx- <ParErr- >TAbort- <TAbort- <MAbort- >SERR- DetParErr-
    Capabilities: [88] Bridge subsystem vendor/device ID
    Capabilities: [80] Power Management
    Capabilities: [90] Message Signaled Interrupts
    Capabilities: [a0] PCI Express v2 Root Port, MSI 0
      Link capabilities: Max speed 5.0 GT/s Max width x16
      Negotiated link status: Current speed 2.5 GT/s Width x4
      Link capabilities2: Not implemented
      DevCtl: CorrErr- NonFatalErr- FatalErr- UnsupReq-
              RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
      DevSta: CorrErr+ NonFatalErr- FatalErr- UnsupReq- AuxPwr- TransPend-
      SltCap: AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug- Surprise-
             Slot #0 PowerLimit 0.000W; Interlock- NoCompl+

Die obige Ausgabe stammt von derdump_info_libpciaccess.cProgramm. Es beginnt bei einem bestimmten PCI-Gerät und arbeitet sich die PCI-Topologie hinunter bis zum Root-Complex. Oben wird sowohl die Unterstützung des PCIe-Geräts als auch des Root-Complexes gezeigt 5.0 GT/s, aber wir liefen bei 2.5 GT/s.

Als das pcie_set_speed.shvon Alex Forencich geschriebene Skript ausgeführt wurde, meldete es, dass die Verbindungsgeschwindigkeit von 1 auf 2 geändert wurde. Das einzige verwendete Argument war das zu verwendende PCI-Gerät, sodass das PCIe-Gerät versucht, seine schnellste unterstützte Verbindungsgeschwindigkeit auszuhandeln:

$ sudo ~/Downloads/pcie_set_speed.sh 0000:01:00.0
Link capabilities: 02212d02
Max link speed: 2
Link status: 5041
Current link speed: 1
Configuring 0000:00:01.0...
Original link control 2: 00000002
Original link target speed: 2
New target link speed: 2
New link control 2: 00000002
Triggering link retraining...
Original link control: 50410040
New link control: 50410060
Link status: 5042
Current link speed: 2

Und das dump_info_libpciaccessProgramm meldete dann, dass das PCIe-Gerät und der Root-Komplex Folgendes ausgehandelt hatten 5 GT/s:

$ dump_info/dump_info_libpciaccess 
domain=0000 bus=01 dev=00 func=00
  vendor_id=10ee (Xilinx Corporation) device_id=7024 ((null)) subvendor_id=0002 subdevice_id=0009
  control: I/O- Mem+ BusMaster+ ParErr- SERR- DisINTx-
  status: INTx- <ParErr- >TAbort- <TAbort- <MAbort- >SERR- DetParErr-
  bar[0] base_addr=f0110000 size=4000 is_IO=0 is_prefetchable=1 is_64=1
  bar[2] base_addr=f0100000 size=10000 is_IO=0 is_prefetchable=1 is_64=1
  Capabilities: [40] Power Management
  Capabilities: [48] Message Signaled Interrupts
  Capabilities: [60] PCI Express v2 Express Endpoint, MSI 0
    Link capabilities: Max speed 5.0 GT/s Max width x4
    Negotiated link status: Current speed 5.0 GT/s Width x4
    Link capabilities2: Not implemented
    DevCtl: CorrErr- NonFatalErr- FatalErr- UnsupReq-
            RlxdOrd- ExtTag+ PhantFunc- AuxPwr- NoSnoop+
    DevSta: CorrErr+ NonFatalErr- FatalErr- UnsupReq- AuxPwr- TransPend-
  domain=0000 bus=00 dev=01 func=00
    vendor_id=8086 (Intel Corporation) device_id=0101 (Xeon E3-1200/2nd Generation Core Processor Family PCI Express Root Port) subvendor_id=8086 subdevice_id=2002
    control: I/O+ Mem+ BusMaster+ ParErr- SERR- DisINTx+
    status: INTx- <ParErr- >TAbort- <TAbort- <MAbort- >SERR- DetParErr-
    Capabilities: [88] Bridge subsystem vendor/device ID
    Capabilities: [80] Power Management
    Capabilities: [90] Message Signaled Interrupts
    Capabilities: [a0] PCI Express v2 Root Port, MSI 0
      Link capabilities: Max speed 5.0 GT/s Max width x16
      Negotiated link status: Current speed 5.0 GT/s Width x4
      Link capabilities2: Not implemented
      DevCtl: CorrErr- NonFatalErr- FatalErr- UnsupReq-
              RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
      DevSta: CorrErr+ NonFatalErr- FatalErr- UnsupReq- AuxPwr- TransPend-
      SltCap: AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug- Surprise-
             Slot #0 PowerLimit 0.000W; Interlock- NoCompl+

D. h., mithilfe eines Skripts konnte die PCIe-Verbindungsgeschwindigkeit erfolgreich geändert werden, ohne dass ein Neustart erforderlich war.

Auch dertest_dma_bridge_parallel_streams.cDas Programm, das zur Messung des DMA-Durchsatzes des FPGA-basierten PCIe-Geräts geschrieben wurde, zeigte eine Steigerung des Durchsatzes. Das Programm meldet den in den letzten 10 Sekunden erreichten Durchsatz. Zu Beginn des folgenden Beispiels hatte das PCIe-Gerät eine Geschwindigkeit von 2,5 GT/s. Das pcie_set_speed.shSkript änderte die Verbindungsgeschwindigkeit des PCIe-Geräts während des Tests, und der gemessene Durchsatz stieg:

  0000:01:00.0 0 -> 1 381.186 Mbytes/sec (3811835904 bytes in 9.999928 secs)
  0000:01:00.0 1 -> 0 381.186 Mbytes/sec (3811835904 bytes in 9.999928 secs)

  0000:01:00.0 0 -> 1 381.193 Mbytes/sec (3811966976 bytes in 10.000095 secs)
  0000:01:00.0 1 -> 0 381.193 Mbytes/sec (3811966976 bytes in 10.000095 secs)

  0000:01:00.0 0 -> 1 680.225 Mbytes/sec (6802243584 bytes in 9.999985 secs)
  0000:01:00.0 1 -> 0 680.226 Mbytes/sec (6802243584 bytes in 9.999983 secs)

  0000:01:00.0 0 -> 1 737.226 Mbytes/sec (7372210176 bytes in 9.999935 secs)
  0000:01:00.0 1 -> 0 737.219 Mbytes/sec (7372210176 bytes in 10.000023 secs)

  0000:01:00.0 0 -> 1 737.226 Mbytes/sec (7372275712 bytes in 10.000028 secs)
  0000:01:00.0 1 -> 0 737.226 Mbytes/sec (7372275712 bytes in 10.000027 secs)

Für das obige Beispiel wurde ein PC verwendet, der Secure Boot nicht unterstützt. Eine Einschränkung des pcie_set_speed.shSkripts ist, dass es setpcidie Verbindungsgeschwindigkeit ändert. Wenn Secure Boot aktiviert ist, wird der Linux-KernelSperrungverhindert dann setpcidie Durchführung von Schreibvorgängen in PCIe-Konfigurationsregistern, die zum Ändern der Verbindungsgeschwindigkeit erforderlich sind.

verwandte Informationen