このページの翻訳:
ソースの表示
管理最近の変更サイトマップ

PVEのWindows 10ゲストでSR-IOVのVFが動いた!

Proxmox VE 6.3とConnectX-3を使って、ゲストのWindows 10 ProfessionalでSR-IOVのVirtual Functionが動いたぞー!デバイスマネージャで認識させるところまでは楽勝だったが、何度ドライバ当て直してもエラーコード43で動かなくて随分苦労した。結局、PVEのビルトインドライバが古かったのが原因だったけど、それはまた後日。

見せてもらおうか、SR-IOVの性能とやらを!

物理マシンのWindows 10と、PVE上の仮想マシンのWindows 10をConnectX-3の40GBASE-SR接続した環境で、MS謹製ネットワーク性能測定ツールNTttcpを使い速度を測った。物理マシンが送信側、VMが受信側とした結果は下図のとおり。

右下のアクティブなタスクマネージャが物理側で、他のウィンドウはリモートデスクトップ経由のVM側だ。26Gbpsほど出ているのがわかる。同じ条件でVM側をvirtio-netとすると12Gbps程度だった。速度も然ることながらPVEのCPU負荷が段違いなので、さすがSR-IOV。

なお、最大瞬間風速で32Gbps程度出ることは確認した。

LinuxがGPTを1MB確保するのはWindowsとの互換性のため

LinuxでGPTを作ると、First usable LBAとして512バイトセクタドライブで2048、4kセクタドライブで256が設定されることに気づいた。これだと、パーティショニングツールからはGPTとして1MiBが確保されたかのように見える。

GPTの実際のサイズは16.5KiBであるから、本来は33セクタ@512Bまたは5セクタ@4KiBで事足りる。FreeBSDの39セクタ@512Bに慣れた身からすると、無駄とも思えるサイズだ。

理由を調べてみると、どうもWindowsとの互換性のためっぽい。

WindowsではVistaとWindows Server 2008から、パーティションの先頭を1MiBアライメントで揃えるようになったそうだ。Linuxはこれに追従したとのこと。1MiBアライメントなら、512バイトと4kBの両方の倍数なので所謂AFTアライメント問題が解消でき、将来、より大きなセクタサイズが登場した時に対応できる可能性も高まる。

言われてみれば納得の理由だ。逆にFreeBSDが20KiBしか確保しないことが不安になってくる…。パーティション追加時にgpart create -a 1Mで1MiB境界に揃えてやればいいんだけではあるが、これだとパーティション一覧に“未使用領域”として計上されてしまうのが、ちょっとカッコ悪い。

どうでもいいけど調査の過程で、今更ながらCHSやらセクター63やらシリンダ境界規定やらを調べてしまった。


(2021-01-16 追記)

Linuxのfdiskで切ったパーティションをFreeBSDで見てみた。

> gpart show
=>        6  234423115  nvd0  GPT  (894G)
          6     131072     1  efi  (512M)
     131078   26214400     2  freebsd-zfs  (100G)
   26345478  208077643        - free -  (794G)

=>      256  468843345  nvd1  GPT  (1.7T)
        256     131072     1  efi  (512M)
     131328   26214400     2  freebsd-zfs  (100G)
   26345728  375914496     3  !6a898cc3-1dd2-11b2-99a6-080020736631  (1.4T)
  402260224   13107200     4  !6a898cc3-1dd2-11b2-99a6-080020736631  (50G)
  415367424   53476177        - free -  (204G)

nvd0がFreeBSDのgpart、nvd1がLinuxのfdiskで作成したもので、どちらも4kセクタである。

FreeBSDのgpartもFirst usable LBAをちゃんと見ているようで、nvd1のESPの開始セクタ256セクタ=1MiB地点を正しく認識している。

将来のことを考えると、GPTを作るところまではLinuxまたはWindowsでやった方がいいかもしれないなぁ。

参考サイト

loader.efiで任意のパーティションのFreeBSDをブートする

FreeBSD 12.0-RELEASEあたりから、UEFIのブートローダとして従来のboot1.efiに代わりloader.efiが使われるようになった。

どちらもZFSまたはUFSからシステムを起動する役割を持つが、boot1.efiは複数のストレージからファイルシステムを探すのに対し、loader.efiは自身が読み込まれたストレージのみが対象となる。簡単に言えば、loader.efiだと別HDDのFreeBSDシステムを起動できないというわけ。まぁ、ブートローダのプロンプトで手動で起動デバイスを指定してやれば出来るんだけど、毎度行うのは現実的ではないよね。

どうにか自動化できないかと各種文献あさりとGooglingをしてみるも、それらしい情報はなく…。仕方なくソースコードを眺めてみると、loader.envでrootdev変数を指定してやれば行けそうと分かった。

