NVIDIA MellanoxのNICである
SmartNICで使えるInboxドライバーとOFEDドライバー
2019年にNVIDIAに買収されたMellanoxは、HPC
「SmartNIC」
さて、一口にSmartNICと言ってもいくつかの種類が存在します。
- ASICベースのSmartNIC
- SoCベースのSmartNIC
- FPGAベースのSmartNIC
ASICベースのSmartNICは、いわゆる昔ながらの
それに対して、SoCベースとFPGAベースはNICの上にCPUやFPGAが搭載されています。SoCベースだとArmが採用されていることが多く、SoCの上でLinuxが動きますので自由にフレームを操作できるのです。SoCベースでは、たとえばNVIDIAのBlueFieldなどが代表的です。FPGAベースはその名の通りFPGAが搭載されているため、並列処理が支配的で用途に応じて処理が異なるようなケースで効果を発揮します。
そんなSmartNICですが、用途を考えるとどうしても値段は高くなってしまいます。普通のご家庭ではまず買うことはありません。それはConnectXも同じで、最新世代については仕事か全力の趣味でない限り買えない
前述した通り、ConnectXはASICベースのSmartNICであり、EthernetタイプのアダプターについてはUbuntuカーネルに組み込まれたドライバーでそのまま動きます。Mellanox時代の文化なのか、ConnectXについてはNVIDIAのGPUと異なりカーネルドライバーもユーザーランドツールもそのほとんどがFLOSSライセンスで提供されています。つまりUbuntuマシンにPCIeデバイスとして接続したらそのまま動くことが多いのです。この、Linuxディストリビューション等に組み込まれたドライバーを
それに対してNVIDIA Mellanoxは
しかしながらSmartNICは、ゲームPCにおけるGPUと同じように、可能な限り本来の性能を引き出すことが求められるデバイスです。Inboxドライバーで問題なく使えるとしても、OFEDドライバーに適用された改善策によって少しでも性能があがるなら、それを取り込みたいと思うでしょう。
そこで今回はサーバー版のUbuntu 22.
OFEDドライバーのダウンロードとインストール
さっそくOFEDドライバーをダウンロードし、インストールしましょう。インストール方法についてはNVIDIAのサイトに、リリースごとのインストール方法や変更履歴など一緒にまとまっています。まずはそちらを読むと良いでしょう。
ちなみにOFEDドライバーには複数のリリースがあります。
- 23.
07系:2023年10月時点での最新版 - 5.
4/ 5. 8系:長期サポート版 - 4.
9系:ConnectX-3以前をサポートしている長期サポート版
長期サポート版
NVIDIAのOFEDドライバーのダウンロードから、次の手順で選択してアーカイブをダウンロードします。
- バージョンを指定
(今回は23. 07-0. 5.1. 2) - OSとして
「Ubuntu」 を選択 - OSバージョンとして
「Ubuntu 22. 04」 を選択 - CPUアーキテクチャーとして
「x86_ 64」 を選択
ダウンロードできるのは次の3種類のアーカイブです。
- ISO
- tgz
- SOURCE
ISOとtgzはアーカイブ方式の違いでしかなく、中身はまったく同じです。インストール用のスクリプトとドキュメント、Debianパッケージが同梱されています。SOURCEはISO/
今回はISOファイルをダウンロードして配置しましょう。ダウンロードする際は、EULAに同意する必要がある点に注意してください。ダウンロードしたISOファイルは適当なマウントポイントにマウントしておきます。
$ ls MLNX_OFED_LINUX-23.07-0.5.1.2-ubuntu22.04-x86_64.iso $ sudo mount -o loop,ro MLNX_OFED_LINUX-23.07-0.5.1.2-ubuntu22.04-x86_64.iso /mnt/
インストールスクリプトはmlnxofedinstall
」
$ /mnt/mlnxofedinstall -h Usage: /mnt/mlnxofedinstall [-c <packages config_file>|--all|--hpc|--vma|--xlio|--basic|--bluefield] [OPTIONS] Installation control: --force Force installation --tmpdir Change tmp directory. Default: /tmp -k|--kernel <version> Default on this system: 5.15.0-84-generic (relevant if --without-dkms is given) -s|--kernel-sources <path> Default on this system: /lib/modules/5.15.0-84-generic/build (relevant if --without-dkms is given) --distro Set Distro name for the running OS (e.g: ubuntu14.04). Default: Use auto-detection. --skip-distro-check Do not check MLNX_OFED_LINUX vs Distro matching --without-depcheck Run the installation without verifying that all required Distro's packages are installed --check-deps-only Check for missing required Distro's packages and exit --print-distro Print distribution name and exit (中略) Package selection: -c|--config <packages config_file> Example of the config file can be found under docs (ofed.conf-example) --all Install all available packages --bluefield Install BlueField packages --hpc Install minimum packages required for HPC --basic Install minimum packages for basic functionality --dpdk Install minimum packages required for DPDK --ovs-dpdk Install DPDK and OVS packages (後略)
mlnxofedinstall
では、オプションによってインストール時の挙動を変えられます。たとえばコンテナにユーザーランドのツールをインストールしたいだけなので、カーネルドライバーのインストールやファームウェアの更新は不要なんて設定も可能です。今回は特にカスタマイズせずそのまま実行することにしましょう。具体的には次のような処理をスクリプトが実行します。
- もし古いバージョンが存在したらアンインストール
- オプションに応じて各種パッケージのインストール
- カーネルドライバー用にDKMSの設定
- ファームウェアの更新
/etc/
のsecurity/ limits. conf memlock
をsoft/hardともにunlimitedとする - 実行ログを
/tmp/
以下に保存MLNX_ OFED_ LINUX.<PID>.logs/
RHEL・
とりあえずは実際にインストールしてみましょう。インストール時点でセキュアブートがオンだと、ファームウェアの更新が失敗しますがこれは後から対応可能です。よって特にオプションを指定せずに実行すると次のような結果になります。
$ sudo /mnt/mlnxofedinstall Logs dir: /tmp/MLNX_OFED_LINUX.9791.logs General log file: /tmp/MLNX_OFED_LINUX.9791.logs/general.log Below is the list of MLNX_OFED_LINUX packages that you have chosen (some may have been added by the installer due to package dependencies): (中略) This program will install the MLNX_OFED_LINUX package on your machine. Note that all other Mellanox, OEM, OFED, RDMA or Distribution IB packages will be removed. Those packages are removed due to conflicts with MLNX_OFED_LINUX, do not reinstall them. Do you want to continue?[y/N]:y
オプションなしの場合、パッケージリストのあとに最初に機能的にかぶるパッケージを削除してしまう旨の確認があります。これはUbuntuの公式リポジトリにあるMellanox用のツールが該当し、OFEDドライバーのそれと共存はできないので、削除することを示しています。また、削除したあとに再インストールしない旨も記載があるのでその点注意してください。ちなみにUbuntuをクリーンインストールした状態だと削除されるものはありませんでした。
あとはそのまま放置していればインストールは完了します。
Added 'RUN_FW_UPDATER_ONBOOT=no to /etc/infiniband/openib.conf Initializing... Attempting to perform Firmware update... Querying Mellanox devices firmware ... write counter to semaphore: Operation not permitted write counter to semaphore: Operation not permitted write counter to semaphore: Operation not permitted write counter to semaphore: Operation not permitted (中略) Installation passed successfully To load the new driver, run: /etc/init.d/openibd restart
いくつかのエラーログは表示されていますが、インストール自体は成功しています。エラーログについては、主にファームウェアの更新に関する部分です。Ubuntu 22.
インストールが完了したら、ISOイメージをアンマウントしておきましょう。
$ sudo umount /mnt
これでインストールそのものは完了しました。次からはインストールしたドライバーをセキュアブート環境でもロードできるようにし、失敗したファームウェアの更新を再実施します。
MOKManagerを使ってドライバーの鍵を登録する
OFEDドライバーで重要なのがカーネルドライバーです。これは次のようにupdates
ディレクトリにDKMSを使ってインストールされます。
$ find /lib/modules -name mlx5_core.ko /lib/modules/5.15.0-84-generic/kernel/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.ko /lib/modules/5.15.0-84-generic/updates/dkms/mlx5_core.ko
カーネルモジュールは、ログの最後にあるようにopenibdを再起動することでロードできるのですが、ただインストールしただけだとセキュアブートによって阻害されてしまいます。Ubuntuの場合、DKMSでカーネルモジュールを署名するものの、その署名を検証するための鍵がセキュアブートの鍵リストに登録されていないからです。その結果、モジュールをロードしようとすると次のようなログがdmesgに残ることになります。
[653270.997456] Lockdown: modprobe: unsigned module loading is restricted; see man kernel_lockdown.7
まずはこれに対応しましょう。まず、DKMSのカーネルモジュールは次のようなfingerprintを持った鍵で署名されています。
$ modinfo mlx5_core | grep sig_key sig_key: 60:1C:75:3B:15:67:5F:79:C3:41:7D:65:CA:B8:A2:D8:71:F8:D4:DB
この署名を検証するための鍵は/var/
」
$ openssl x509 -inform der -in /var/lib/shim-signed/mok/MOK.der -noout -serial serial=601C753B15675F79C3417D65CAB8A2D871F8D4DB
そこでこの鍵をセキュアブートの鍵データベースに登録します。
shibata@meet:~$ sudo mokutil --import /var/lib/shim-signed/mok/MOK.der [sudo] shibata のパスワード: input password: input password again:
最初のパスワードは
今回は署名検証用の鍵を登録するため、一旦再起動してコンソール画面からそれを許可する必要があるのです。サーバーマシンだとIPMIやシリアルコンソールのアクセスが必要ですし、通常のPCだとディスプレイとキーボードの接続が必要になる点に注意してください。
上記の設定後に再起動すると、Ubuntuが起動する前に青い画面で
- 「Enroll MOK」
を選択してエンターキーを押す - 「View key 0」
を選択してエンターキーを押す - 鍵の情報が表示されるので期待通りであることを確認してエンターキーを押す
- enrollするか問われるので
「Yes」 を選択してエンターキーを押す - 事前に設定したパスワードを入力してエンターキーを押す
- 「Reboot」
を選択してエンターキーを押す
おおよそ画面の指示通りに進めばOKです。これでそのまま起動すると、今度はmlx5_
などがロードされていることがわかるでしょう。
$ lsmod | grep mlx mlx5_ib 454656 0 ib_uverbs 135168 2 rdma_ucm,mlx5_ib ib_core 430080 8 rdma_cm,ib_ipoib,iw_cm,ib_umad,rdma_ucm,ib_uverbs,mlx5_ib,ib_cm mlx5_core 2097152 1 mlx5_ib mlxdevm 176128 1 mlx5_core mlxfw 32768 1 mlx5_core psample 20480 1 mlx5_core tls 114688 1 mlx5_core mlx_compat 69632 11 rdma_cm,ib_ipoib,mlxdevm,iw_cm,ib_umad,ib_core,rdma_ucm,ib_uverbs,mlx5_ib,ib_cm,mlx5_core pci_hyperv_intf 16384 1 mlx5_core
無事にロードされると、openibd.
$ systemctl status openibd.service ● openibd.service - openibd - configure Mellanox devices Loaded: loaded (/lib/systemd/system/openibd.service; enabled; vendor preset: enabled) Active: active (exited) since Sun 2023-10-01 16:36:46 JST; 38s ago Docs: file:/etc/infiniband/openib.conf Process: 960 ExecStart=/etc/init.d/openibd start bootid=a765c657d74a4fa681aff4b5d45ea2d8 (code=exited, status=0/SUCCESS) Main PID: 960 (code=exited, status=0/SUCCESS) Tasks: 0 (limit: 76740) Memory: 6.6M CPU: 326ms CGroup: /system.slice/openibd.service 10月 01 16:36:45 meet systemd[1]: Starting openibd - configure Mellanox devices... 10月 01 16:36:46 meet openibd[960]: [49B blob data] 10月 01 16:36:46 meet systemd[1]: Finished openibd - configure Mellanox devices.
うまく動くようになれば、次のようにセルフテストコマンドも
$ sudo hca_self_test.ofed ---- Performing Adapter Device Self Test ---- Number of CAs Detected ................. 2 PCI Device Check ....................... PASS Kernel Arch ............................ x86_64 Host Driver Version .................... MLNX_OFED_LINUX-23.07-0.5.1.2 (OFED-23.07-0.5.1): 5.15.0-84-generic Host Driver RPM Check .................. PASS Firmware on CA #0 NIC .................. v14.32.1010 Firmware on CA #1 NIC .................. v14.32.1010 Host Driver Initialization ............. PASS Number of CA Ports Active .............. 0 Port State of Port #1 on CA #0 (NIC)..... DOWN (Ethernet) Port State of Port #1 on CA #1 (NIC)..... DOWN (Ethernet) Error Counter Check on CA #0 (NIC)...... PASS Error Counter Check on CA #1 (NIC)...... PASS Kernel Syslog Check .................... PASS Node GUID on CA #0 (NIC) ............... e8:eb:d3:03:00:13:68:82 Node GUID on CA #1 (NIC) ............... e8:eb:d3:03:00:13:68:83 ------------------ DONE ---------------------
これでカーネルモジュールの準備も完了です。ちなみに鍵の登録も完了したため、今後カーネルのアップデートに伴いDKMSによってカーネルモジュールが再構築されたとしても自動的に再署名されます。よって、上記のようなMOKManager経由の起動は不要となります。
ファームウェアを更新する
インストール途中にファームウェアを更新しようとしたものの、次のようなエラーメッセージが表示されました。
Querying Mellanox devices firmware ... write counter to semaphore: Operation not permitted
これはカーネルの
[653269.659599] Lockdown: mlxfwmanager: direct PCI access is restricted; see man kernel_lockdown.7
lockdown機能については、次のコマンドで有効化されているか確認できます。
$ cat /sys/kernel/security/lockdown none [integrity] confidentiality
Ubuntuカーネルの場合は、セキュアブートが有効になっていると自動的にlockdownが有効化されます。これを無効化するには、セキュアブートをオフにする以外の方法はありません[6]。
そこで今度はファームウェア更新のために、一時的にセキュアブートを無効化して起動しましょう。UEFI/
先ほどと同じくmokutil
コマンドを使えば、再起動前に無効化の処理を登録しておき、再起動後にパスワード入力によってその設定を反映することが可能です。
$ sudo mokutil --disable-validation password length: 8~16 input password: input password again:
今度のパスワードは8文字以上16文字以内で入力してください。これも一時的なパスワードになります。ただし、先ほどと異なり
入力したら再起動します。次もシリアルコンソールやディスプレイとキーボードへのアクセスが必要です。Ubuntuが起動する前に青い画面で
- 「Change Secure Boot state」
を選択してエンターキーを押す - 「Enter password character N:」
と表示されるのでパスワードの 「N番目」 の文字を入力してエンターキーを押す - 上記を何回か繰り返す
- セキュアブートを無効化するか問われるので
「Yes」 を選択してエンターキーを押す - 「Reboot」
を選択してエンターキーを押す
これでセキュアブートが無効化された状態で起動します。
$ sudo dmesg | grep secureboot [ 0.000000] secureboot: Secure boot disabled [ 0.013636] secureboot: Secure boot disabled
さっそくファームウェアを更新してみましょう。あらかじめlspci
コマンドなどで、更新対象のデバイスのアドレスを確認しておきます。
$ lspci | grep Mellanox 01:00.0 Ethernet controller: Mellanox Technologies MT27710 Family [ConnectX-4 Lx] 01:00.1 Ethernet controller: Mellanox Technologies MT27710 Family [ConnectX-4 Lx]
上記の例だとmlxfwmanager
コマンドを使用します。--online
」-d デバイスアドレス
」
$ sudo mlxfwmanager --online -u -d 01:00.0 Querying Mellanox devices firmware ... Device #1: ---------- Device Type: ConnectX4LX Part Number: MCX4121A-ACA_Ax Description: ConnectX-4 Lx EN network interface card; 25GbE dual-port SFP28; PCIe3.0 x8; ROHS R6 PSID: MT_2420110034 PCI Device Name: 01:00.0 Base MAC: e8ebd3136882 Versions: Current Available FW 14.32.1010 14.32.1010 PXE 3.6.0502 3.6.0502 UEFI 14.25.0017 14.25.0017 Status: Up to date
今回はmokutil
を実行して再起動する必要があります。
$ sudo mokutil --enable-validation $ sudo reboot
有効化する場合も、無効化のときと同じようにMOKManagerの指示に従ってください。
このようにセキュアブート有効化環境だと、ファームウェアの更新はいろいろと面倒です。しかしながらそんなに頻繁にファームウェアを更新する期間があるわけではないですし、BIOSの更新と同じようなものだと割り切ってしまいましょう[7]。
MST(Mellanox Software Tools)の起動
OFEDには
$ sudo mst start Starting MST (Mellanox Software Tools) driver set Loading MST PCI module - Success Loading MST PCI configuration module - Success Create devices Unloading MST PCI module (unused) - Success
MSTサービスを起動するといくつかのカーネルドライバーがロードされ、/dev/
」
$ ls /dev/mst/ mt4117_pciconf0 mt4117_pciconf0.1
このデバイスファイルを使うと、現在のより詳細な情報を取得可能です。たとえばmlxlink
コマンドを使うと、デバイスのリンク状態や障害情報を取得できます。また-m
」
$ sudo mlxlink -d /dev/mst/mt4117_pciconf0 -m Operational Info ---------------- State : Active Physical state : LinkUp Speed : 25GbE Width : 1x FEC : Standard RS-FEC - RS(528,514) Loopback Mode : No Loopback Auto Negotiation : ON Supported Info -------------- Enabled Link Speed : 0x38007013 (25G,10G,1G) Supported Cable Speed : 0x20002001 (25G,10G,1G) Troubleshooting Info -------------------- Status Opcode : 0 Group Opcode : N/A Recommendation : No issue was observed Tool Information ---------------- Firmware Version : 14.32.1010 MFT Version : mft 4.25.0-62 Module Info ----------- Identifier : SFP28/SFP+ Compliance : 100GBASE-SR4 or 25GBASE-SR Cable Technology : N/A Cable Type : Optical Module (separated) OUI : Other Vendor Name : FS Vendor Part Number : SFP28-25GSR-85 Vendor Serial Number : F2034318317 Rev : B Wavelength [nm] : 850 Transfer Distance [m] : 10 Attenuation (5g,7g,12g) [dB] : N/A FW Version : N/A Digital Diagnostic Monitoring : Yes Power Class : 1.0 W max CDR RX : OFF CDR TX : OFF LOS Alarm : N/A Temperature [C] : 35 [-5..75] Voltage [mV] : 3282 [2970..3630] Bias Current [mA] : 6.240 [1..15] Rx Power Current [dBm] : 0 [-12..4] Tx Power Current [dBm] : 0 [-10..4]
今回はOFEDドライバーのインストールのみを紹介しました。これだけだとドライバーがInboxに比べて少し新しくなって、もしかすると性能が向上したかもしれないぐらいの話になってしまいます。それはそれでうれしいのですが、せっかくInbox以外のドライバーを入れたいので、いろいろな機能も試したいところです。けれどもそれは別のお話。また別の機会に解説することにしましょう。