あっきぃ日誌

鉄道ブログのような技術系ブログのようななにか

Raspberry Pi Compute Module 4でPCI Expressデバイスを動かす(10GbE NIC編)

Raspberry Pi Advent Calendar 2020の16日目です。

adventar.org

15日目はtakiponeさんのRaspberry Pi Zero 2台とB+をUSBで繋いでLinuxルーター検証環境でした。私が7日にL2スイッチを作っていたので、これでL3もカバーされましたね!

さて今日はついに!CM4で10GbE NICです。

試すNIC

今回試すのは、自前の10GbEカード「SolarFlare SFN5122F」と会社から借りてきた「Intel X520DA-2」の2枚。結果から言うとSolarFlareのNICが使えて、メジャーなはずのX520は一瞬しかリンクアップせず使えない結果となりました。

(追記)X520は自宅の10GbEスイッチとの相性でリンクしないだけで、動作しました。

カーネルコンパイル

コンパイル作業は例によってCM4ではなくPi4 8GBRAMモデルを使用し、ストレージもUSB SSDUSB3.0接続して爆速でコンパイルしていきます。クロスコンパイル……知らない子ですね。あと、カーネルコンパイル環境の用意の方法はGbE編で紹介済みです。

Raspberry Pi Compute Module 4でPCI Expressデバイスを動かす(GbE NIC編) - あっきぃ日誌

今回は、Raspberry Piカーネルコンパイルのドキュメントに従って、CONFIG_LOCALVERSIONを付け足すようにしました。これとkernel7l.imgのバックアップをやっておけば、なんかミスっても切り戻し可能です。

Kernel building - Raspberry Pi Documentation

pi@usbpi:~/linux $ vi .config

# -pcitestを足した
CONFIG_LOCALVERSION="-v7l-pcitest"

SolarFlareのカーネルオプション

make menuconfigで入ったら、「Device Drivers」→「Network device support」→「Ethernet driver support」 の順に辿り、IntelとSolarFlareのオプションを有効にします。

<M>     Intel(R) 10GbE PCI Express adapters support              
[*]       Intel(R) 10GbE PCI Express adapters HWMON support (NEW)

[*]   Solarflare devices  
<M>     Solarflare SFC9000/SFC9100/EF100-family support               
[*]       Solarflare SFC9000/SFC9100-family MTD support (NEW)         
[*]       Solarflare SFC9000/SFC9100-family hwmon support (NEW)       
[*]       Solarflare SFC9000/SFC9100-family MCDI logging support (NEW)
<M>     Solarflare SFC4000 support                                    
[*]       Solarflare SFC4000 MTD support (NEW)  

あとは保存してコンパイルします。所要時間は1時間くらいでした。

pi@usbpi:~/linux $ make modules_prepare
(必要に応じてscreenなどを張って)
pi@usbpi:~/linux $ make -j 4

コンパイルできたら、成果物をインストールしていきます。モジュールはmakeコマンドで、カーネルイメージとDeviceTree周りはバックアップしつつコピーします。

# モジュール
pi@usbpi:~/linux $ sudo make modules_install

# カーネルイメージ。バックアップは2回目以降は適宜工夫を
pi@usbpi:~/linux $ sudo cp /boot/kernel7l.img /boot/kernel7l.img.bak
pi@usbpi:~/linux $ sudo cp arch/arm/boot/zImage /boot/kernel7l.img