loader.efiにせよboot1.efiにせよ、最終的に起動対象はcurrdev変数の値が使われるが、loader.efiの場合rootdev変数の値が問答無用でcurrdevとして採用される。

でもって、rootdevの設定はEFIシステムパーティションの/efi/freebsd/loader.envファイルで行う。これは比較的最近作られた機能で、12.2-RELEASEから使えるようだ。

同ファイルに以下の一行を追加。ルートディレクトリとなるファイルシステムを指定する。UFSならdisk0p1という具合。末尾のコロンは誤字じゃないのでござる。

rootdev=zfs:zroot/ROOT/default:

2021-01-09現在、これらはドキュメント化されてないので、将来変わるかもしれないし動作の保証も致しかねる。

ま、こんな面倒なことしなくても、従来どおりboot1.efi使えばいいんだけどね!

FreeBSDのboot1.efiがもう使われていなかった件

UEFI環境でのFreeBSD (x64)のブートは、下表の手順で行われるとされている。manにも書かれている由緒正しい手順だ。

  1. UEFI:/EFI/BOOT/BOOTX64.EFI
    • UEFIシステム起動時に実行されるブートローダ
  2. ファーストステージ: boot1.efi (man)
    • freebsd-zfs, freebsd-ufsパーティションを探し、次のステージを起動するブートローダ。パーティション探索は、自身が読み込まれたストレージ→UEFIのブートオーダーに沿ったストレージの順に行われる。
  3. ファイナルステージ: loader.efi (man)
    • 環境変数currdev, loaddevで指定されたストレージからカーネルを起動する。
  4. カーネル

ファームウェア(UEFI)がEFIシステムパーティションのBOOTX64.EFIを起動し、それがboot1.efiを起動し、さらにloader.efiに処理が移り、最終的にカーネルが立ち上がる流れとなっている。スタンドアローンなFreeBSD環境では、boot1.efiがBOOTX64.EFIとしてコピーされるので、実際はBOOTX64.EFI→loader.efi→カーネルの順で起動、、、ということになっている。

言葉を濁してるのは、まぁお察しのとおり、manの説明と現状の実装が異なってるから。どうやらFreeBSD 12.0-RELEASEあたりで、BOOTX64.EFIとしてloader.efiが使われるようになったらしい(当該コミット)。この辺は現在絶賛過渡期のようで、ESP生成まわりを大きく作り変えたパッチも存在している。

試しにFreeBSD 12.2-RELEASEのインストーラが作ったESPをマウントし、BOOTX64.EFIとloader.efiのハッシュを比較すると見事に同じということが分かる。

というわけで、現実はファーストステージをすっ飛ばし、ファイナルステージブートローダがいきなり動き出す。

これでも大抵の環境では問題ない一方、現状、loader.efiは別ディスクのFreeBSDパーティションの探索を行わないようなので、そのようなストレージ構成だとFreeBSDのブートができない。こいつぁ困ったぜ。

回避策としては、手動でBOOTX64.EFIをboot1.efiにするか、あるいはloader.efiのままプロンプトでcurrdevを手動で指定し、zfs.koをカーネルを手動で読み込んでやればいい。前者の方が明らかに簡単ですな。

loader.efiのソースを見てたら、まだmanに載ってない方法が使えそうな気がするので、後日試す予定。

参考サイト

Proxmox VEのKSMを止める

Proxmox VE 6.2で仮想マシンを起動した途端、CPUファンが唸りを上げ、消費電力が50Wも増える状況に遭遇した。ゲスト側は完全にアイドル状態にもかかわらずだ。

こりゃ何事とホストでtopしてみると、ksmdなるプロセスがCPUを70~80%喰っていた。

ksmdの正体はKernel Samepage Mergingデーモンで、複数VMの同一内容のメモリページを共有して実メモリの消費量を抑える役割を担っているようだ。確かにこれはCPUリソースを食いそうだ。

メモリは潤沢にありオーバーコミットの予定もないので、お役御免ってことで無効化してしまう。同一バージョンのゲストOSを大量に起動するような状況じゃないと、イマイチ効果が薄そうな気もするし。

# systemctl disable ksmtuned

公式の解説では、その後ホストを再起動の指示があるが、systemctl stop ksmtunedでも同じ効果あるんじゃないかしら。知らんけど。KSMが効きまくってる環境だとヤバそうな気もするので、素直に再起動しときましょうか。

KSM無効後はCPU負荷も消費電力も元に戻った。めでたしめでたし。

参考サイト

start.txt · 最終更新: 2019-08-19 02:45 by Decomo
CC Attribution-Noncommercial-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0