StarTech ST10GSPEXNB(Tehuti TN4010)のベンダードライバがDebian 11、カーネル5.10でビルドできない
バックアップサーバーに10G SFP+ポートを持たせようとStarTech ST10GSPEXNBを買った、Linuxドライバ付きで売られているカードなら最近のディストリビューションでもビルドできるだろうという前提で。それは自分が楽観的すぎた。
- StarTech ST10GSPEXNB, Tehuti TN4010チップ
- Debian 11, カーネル5.10.0-13-amd64、対応するheadersはインストール済み
- カードに付属していたベンダードライバパッケージそのまま
- ケージには汎用の10G SFP+モジュール、もっともカードはそれを気にするところまでたどり着いていない
makeはかなり先まで進むが、transmitパスのところで転ぶ:
$ make
...
tn40.c:3644: error: assignment to 'struct skb_frag_struct *' from incompatible pointer type
tn40.c:3648: error: invalid use of undefined type 'struct skb_frag_struct'
tn40.c:3651: error: invalid use of undefined type 'struct skb_frag_struct'
最後の2つはDMAマッピングの呼び出しのところで出ている。
ここまで試したこと:
- chmod +x mvidtoh.sh。これをやる前はpermission deniedでビルドが止まり、PHYヘッダーが生成されなかった。ここは解決済み
- uname -rとインストール済みheadersを突き合わせたが一致している
- ベンダー配布のものより新しいパッケージがないか探したが、何も見つからなかった
この10年以内のカーネルでこれを動かしている人はいるか、いるならどうやって?
Comments 6
具体的にどのドライバパッケージなのか。tarballにバージョンの刻印はあるか、readmeはどのカーネル範囲を謳っているのか。自分が触ってきたTehuti系のカードはどれも、readmeにサポート対象カーネルを書いたソースツリーが付いてきたが、大抵は実際に使っているカーネルよりずいぶん古いところで止まっている。
どのツリーをビルドしているのかも書いておく価値がある。カードに付属するベンダー版と、コミュニティのtn40xx系ツリー(tn40xx-006やtn40xx-003、それにlinux-6.6やlinux-6.7ブランチ)があって、これらは歴史上のポジションがまるで違う。みんな気づかないまま別のコードについて意見交換していることがよくある。
最後に一点。ログの中で本当に3644が最初のエラーなのか、それとももっと上にノイズとして読み流したものがあるのか。この3行は1つのAPI変更に見えるが、もしもっと前でビルドが壊れているなら、残りはその余波にすぎない。
コミュニティツリーというのは初耳だ、自分が持っているのは箱に入っていたtarballだけで、ここでの作業は全部それを展開したそのままのものから行っている。そのブランチ群は次に読むものにする。参考までに、tarballにもmakefileにもバージョンはどこにも書かれていない。
readmeはまさに言う通りの内容だ。3.x系のカーネルについて書かれていて、4.14系で止まっている。これはハードリミットというより、テスト済みの範囲についてのメモだと読んでいたが、今思えば甘かった。
それと、たしかに3644が最初のエラーだ。それより上には警告しかない。未使用変数、暗黙の宣言といった、このツリーなら日常的に出しているらしいものばかりで、ビルドはそれらを何ごともなく通り過ぎてから、transmitパスでぴたりと止まる。3644、3648、3651という同じ3行が、毎回同じ順番で出る。
readmeの意図がどうであれ、それはハードリミットだ。貼ってくれたエラーがその理由をそのまま物語っている。
カーネルはskbフラグメントの表現方法を変えた。5.4以降、skb_frag_tはbio_vecになり、struct skb_frag_structはもう存在しない。struct skb_frag_struct *に代入しているソースは、まさに書いてある3644のエラーを出す。それを参照してページとオフセットをDMAマッピングの呼び出しに渡すコードは、3648と3651のinvalid use of an undefined typeを出す。もう存在しない型を、ヘッダーでもフラグでも古いコンパイラでも回避することはできない。
つまり5.10では、そのツリーは設定ではなく編集が必要になる。transmitパスのフラグメント処理を現行のアクセサに合わせて書き直す必要があり、これは1行修正ではなく本物のパッチだ、その周辺のDMAマッピングも同時に形が変わるので。
このカードは持っていないので、これは診断であって保証ではないと思ってほしい。なぜビルドが失敗するのか、それがソース側の問題であることは説明できるが、直したあとにドライバがリンクを上げてくれるかまでは分からない。
そのパッチに週末を丸ごと突っ込む前に、その先に何が待っているかを見ておくといい。
手元にStarTech PEX10000SFPがある、TN9510バリアントで、PCI 1fc9:4025、subsystem 1fc9:3015。out-of-treeのtn40xxドライバはこれに対してビルドもロードもでき、dmesgはかなり期待の持てる内容になっている:
それなのにインターフェースはNO-CARRIERのまま、モジュールの赤いランプが点いたまま、ずっとそこで止まっている。同じカード、同じケージ、同じ光モジュールをStarTechのWindowsドライバで使うと即座にリンクする。つまりハードウェアは健全でPHYファームウェアもロードされていて、そのドライバ移植のリンク段階だけが仕事を終えられていない。
Ubuntu 22.04とRocky Linux 8.10、カーネル4.18、5.15、6.5、6.9、それにtn40xx-006、tn40xx-003、linux-6.6、linux-6.7の各ブランチを一通り試した。どれ一つとしてキャリアは得られなかった。正直なところ、コンパイルできるようにするところまでは楽な半分でしかない。
それは週末を潰す代わりに金を使う理由になる、普段は週末で片付ける派の自分が言うのだから間違いない。中古のIntelやMellanoxの10Gカードなら半日分の自分の時間より安く済むし、ドライバはすでに起動しているカーネルに入っている。
Intelにしてサードパーティ製光モジュールを挿す場合に知っておくべきことが一つ。X520はモジュールを"unsupported SFP+ module type was detected"で完全に拒否し、インターフェース自体が現れなくなる。直し方はモジュールオプション:
デュアルポートカードならそこは1,1にする。そのあとはモジュールをunload/reloadするだけでなく、update-initramfs -uしてコールドブートすること。無効化された状態がファームウェアに焼き付いてしまい、ウォームリロードではそれがクリアされないことが多いので。これが効くのは82599とX520だけで、チェックがドライバ側にある場合に限る。X710ではチェックがファームウェア側にあるので、このオプションでは救われない。
アドバイスとしては正しいが、問題を取り違えている、しかも同じ流れの中で。allow_unsupported_sfpはドライバの光モジュールホワイトリストの話で、このスレッドのカードはそもそもコンパイルすらできていない。ここにいる誰も、光モジュールを拒否される段階にすら近づいていない。後で役立つ知識ではあるが、今の答えにはならない。
とはいえ中古が選択肢にあるなら、素直に動くもう一つの候補はHP NC523SFPで、中身はOEM版のQLogic QLE3242、HPのパート番号593715-001。カーネル内蔵のqlcnicドライバで動くので、ビルドするものが何もない。手元の機体はqlcnic 5.3.66、アダプタファームウェア4.8.20と表示されていて、導入以来手をかけていない。
注意点は2つ。発熱が大きく、アイドルでも16〜17W程度あるので、静かな部屋だと気になる。それとSR-IOVについては聞いた誰からもはっきりした答えが得られず、あやふやなままだ。SR-IOVが必要ならNC552SFPのほうが買いとしては良く、bnx2xを使っていてちゃんとサポートしている、ただし上流でARIフォワーディングを有効にしないと見えてこない。