# DeviceTree
pi@usbpi:~/linux $ sudo mv -a /boot/overlays /boot/overlays.bak
pi@usbpi:~/linux $ sudo mkdir /boot/overlays
pi@usbpi:~/linux $ sudo cp arch/arm/boot/dts/overlays/*.dtb* /boot/overlays/
pi@usbpi:~/linux $ sudo cp arch/arm/boot/dts/overlays/README /boot/overlays/

ここまでできたら一旦再起動します。

Solar Flareの10GbE NICを動かす!

ではいよいよ10GbE NICを動かします。一式をつなぎ込んで電源ON!!

f:id:Akkiesoft:20201216123612j:plain

lspci、lsmod、ethtoolの情報は異常なしです。

pi@usbpi:~ $ lspci
00:00.0 PCI bridge: Broadcom Limited Device 2711 (rev 20)
01:00.0 Ethernet controller: Solarflare Communications SFC9020 [Solarstorm]
01:00.1 Ethernet controller: Solarflare Communications SFC9020 [Solarstorm]

pi@usbpi:~ $ lsmod | grep sfc
sfc                   286720  0
mdio                   16384  1 sfc
mtd                    69632  8 ofpart,sfc

pi@usbpi:~ $ ethtool -i eth1
driver: sfc
version: 5.10.0-rc7-v7l-sfc1+
firmware-version: 3.3.2.1000
expansion-rom-version: 
bus-info: 0000:01:00.0
supports-statistics: yes
supports-test: yes
supports-eeprom-access: no
supports-register-dump: yes
supports-priv-flags: no

IPアドレスが取得できているか確認します。以前はカーネルコンパイル周りの経験値が足りず、DHCPのアドレス取得に失敗したり、取得できていてもうまく疎通できなかったりしましたが、今回は成功しています。きたー!

3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0f:53:**:**:** brd ff:ff:ff:ff:ff:ff
    inet 192.168.29.141/24 brd 192.168.29.255 scope global dynamic noprefixroute eth1
       valid_lft 14390sec preferred_lft 12590sec
    inet6 (略) scope global dynamic mngtmpaddr noprefixroute 
       valid_lft 14390sec preferred_lft 12590sec
    inet6 (略) scope link 
       valid_lft forever preferred_lft forever
4: eth2: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN group default qlen 1000
    link/ether 00:0f:53:**:**:** brd ff:ff:ff:ff:ff:ff

X520

先に動かないと書いてしまいましたが、X520の方も動作検証をします。認識の具合は普通でした。

pi@usbpi:~ $ lspci
00:00.0 PCI bridge: Broadcom Limited Device 2711 (rev 20)
01:00.0 Ethernet controller: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01)
01:00.1 Ethernet controller: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01)

pi@usbpi:~ $ lsmod | grep ixgbe
ixgbe                 266240  0

pi@usbpi:~ $ ethtool -i eth1
driver: ixgbe
version: 5.10.0-rc7-v7l-pcitest+
firmware-version: 0x000161ae
expansion-rom-version: 
bus-info: 0000:01:00.0
supports-statistics: yes
supports-test: yes
supports-eeprom-access: yes
supports-register-dump: yes
supports-priv-flags: yes

ケーブルは繋いでいますが、リンクダウンしています。

pi@usbpi:~ $ ip a
3: eth1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN group default qlen 1000
    link/ether 90:e2:ba:**:**:** brd ff:ff:ff:ff:ff:ff
4: eth2: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN group default qlen 1000
    link/ether 90:e2:ba:**:**:** brd ff:ff:ff:ff:ff:ff

dmesgでケーブルをさしこんだときのログを見ると、すぐにリンクダウンしている様子が確認できました。カードを見ると、LINKとACTのランプが高速で点滅していて、動作が怪しいです。まあ、動作NGと見るのが妥当でしょう。

[  176.263616] ixgbe 0000:01:00.0 eth1: detected SFP+: 3
[  176.421193] ixgbe 0000:01:00.0 eth1: NIC Link is Up 10 Gbps, Flow Control: RX/TX
[  176.421490] IPv6: ADDRCONF(NETDEV_CHANGE): eth1: link becomes ready
[  177.422576] ixgbe 0000:01:00.0 eth1: NIC Link is Down

ちなみに、DellのSFP+モジュールを差し込んだらunsupportedと怒られました。

[  564.014629] ixgbe 0000:01:00.0: failed to initialize because an unsupported SFP+ module type was detected.
[  564.014650] ixgbe 0000:01:00.0: Reload the driver after installing a supported module.

このX520カードもDell OEMっぽいシールがはられているんですが……。そう、一点気になるとすれば、そのあたりのOEMによるファームウェアの違いとかがあります。とにかくCM4でこのX520カードはダメでした。いちおう会社に純正のもあるんですが使用中なので、空いたらリトライしたいところです。

追記

Twitterでコメントを もらいました。うちのQNAPのハブQSW-308-1CにはX520と相性問題があるそう。マジか

というわけでつなぎ先をスイッチからラックサーバー×SolarFlareに変えてテストしようとしたら、このタイミングでラックサーバーが死亡こっちはこっちで相性問題が発生して起動せず……。自宅サーバーで稼働中のSolarFlareに差し込んで無事リンクまで確認できました。

iperf3でベンチマーク

X520は動かなかったのでラックサーバーに入ってもらって、これとCM4のSolarFlareとでiperf3で測定します。どちらの10GbENICも直結してIPアドレスを固定した上で測定しました。長ったらしいですが、全部の出力を貼ります。ところでラックサーバーではX520は動きましたね。また、ラックサーバー側はUbuntu Server 20.04です。

f:id:Akkiesoft:20201216202758j:plain
(追記)ベンチマークの様子の写真を貼り忘れてたので貼りました

まずはCM4をサーバーにした方の結果。

pi@usbpi:~ $ iperf3 -s
-----------------------------------------------------------
Server listening on 5201
-----------------------------------------------------------
Accepted connection from 192.168.0.1, port 57926
[  5] local 192.168.0.2 port 5201 connected to 192.168.0.1 port 57928
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-1.00   sec   300 MBytes  2.52 Gbits/sec                  
[  5]   1.00-2.00   sec   313 MBytes  2.62 Gbits/sec                  
[  5]   2.00-3.00   sec   313 MBytes  2.62 Gbits/sec                  
[  5]   3.00-4.00   sec   313 MBytes  2.62 Gbits/sec                  
[  5]   4.00-5.00   sec   313 MBytes  2.63 Gbits/sec                  
[  5]   5.00-6.00   sec   313 MBytes  2.63 Gbits/sec                  
[  5]   6.00-7.00   sec   313 MBytes  2.62 Gbits/sec                  
[  5]   7.00-8.00   sec   313 MBytes  2.62 Gbits/sec                  
[  5]   8.00-9.00   sec   313 MBytes  2.63 Gbits/sec                  
[  5]   9.00-10.00  sec   313 MBytes  2.63 Gbits/sec                  
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-10.00  sec  3.04 GBytes  2.61 Gbits/sec                  receiver

---

akkie@rackme:~$ iperf3 -c 192.168.0.2
Connecting to host 192.168.0.2, port 5201
[  5] local 192.168.0.1 port 57928 connected to 192.168.0.2 port 5201
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec   306 MBytes  2.57 Gbits/sec    0    724 KBytes       
[  5]   1.00-2.00   sec   312 MBytes  2.62 Gbits/sec    0    724 KBytes       
[  5]   2.00-3.00   sec   312 MBytes  2.62 Gbits/sec    0    724 KBytes       
[  5]   3.00-4.00   sec   314 MBytes  2.63 Gbits/sec    0    724 KBytes       
[  5]   4.00-5.00   sec   312 MBytes  2.62 Gbits/sec    0    724 KBytes       
[  5]   5.00-6.00   sec   314 MBytes  2.63 Gbits/sec    0    724 KBytes       
[  5]   6.00-7.00   sec   312 MBytes  2.62 Gbits/sec    0    724 KBytes       
[  5]   7.00-8.00   sec   312 MBytes  2.62 Gbits/sec    0    724 KBytes       
[  5]   8.00-9.00   sec   314 MBytes  2.63 Gbits/sec    0    724 KBytes       
[  5]   9.00-10.00  sec   312 MBytes  2.62 Gbits/sec    0    724 KBytes       
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec  3.05 GBytes  2.62 Gbits/sec    0             sender
[  5]   0.00-10.00  sec  3.04 GBytes  2.61 Gbits/sec                  receiver

iperf Done.

次にラックサーバーをサーバーにした方の結果。

akkie@rackme:~$ iperf3 -s
-----------------------------------------------------------
Server listening on 5201
-----------------------------------------------------------
Accepted connection from 192.168.0.2, port 34584
[  5] local 192.168.0.1 port 5201 connected to 192.168.0.2 port 34586
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-1.00   sec   304 MBytes  2.55 Gbits/sec                  
[  5]   1.00-2.00   sec   322 MBytes  2.70 Gbits/sec                  
[  5]   2.00-3.00   sec   320 MBytes  2.69 Gbits/sec                  
[  5]   3.00-4.00   sec   322 MBytes  2.70 Gbits/sec                  
[  5]   4.00-5.00   sec   321 MBytes  2.70 Gbits/sec                  
[  5]   5.00-6.00   sec   323 MBytes  2.71 Gbits/sec                  
[  5]   6.00-7.00   sec   317 MBytes  2.66 Gbits/sec                  
[  5]   7.00-8.00   sec   321 MBytes  2.69 Gbits/sec                  
[  5]   8.00-9.00   sec   320 MBytes  2.68 Gbits/sec                  
[  5]   9.00-10.00  sec   320 MBytes  2.69 Gbits/sec                  
[  5]  10.00-10.02  sec  5.97 MBytes  2.76 Gbits/sec                  
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-10.02  sec  3.12 GBytes  2.68 Gbits/sec                  receiver

---

pi@usbpi:~ $ iperf3 -c 192.168.0.1
Connecting to host 192.168.0.1, port 5201
[  5] local 192.168.0.2 port 34586 connected to 192.168.0.1 port 5201
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec   312 MBytes  2.62 Gbits/sec    0   1.27 MBytes       
[  5]   1.00-2.00   sec   322 MBytes  2.71 Gbits/sec    0   1.27 MBytes       
[  5]   2.00-3.00   sec   320 MBytes  2.68 Gbits/sec    0   1.27 MBytes       
[  5]   3.00-4.00   sec   322 MBytes  2.71 Gbits/sec    0   1.27 MBytes       
[  5]   4.00-5.00   sec   321 MBytes  2.69 Gbits/sec    0   1.27 MBytes       
[  5]   5.00-6.00   sec   322 MBytes  2.71 Gbits/sec    0   1.27 MBytes       
[  5]   6.00-7.00   sec   318 MBytes  2.66 Gbits/sec    0   1.27 MBytes       
[  5]   7.00-8.00   sec   321 MBytes  2.69 Gbits/sec    0   1.27 MBytes       
[  5]   8.00-9.00   sec   320 MBytes  2.69 Gbits/sec    9   1.27 MBytes       
[  5]   9.00-10.00  sec   320 MBytes  2.68 Gbits/sec    0   1.27 MBytes       
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec  3.12 GBytes  2.68 Gbits/sec    9             sender
[  5]   0.00-10.02  sec  3.12 GBytes  2.68 Gbits/sec                  receiver

iperf Done.

上記から、大体2.6Gbps、MB単位ではで300MB/sくらい出ることが確認できました。Raspberry Pi4のPCI Expressは2.0 x1規格で理論値は500MB/sくらいのようなので、3/5くらいの性能が出る、ということになります。

また、先日のNVMe SSDの測定結果も270MB/s前後だったことから、なんとなく実測性能は300MB/s前後、と見ることができそうです。

まとめ

Raspberry Pi Compute Module 4で10GbE NICがついに動作させられました。ブログなので動くように手順が整理していますが、手探りしながら動いた瞬間「うおお!!」って叫びました。

測定の結果から、Pi4のUSB3.0ポートに2.5GbE NICでもさしておけば性能的にはOKという見方もできます。ただ、ここにUSB SSDもつないでローカルストレージにすると300MB/sの帯域を奪い合うことになるので、やるならどっちかになりそうな感じです。まあ、SSDですね。

ヤフオクで粘っていればたまに安価にカードが拾えるので、速度よりも男のロマン的に動かしてみるのも良いですね。

さて、このあとはGPUも……と生きたいところですが、こちらはドライバー以前に起動中にカーネルパニックでコケるレベルなので、おそらくブログネタにはできなさそうです。もしかするとCM4のRAMが足りないとか、そっち方面の問題が出てるかなあと想像しているところです。わからないですけどね。ちなみに、x1スロット形状でHDMIが4つ出るGT710カードは使えているという話が財団の中の人から出てるっぽいです。が、そこまでして動かしたいわけでもなく……🤔。

あとは、SolarFlareを動かしている様子の写真に写り込んでいたUSB3.0SATAのコンボカードもあるのですが、これもどうもコンボにするためのスイッチチップが怪しいのかどちらも動作が不安定です。VL805チップなUSB3.0カードはAliExpressでポチポチしたので、届いたらテストしていくつもりですが、これは多分Advent Calendarが終わったあとになりそうです。